This time for everyone to bring PHP implementation of the app payment case analysis, PHP implementation of the app pay attention to what matters, the following is the actual case, take a look.
First, the PHP background to generate pre-paid transaction orders, return the correct pre-payment transaction back-up logo and then in the app to adjust the payment!
Official Document: Https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1
According to the document stitching required parameters, here need a few methods, directly on the code!
The parameters to be transmitted are assembled into an XML format and sent as a parameter array!
Public Function ToXml ($data =array ()) {if (!is_array ($data) | | count ($DATA) <= 0) { return ' array exception ';} $xml = "<xml > "; foreach ($data as $key = + $val) { if (is_numeric ($val)) { $xml. = "<". $key. " > ". $val." </". $key." > "; } else{ $xml. = "<". $key. " ><! [cdata[]. $val. "] ></". $key." > "; } } $xml. = "</xml>"; return $xml; }
2. Generate random strings, required parameters! Here are a lot of ways to see their hobbies are OK!
function Rand_code () {$str = ' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ';//62 Characters $STR = Str_ Shuffle ($STR); $str = substr ($str, 0,32); return $STR;}
3. Here is a more important step, this method will be used many times! To generate a signature
Private Function Getsign ($params) {ksort ($params);//The parameter array is sorted from small to large with the argument name ASCII ($params as $key = $item) { I F (!empty ($item)) { //reject argument with null parameter value $NEWARR [] = $key. ' = '. $item; Integrate a new parameter array }} $stringA = Implode ("&", $NEWARR); Use the & symbol connection parameter $stringSignTemp = $stringA. " &key= "." ************************"; Splicing key//key is set in the Merchant Platform API Security $stringSignTemp = MD5 ($stringSignTemp); The string is MD5 encrypted $sign = Strtoupper ($stringSignTemp); Converts all characters to uppercase return $sign; }
4. Pass parameters to, generate a pre-paid order! Receive the returned data, in the back to the app side, the app side call payment interface, complete payment! The required parameters of the app are shown in document: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2
Public Function Wx_pay () {$nonce _str = $this->rand_code ();//Call Random string generation method to get a random string $data [' appid '] = ' wxdbc5dc******* '; /appid $data [' mch_id '] = ' 1493***** '; Merchant number $data [' body '] = "app payment test"; $data [' spbill_create_ip '] = $_server[' http_host '); IP address $data [' total_fee '] = 1; Amount $data [' out_trade_no '] = time (). Mt_rand (10000,99999); Merchant Order number, cannot repeat $data [' nonce_str '] = $nonce _str; Random string $data [' notify_url '] = ' http://xxx.xxx.com/wx_notify '; Callback address, the user receives the notice after payment, must be the URL which can be visited directly, cannot follow the parameter $data [' trade_type '] = ' APP '; Payment method//The data that participates in the signature is saved to the array Note: The above parameters are appended to the $data, and the $data should contain all data except for the sign that is required in the development documentation $data [' sign '] = $this->getsign ($ data); Get signature $xml = $this->toxml ($data); The array-to-XML//curl is passed $url = "Https://api.mch.weixin.qq.com/pay/unifiedorder"; Header ("Content-type:text/xml"); $ch = Curl_init (); curl_setopt ($ch, Curlopt_url, $url); if (Stripos ($url, "https://")!==false) {curl_setopt ($ch, curlopt_sslversion, CURL_SSLVERSION_TLSV1); curl_setopt ($ch, Curlopt_ssl_verifypeer, FALSE); Curl_setopT ($ch, Curlopt_ssl_verifyhost, FALSE); } else {curl_setopt ($ch, curlopt_ssl_verifypeer,true); curl_setopt ($ch, curlopt_ssl_verifyhost,2);//Strict calibration}//Set header curl_setopt ($ch, Curlopt_sslversion, Curl_sslversion_ TLSV1); curl_setopt ($ch, Curlopt_header, FALSE); Requires the result to be a string and output to the screen curl_setopt ($ch, Curlopt_returntransfer, TRUE); Set timeout curl_setopt ($ch, Curlopt_timeout, 30); curl_setopt ($ch, Curlopt_post, TRUE); Transfer files curl_setopt ($ch, Curlopt_postfields, $xml); Run Curl $data = curl_exec ($ch); Returns the result if ($data) {curl_close ($ch); Returns success, converting XML data to an array. $re = $this->fromxml ($data); if ($re [' return_code ']! = ' SUCCESS ') {JSON ("201", ' signature failed '); } else{//Receive the returned data, passed to app! $arr =array (' prepayid ' = + $re [' prepay_id '], ' appid ' = ' wxdbc5dc***** ', ' partnerid ' = ' 14937**** ', ' pack Age ' = ' sign=wxpay ', ' noncestr ' and ' _str ', ' timestamp ' =>time (); The second time the signature is generated $sign = $this->getsign ($arr); $arr [' sign '] = $sign; JSON (' 200 ', ' signature successful ', $arr); }} else {$error = curL_errno ($ch); Curl_close ($ch); JSON (' 201 ', "Curl error, error code: $error"); } }
5. Convert the XML data to an array, which is used when the returned data is received.
Public Function FromXml ($xml) {if (! $xml) { echo "XML data Exception!) "; } Convert XML to array//disallow referencing external XML entity Libxml_disable_entity_loader (TRUE); $data = Json_decode (Json_encode (simplexml_load_string ($xml, ' simplexmlelement ', Libxml_nocdata)), true); return $data; }
Second, the app payment succeeds, will call you fill in the callback address.
return parameters See document: Https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3
The payment callback function wx_notify () {//receives the returned data data, the returned XML format $xmlData = file_get_contents (' php://input '); Converts an XML format to an array $data = $this->fromxml ($xmlData); Logs are used to check whether the data is accepted successfully, and after the validation is successful, it can be deleted. $file = fopen ('./log.txt ', ' A + '); Fwrite ($file, Var_export ($data, true)); To prevent false data, verify that the signature is the same as returned. Record, return the signature, when generating the signature, you must remove the Sign field. $sign = $data [' sign ']; unset ($data [' sign ']); if ($sign = = $this->getsign ($data)) {///signature verification succeeds, the judgment returns the returned if ($data [' result_code '] = = ' SUCCESS ') {//The business logic is made according to the order number returned $arr = Array (' pay_status ' = 1,); $re = M (' order ')->where ([' order_sn ' = ' = $data [' Out_trade_no ']])->save ($arr); After processing is complete, tell the successful result! if ($re) {echo ' <xml> <return_code><![ Cdata[success]]></return_code> <return_msg><! [cdata[ok]]></return_msg> </xml> '; exit (); }}//payment failed, output error message else{$file = fopen ('./log.txt ', ' A + '); Fwrite ($file, "error message:" $data [' Return_msg '].date ("y-m-d h:i:s"), Time (). " \ r \ n "); }} else{$file = fopen ('./log.txt ', ' A + '); FwrITE ($file, "error message: Signature verification failed". Date ("y-m-d h:i:s"), Time (). " \ r \ n "); }}
Here, the app payment process has been successfully completed! Thank you for your support!
Believe that you have read the case of this article you have mastered the method, more exciting please pay attention to the PHP Chinese network other related articles!
Recommended reading:
PHP RSA encryption and decryption and development interface Case usage analysis
PHP Long Connection use case study