PHP實現APP微信支付案例解析

來源:互聯網
上載者:User
這次給大家帶來PHP實現APP支付案例解析,PHP實現APP支付的注意事項有哪些,下面就是實戰案例,一起來看一下。

一、PHP後台後台產生預支付交易單,返回正確的預支付交易回話標識後再在APP裡面調起支付!

官方文檔:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1

根據文檔拼接需要的參數,這裡需要幾個方法,直接上代碼!

傳輸給的參數要組裝成xml格式發送,傳如參數數組!

public function ToXml($data=array()) { if(!is_array($data) || count($data) <= 0) {  return '數組異常'; } $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.產生隨機字串,所需參數! 這裡方法很多,看自己愛好都行!

function rand_code(){ $str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';//62個字元 $str = str_shuffle($str); $str = substr($str,0,32); return $str;}

3.這裡是比較重要的一步了,這個方法會多次用到!產生簽名

private function getSign($params) { ksort($params); //將參數數組按照參數名ASCII碼從小到大排序 foreach ($params as $key => $item) {  if (!empty($item)) {  //剔除參數值為空白的參數  $newArr[] = $key.'='.$item; // 整合新的參數數組  } } $stringA = implode("&", $newArr);  //使用 & 符號串連參數 $stringSignTemp = $stringA."&key="."************************"; //拼接key // key是在商戶平台API安全裡自己設定的 $stringSignTemp = MD5($stringSignTemp); //將字串進行MD5加密 $sign = strtoupper($stringSignTemp); //將所有字元轉換為大寫 return $sign; }

4.傳遞參數給,產生預支付訂單! 接收返回的資料,在反給APP端,APP端調用支付介面,完成支付 ! APP端所需參數見文檔: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(); //調用隨機字串產生方法擷取隨機字串 $data['appid'] ='wxdbc5dc*******'; //appid $data['mch_id'] = '1493*****' ; //商戶號 $data['body'] = "APP支付測試"; $data['spbill_create_ip'] = $_SERVER['HTTP_HOST']; //ip地址 $data['total_fee'] = 1;    //金額 $data['out_trade_no'] = time().mt_rand(10000,99999); //商戶訂單號,不能重複 $data['nonce_str'] = $nonce_str;   //隨機字串 $data['notify_url'] = 'http://xxx.xxx.com/wx_notify'; //回調地址,使用者接收支付後的通知,必須為能直接存取的網址,不能跟參數 $data['trade_type'] = 'APP'; //支付方式 //將參與簽名的資料儲存到數組 注意:以上幾個參數是追加到$data中的,$data中應該同時包含開發文檔中要求必填的剔除sign以外的所有資料 $data['sign'] = $this->getSign($data); //擷取簽名 $xml = $this->ToXml($data);  //數組轉xml //curl 傳遞給方 $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);//嚴格校正 } //設定header curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); curl_setopt($ch, CURLOPT_HEADER, FALSE); //要求結果為字串且輸出到螢幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); //設定逾時 curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_POST, TRUE); //傳輸檔案 curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); //運行curl $data = curl_exec($ch); //返回結果 if($data){  curl_close($ch);  //返回成功,將xml資料轉換為數組.  $re = $this->FromXml($data);  if($re['return_code'] != 'SUCCESS'){  json("201",'簽名失敗');  }  else{  //接收返回的資料,傳給APP!  $arr =array(   'prepayid' =>$re['prepay_id'],   'appid' => 'wxdbc5dc*****',   'partnerid' => '14937****',   'package' => 'Sign=WXPay',   'noncestr' => $nonce_str,   'timestamp' =>time(),  );  //第二次產生簽名  $sign = $this->getSign($arr);  $arr['sign'] = $sign;  json('200','簽名成功',$arr);  } } else {  $error = curl_errno($ch);  curl_close($ch);  json('201',"curl出錯,錯誤碼:$error"); } }

5.將xml資料轉換為數組,接收返回資料時用到.

public function FromXml($xml) { if(!$xml){  echo "xml資料異常!"; } //將XML轉為array //禁止引用外部xml實體 libxml_disable_entity_loader(true); $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $data; }

二、APP支付成功後,會調用你填寫的回調地址.

返回參數詳見文檔:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3

// 支付回調 function wx_notify(){  //接收返回的資料資料,返回的xml格式  $xmlData = file_get_contents('php://input');  //將xml格式轉換為數組  $data = $this->FromXml($xmlData);  //用日誌記錄檢查資料是否接受成功,驗證成功一次之後,可刪除。  $file = fopen('./log.txt', 'a+');  fwrite($file,var_export($data,true));  //為了防止假資料,驗證簽名是否和返回的一樣。  //記錄一下,返回回來的簽名,產生簽名的時候,必須剔除sign欄位。  $sign = $data['sign'];  unset($data['sign']);  if($sign == $this->getSign($data)){  //簽名驗證成功後,判斷返回返回的  if ($data['result_code'] == 'SUCCESS') {  //根據返回的訂單號做商務邏輯  $arr = array(   'pay_status' => 1,   );  $re = M('order')->where(['order_sn'=>$data['out_trade_no']])->save($arr);  //處理完成之後,告訴成功結果!  if($re){   echo '<xml>  <return_code><![CDATA[SUCCESS]]></return_code>  <return_msg><![CDATA[OK]]></return_msg>  </xml>';exit();  }  }  //支付失敗,輸出錯誤資訊  else{  $file = fopen('./log.txt', 'a+');  fwrite($file,"錯誤資訊:".$data['return_msg'].date("Y-m-d H:i:s"),time()."\r\n");   } } else{  $file = fopen('./log.txt', 'a+');  fwrite($file,"錯誤資訊:簽名驗證失敗".date("Y-m-d H:i:s"),time()."\r\n");   }}

在這裡,APP支付流程就成功走完了!謝謝支援!

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

PHP的RSA加密解密與開發介面案例流量分析

PHP長串連使用案例分析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.