1. Payment
Payment is mainly divided into several steps:
1. The front-end carries the data required for payment (commodity ID, purchase quantity, etc.) to initiate a payment request.
2 After receiving the payment request, the backend processes the payment data, and then carries the processed data to request the unified payment order interface of the WeChat server
3. The backend receives the previous step Request the return data from the WeChat server, process it again, and then return to the front end so that the front end can start payment.
4 The front-end performs the payment action
5 After the front-end payment is completed, the WeChat server will send a payment notification to the back-end (that is, WeChat wants to tell you that the customer has paid). The client determines that the payment is completed based on this notification, and then takes the corresponding actions after the payment is completed, such as modifying the order status, adding transaction logs, etc.
It can be seen from these steps that the main function of the backend is to transmit the data required for payment to the WeChat server, and then determine whether the payment is completed based on the response of the WeChat server.
This process is quite easy to understand. Figuratively speaking, the front-end is a customer, the back-end is the store, and the unified ordering interface of the WeChat server is like a cashier. The customer tells the store, who am I, and now I have to pay how much to buy you such and such. The store owner told the cashier, "How much does so-and-so have to pay? You should be prepared to collect the money." After the cashier received the money, he went to tell the store, "I have received the money, please give him something."
The specific implementation of each step will be explained in detail below.
1. Front-end request for payment
Front-end request for payment is to simply carry the data required for payment, such as user ID, payment amount, payment order ID, etc. to your business Logically related data** or related to the data required to request the WeChat server payment unified order interface in the next step**, use wx.request() of the WeChat applet to request the back-end payment interface.
2. The backend requests the WeChat server
After the backend receives the payment request sent by the frontend, it can perform relevant verifications, such as determining whether the user has any problems and whether the payment amount is correct. etc.
After verifying that there is no problem and you can apply for payment to the WeChat server, the backend needs to use the data format specified by WeChat to request WeChat's unified payment order interface.
Request data specified by WeChat:
This requires more code to implement. Because the amount of data required is large, it also needs to be encrypted and sent in XML format.
First of all, the following data are parameters that must be provided to the WeChat server when using the mini program to pay.
Mini program appid. There is probably no one who writes small programs who doesn’t know this. . .
User ID openid. That is the user's mini program ID. I explained how to obtain it in my last blog.
Merchant number mch_id. After successfully applying for WeChat payment merchant certification, the email sent to you by WeChat will contain
the merchant order number out_trade_no. The order number generated by the merchant for this payment
Total amount total_fee. The total amount of the order, a very important point is that the unit is cents, so pay special attention to it.
WeChat server callback notification interface address notify_url. After WeChat confirms that the money has arrived, it will send multiple messages to this address to tell you that the customer has paid. You need to return a message to WeChat to indicate that you have received the notification. . This address cannot have a port number, and must be able to directly accept POST method requests.
Transaction type trade_type. The WeChat applet payment value is unified as JSAPI
Product information Body. Similar to the format of "Tencent-Game"
Terminal IP address spbill_create_ip.
Terminal address IP, which is the IP address requesting payment.
Random string nonce_str. A string randomly generated by the backend is required to ensure data security. WeChat requires no longer than 32 bits.
Signature sign. Use all the above parameters to process the encryption and generate the signature accordingly. (The specific processing method can be seen in the code below, which can be reused directly.)
After processing all the above data, organize the data in XML format and send it to the WeChat payment unified order interface/pay using the POST method /unifiedorder.
3. The backend accepts the data returned by the WeChat server
After the WeChat server receives the payment data, if there is no problem with the data, it will return the corresponding data for payment, which is very important. is a data field named prepay_id. This data needs to be returned to the front end before the front end can continue to pay.
Therefore, after the back-end receives the return data from the WeChat server, it needs to perform corresponding processing, and finally return the following data to the front-end:
appid Needless to say
timeStamp current timestamp
nonceStr random string
package is the prepay_id mentioned above, but remember that the format is such as "prepay_id= prepay_id_item". Otherwise an error will result.
signType encryption method, generally should be MD5
paySign processes and encrypts the above data accordingly.
At this point, the back-end payment interface has completed the function of receiving the front-end payment request and returning the data required for front-end payment.
4. The front-end initiates payment
After receiving the return data, the front-end uses wx.requestPayment() to request payment. The values ??of the object parameters required by this API are the data returned in the previous step.
5. The backend accepts WeChat server callbacks
After the frontend completes the payment, the WeChat server confirms that the payment has been completed. A notification will be sent to the callback address set in the first step. After receiving the notification, the back-end receiving callback interface can determine whether the payment is completed and determine subsequent actions.
It should be noted that after receiving the callback notification from the WeChat server, it is judged whether the payment is successful based on the result_code field of the notification. After receiving the successful notification, the backend needs to return success data to the WeChat server to inform the WeChat server that the callback notification has been received. Otherwise, the WeChat server will keep sending messages to the backend. In addition, WeChat notifications are sent in XML format, so you need to pay attention when accepting and processing them.
This is the rough payment process on WeChat. The following is the WeChat payment class of PHP syntax. You can refer to the above steps to deepen your understanding. When you need to pay, you can directly pass in the parameters to instantiate this class and then call the pay method of the class.
//WeChat payment class
class WeiXinPay{
//========Basic information settings========= ============================
//The unique identifier of the WeChat official account
protected $APPID = appid; //Fill in your appid.
In WeChat public platform
protected $APPSECRET = secret;
//Acceptor ID, identity identifier
protected $MCHID = '11111111'; // Merchant id
//Merchant payment key Key
protected $KEY = '192006250b4c09247ec02edce69f6a2d';
//Callback notification interface
protected $APPURL = '/receivesuc';
//Transaction type
protected $TRADETYPE = 'JSAPI';
//Product type information
protected $BODY = 'wx/book';
//Constructor of WeChat payment class
function __construct($openid, $outTradeNo, $totalFee){
$this-gt; openid = $openid; //User unique identifier
$this-gt; outTradeNo = $outTradeNo; //Item number
$ this-gt; totalFee = $totalFee; //Total price
}
//The payment interface exposed by WeChat payment class
public function pay(){
$result = $this-gt;weixinapp();
return $result;
}
//Process payment-related data returned by WeChat unified ordering interface
private function weixinapp(){
$unifiedorder=$ this-gt; unifiedorder();
$parameters=array(
'appId'=gt; $this-gt;APPID, //Mini program ID
'timeStamp'=gt; ''.time().'', // timestamp
'nonceStr' = gt; $this-gt; createNoncestr(), // random string p>
'package'=gt;'prepay_id='.$unifiedorder['prepay_id'],//data package
'signType'=gt;'MD5'//signature method p>
);
$parameters['paySign']=$this-gt; getSign($parameters);
return $parameters;
}
p>
/*
*Request WeChat unified order interface
*/
private function unifiedorder(){
$parameters = array(
'appid' =gt; $this-gt; APPID, // applet id
'mch_id'=gt; $this-gt; MCHID, //Merchant id
'spbill_create_ip'=gt; $_SERVER['REMOTE_ADDR'], //Terminal ip
'notify_url'=gt; $this-gt; APPURL, / /Notification address
'nonce_str'=gt; $this-gt; createNoncestr(), // Random string
'out_trade_no'=gt; $this-gt; outTradeNo, //Merchant order number
'total_fee'=gt; floatval($this-gt; totalFee), //Total amount
'open_id'=gt;$this-gt; openid, //User openid
'trade_type'=gt;$this-gt;TRADETYPE, //Transaction type
'body' =gt;$this-gt;BODY, //Product information
);
$parameters['sign'] = $this-gt; getSign($parameters);
$xmlData = $ this-gt;arrayToXml($parameters);
$xml_result = $this-gt;postXmlCurl($xmlData,'/pay/unifiedorder',60);
$result = $this-gt;xmlToArray($xml_result);
return $result;
}
//Array to string method
protected function arrayToXml($arr){
$xml = "lt;xmlgt;";
foreach ($arr as $key=gt;$val)
{
if (is_numeric($val)){
$xml.="lt;".$key."gt;".$val."lt; /".$key."gt;";
}else{
$xml.="lt;".$key."gt;l
t;![CDATA[".$val."]]gt;lt;/".$key."gt;";
}
}
$xml.="lt;/xmlgt;";
return $xml;
}
protected function xmlToArray($xml){ p>
$array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $array_data;
}
//Send xml request method
private static function postXmlCurl($xml, $url, $second = 30)
{ p>
$ch = curl_init();
//Set timeout
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt( $ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //Strict verification p>
//Set header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//Require the result to be a string and output it to the screen
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//post submission method
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt( $ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_TIMEOUT, 40);
set_time_limit(0);
//Run curl
$data = curl_exec($ch);
//Return results
if ($data) {
curl_close($ch);
re
turn $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
throw new WxPayException("curl error, error code: $error");
}
}
/*
* Yes Sign the data to be sent to the WeChat unified order interface
*/
protected function getSign($Obj){
foreach ($Obj as $k =gt; $v){
$Parameters[$k] = $v;
}
//Signature step 1: Sort parameters in dictionary order
ksort($Parameters);
$String = $this-gt; formatBizQueryParaMap($Parameters, false);
//Signature step 2: in Add KEY after string
$String = $String."amp; key=".$this-gt;KEY;
//Signature step three: MD5 encryption
$String = md5($String);
//Signature step 4: Convert all characters to uppercase
$result_ = strtoupper($String);
return $result_;
}
/*
*Sort and format parameter methods, required for signature
*/
protected function formatBizQueryParaMap($paraMap, $urlencode)
{
$buff = "";
ksort($ paraMap);
foreach ($paraMap as $k =gt; $v)
{
if($urlencode)
{
$v = urlencode($v);
}
//$buff .= strtolower($k) . "=" . $v . "amp;";
$buff .= $k . "=" . $v . "amp;";
}
$reqPar;
if (strlen(
$buff) gt; 0)
{
$reqPar = substr($buff, 0, strlen($buff)-1);
}
return $reqPar;
}
/*
* Generate random string method
*/
protected function createNoncestr($length = 32 ){
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str ="";
for ( $i = 0; $i lt; $length; $i ) {
$str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
}
The above is the relevant process of WeChat payment. After clarifying the ideas, the process is relatively clear and simple. The point is that you need to pay attention to some details, such as data format, encryption method, etc.
Let’s talk about the specific implementation of WeChat mini program refund
2. Refund
The mini program refund process is similar to payment, but there are some details on the difference.
The first step of refunding is usually as follows:
1. After the user clicks the refund button on the front end, the back end receives the user's refund request and presents it to the merchant through the mall backend, and the merchant confirms After allowing the refund, the backend initiates a request to the WeChat refund interface to request a refund.
2. After the backend sends a request to the WeChat refund interface, it gets the response information, determines whether the refund is completed, and then changes the order status and other business logic based on whether the refund is completed.
The steps for refund are relatively simple compared to WeChat payment.
It is worth noting the following two points:
1. After requesting a refund from the WeChat refund interface, you can directly determine whether the refund has been completed based on the response received. There is no need to set up a special callback interface to wait for WeChat notifications. Of course, if necessary, you can also set up a callback interface on the WeChat merchant platform to accept WeChat callbacks, but it is not necessary.
2. The refund request requires the security certificate provided by WeChat to be installed on the requesting server. In other words, when initiating a refund request compared to a payment request, the request method cannot be reused at the time of request, because WeChat refund needs to carry Certificate request, this certificate can be downloaded from the WeChat merchant platform after successfully applying for a WeChat merchant account. The certificate for the PHP development environment under Linux only needs to be placed in the cert folder in the root directory of the website. Other development environments may require import operations.
The specific steps for refund are explained below
1. The user initiates a refund request
The user initiates a refund request on the front end, and the back end receives the refund Request, mark the corresponding order as applying for refund, and display it in the background. After the merchant checks it, if it agrees to the refund, it will proceed with the corresponding operation. Only then will the real refund process be entered.
2. The merchant initiates a refund Request
After the merchant agrees to the refund, the backend will initiate a request to the refund API provided by WeChat.
It is the same as requesting the WeChat payment API. The refund request also needs the required parameters. After signing, send XML to WeChat's refund API [/pay/refund](/pay/refund)
The parameters required for the refund request are as follows (multiple parameters are also used in payment API requests) :
1. Mini program appid.
2. Merchant number mch_id. After successfully applying for WeChat payment merchant certification, the email sent to you by WeChat will contain
3. Merchant order number out_trade_no. The order number generated when the refund order is paid
4. The refund order number out_refund_no. The refund order number generated by the backend needs to be unique, because multiple identical refund order numbers will only refund once.
5. Total amount total_fee. The total amount of the order, in cents.
6. Refund amount refund_fee is the amount to be refunded, the unit is also in cents
7. Operator op_user_id. It can be the same as the merchant number
8 .random string nonce_str. Same as payment request
9. Signature sign. Use all the above parameters to process the encryption and generate the signature accordingly. (The specific processing method is the same as payment and can be reused directly.)
3. Refund completed
After initiating a refund request, you can directly follow the request in the response XML The result_code field is used to determine whether the refund is successful, so as to process the order status and perform subsequent operations. There is no need to wait for notification from another interface to determine the status of the request, as is the case with payments. Of course, as mentioned above, if you need the WeChat server to send notifications to the backend, you can go to the WeChat merchant platform to set it up.
Because the process of refund is similar to that of payment, I chose to directly inherit the payment class for the PHP class of refund.
The code is as follows. Pay attention to distinguishing between refunds. The difference between the request method postXmlSSLCurl and the payment request method postXmlCurl is the use of the two-way certificate required for refund mentioned above.
````
class WinXinRefund extends WeiXinPay{
protected \$SSLCERT_PATH = 'cert/apiclient_cert.pem'; //Certificate path
protected \$SSLKEY_PATH = 'cert/apiclient_key.pem'; //Certificate path
protected \$opUserId = '1234567899'; //Merchant number
p>
function __construct($openid, $outTradeNo, $totalFee, $outRefundNo, $refundFee){
//Variables required to initialize the refund class
$this- gt; openid = $openid;
$this-gt; outTradeNo = $outTradeNo;
$this-gt; totalFee = $totalFee;
$this -gt;outRefundNo = $outRefundNo;
$this-gt;refundFee = $refundFee;
}
public function refund(){
//Exposed refund interface
$result = $this-gt; wxrefundapi();
return $result;
}
private function wxrefundapi(){
//Refund process through WeChat api
$parma = array(
'appid' =gt; $this-gt;APPID,
'mch_id'=gt; $this-gt;MCHID,
'nonce_str'=gt; $this-gt; createNoncestr( ),
'out_refund_no'=gt; $this-gt; outRefundNo,
'out_trade_no'=gt; $this-gt; outTradeNo,
' total_fee'=gt; $this-gt;totalFee,
'refund_fee'=gt; $this-gt;refundFee,
'op_user_id' =gt; $this-gt; opUserId,
);
$parma['sign'] = $this-gt; getSign($parma);
$xmldata = $this- gt;arrayToXml($parma);
$xmlresult = $this-gt;postXmlSSLCurl($xmldata,'/secapi/pay/re
fund');
$result = $this-gt; xmlToArray($xmlresult);
return $result;
}
//Requests that require the use of certificates
function postXmlSSLCurl($xml, $url, $second=30)
{
$ch = curl_init() ;
//Timeout time
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
//Set the proxy here, if any
//curl_setopt($ch, CURLOPT_PROXY, '8.8.8.8');
//curl_setopt($ch, CURLOPT_PROXYPORT, 8080);
curl_setopt($ch , CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
// Set header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//Require the result to be a string and output it to the screen
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//Set the certificate
//Use the certificate: cert and key belong to two .pem files respectively
//The default format is PEM, can be commented
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLCERT, $this-gt; SSLCERT_PATH);
//The default format is PEM, you can comment
curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLKEY, $this-gt; SSLKEY_PATH );
//Post submission method
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
$data = curl_exec($ch);
//Return results
if($data){
curl_close($ch );
return $data;
}
else {
$error = curl_errno($ch);
echo "curl error, error code: $error"."lt; brgt;";
curl_close($ch);
return false;
}
}}
3. Summary
The above is an introduction to the process and related knowledge of WeChat payment and refund. The PHP classes in this article are all encapsulated and available directly.
Because the things involved in WeChat payment and refund are relatively complicated, many people may be confused if they read the official documents directly. Therefore, after reading this article to understand the process and key points, then read the WeChat official documents. On the one hand, you can have a clearer understanding of the payment and refund process of the mini program. On the other hand, due to the limited length of this article and the limited ability of the author, there must be some flaws or omissions that I have no time to take into account. To be sure, you still need to read more official development documents. After all, it involves payment, and a BUG is no small matter. The WeChat Shop Mini Program is a free shopping mall applet officially launched by WeChat. However, the WeChat Shop Mini Program does not support real-time order notifications. Merchants can only know new orders by manually refreshing the web page. How can I receive order reminders in real time and have them shipped on my mobile phone? Either go through a third-party service (larger cost) or do it yourself (zero cost).
WeChat launched a small program cloud development platform in September this year. To put it simply: Tencent provides free servers for small programs. We use Tencent's free server to realize all functions such as order notification, mobile phone delivery, and automatic order printing.
Watch the video first! This is what it looks like after it's done. You can receive order notifications in real time, automatically print orders, and ship orders on your mobile phone. Look carefully, there are more functions and more highlights. If you think it's okay, you can continue to look at the construction steps.
The construction steps are as follows:
Reuse the official account qualification to quickly create a mini program
The purpose of applying for this mini program is to obtain Tencent’s free server. With the server, Anything can be done. The specific application steps will not be explained in detail here. You can search on Baidu yourself.
Get the AppId and developer password
To obtain the AppId and password of the official account, the AppID of the WeChat store, and the AppId and password of the created mini program. This information will be imported into the created applet. With this information, the mini program can provide services for WeChat stores.
Download the WeChat developer tools and create a new mini program project
In the WeChat developer tools, create a new project. To associate the WeChat store applet with this applet, you can search on Weixin: Caiyun. You will see that the mini program runs very fast, crushing 80% of the mall mini programs on the market.
Create a new mini program project
Associate the WeChat store mini program
Order reminder
After development and construction, merchants can receive real-time Got a reminder on WeChat. There are 2 reminder methods: service notification and automatic order printing. Service notifications are free. If orders are automatically printed, merchants need to purchase a cloud printer. (It’s the kind of takeout printer)
Service notification reminder
Automatic order printing reminder
Shipment on mobile phone
After receiving the order After being reminded, merchants can click directly to enter the mini program delivery interface. And buyers can also receive shipping reminders.
More functions (sharing circle of friends, member management, employee management, etc.) have not been written yet and will be updated later. Through the video, you can see more information. A must-see.