微信支付之h5方式(非微信內置瀏覽器中支付)

這兩天完成了公司網站手機和PC端的支付對接,就是支付寶和微信.php

對接完後有所感觸,咱們來聊一聊,微信支付的坑,爲何這麼說呢,由於我在對接完支付寶後是很愉快的,基本上在demo上稍加修改就ok了,web

對於支付寶我以爲基本上都沒什麼能夠說的,而微信支付...ajax

網上搜了一下,基本上沒有看到有針對h5支付的成功教程,全都是複製粘貼官方文檔,有意思嗎.數據庫

剛好今天空了,來聊一聊微信支付的坑,固然本文也不是光吐槽了事,我會把完整的代碼放到文末尾處,並加以適當的註釋.json

------------------------------api

首先第一步去微信商戶平臺開通h5支付的.服務器

由於公司的app中的微信支付是我對接的,因此在開始作手機網站的微信支付前,我首先想到去微信開放平臺,新建了一個網站應用,微信

最後審覈下來竟然沒有支付接口,只有獲取用戶信息的接口,我有點蒙筆,而後我打了一下客服電話,那邊客服說h5支付在公衆號平臺中完成(注意:這裏客服mm向我扔了一個巨坑,接着往下看app

既然這樣,我就去了微信公衆號平臺,咱們有服務號,拿着appid和mch_id就開始搞,一切都很好,可是提示[商戶號該產品權限預開通中,請等待產品開通後重試],curl

我趕忙登陸商戶平臺看一下,肯定h5是開通的沒問題,這個時候我注意到一個問題,就是個人公衆號平臺中的商戶號和商戶平臺中的商戶號不一致,我檢查了公司信息,郵箱,手機號,二者都是徹底同樣的.

這個時候我把代碼中的商戶號(微信公衆號平臺的)改爲了商戶平臺的商戶號,請求接口返回[商戶號和appid不匹配],我再次堅決,應該用微信公衆號平臺的商戶號,由於appid是用的微信公衆號平臺的.

這個時候我陷入了焦灼,網上找了好久,沒有搜到任何跟[商戶號該產品權限預開通中,請等待產品開通後重試] 有關的結果,我給微信支付技術發了一封郵件,闡述了我遇到的問題,

次日技術回覆了我,說 "你開通h5支付的商戶號是這個(商戶平臺的),而不是你如今用這個(微信公衆號平臺的)",這就是前面那個客服mm給我扔的大坑!!

郵件中還告訴我,我開通h5支付的商戶號對應的appid是這個[appid**],而這個appid是我在開放平臺中之前建的移動應用,也就是咱們以前的app中用的...此時一萬隻草泥馬在開始奔騰.

先後跨度太大,讓我一時沒法接受這個事實,

你先告訴我,h5支付爲何跟移動應用扯上關係了,其次你文檔中提到了一星半點嗎,沒有!,客服mm也是調皮,動不動就h5支付跟開放平臺不要緊,只須要公衆號平臺.

還有 你微信產品真多 微信公衆號平臺(配置),微信開放平臺(文檔),微信商戶平臺(配置),我對接個微信支付要在三大平臺之間來回切換,你真的666!!!

---------------------------------

平復一下心情,來看一下h5支付的流程,整個邏輯是這樣的,首先用戶打開手機網站某個服務頁面

點擊開通某個產品時,此時經過ajax請求帶上產品價格,名稱等參數來請求一個php腳本(wxpay_wap.php),

這個腳本根據官方文檔要求的參數,組合,生成簽名,請求統一下單接口,

返回一個支付url,而後用js生成一個a標籤並模擬點擊或者直接location.href應該都是能夠的,

就會調起微信支付,支付完成後微信會發送一個請求到你設定的回調腳本(wxpay_wap_notify.php),在回調腳本里寫業務邏輯

大致就是這樣的,如下代碼稍加修改就能夠直接用了

---------------------------------

wxpay_wap.php

 1 // 文檔中說的,價格 單位是分
 2 $money = $_POST['money']*100; //商品價格
 3 // 前臺請求的參數
 4 $title = $_POST['title']; //商品名稱
 5 $userid = $_POST['userid']; //用戶id
 6 
 7 $time = time();
 8 
 9 $nonce_str = "hcuasduvihasdiovjerjgvujsaru"; //隨機字符串
10 $appid = "wx**************33"; //在微信開放平臺中的 appid(先要建立一個移動應用)
11 $mch_id = "147****642";  //商戶號,在商戶平臺中查看
12 $key = "51b*************************f15e"; //在微信開放平臺中的 
13 $notify_url = "http://www.xxx.com/xxx/wxnotify.php"; //用戶支付完後微信會來觸發這個腳本,是處理業務邏輯的地方
14 //訂單號能夠靈活使用,好比我這個地方把userid加進去,在異步回調的時候方便直接操做用戶
15 $out_trade_no = $time."__".$userid; 
16 
17 // 下面的參數含義直接看文檔
18 $tmpArr = array(
19     'appid'=>$appid,   //不要填成了 公衆號原始id
20     'attach'=>$title, 
21     'body'=>$title,
22     'mch_id'=>$mch_id,
23     'nonce_str'=>$nonce_str,  
24     'notify_url'=>$notify_url,
25     'out_trade_no'=>$out_trade_no, 
26     'spbill_create_ip'=>$_SERVER['REMOTE_ADDR'],
27     'total_fee'=>$money,
28     'trade_type'=>'MWEB' 
29     );
30 // 簽名邏輯官網有說明,簽名步驟就不解釋了
31 ksort($tmpArr);  
32 
33 $buff = "";
34 foreach ($tmpArr as $k => $v)
35 {
36    $buff .= $k . "=" . $v . "&";
37 }
38 $buff = trim($buff, "&");
39 $stringSignTemp=$buff."&key=51b3363e91fe317fc346526f5933f15e";
40 $sign= strtoupper(md5($stringSignTemp)); //簽名
41 
42 $xml = "<xml>
43            <appid>".$appid."</appid>
44            <attach>".$title."</attach>
45            <body>".$title."</body>
46            <mch_id>".$mch_id."</mch_id>
47            <nonce_str>".$nonce_str."</nonce_str>
48            <notify_url>".$notify_url."</notify_url>
49            <out_trade_no>".$out_trade_no."</out_trade_no>
50            <spbill_create_ip>".$_SERVER['REMOTE_ADDR']."</spbill_create_ip>
51            <total_fee>".$money."</total_fee>
52            <trade_type>MWEB</trade_type>
53            <sign>".$sign."</sign>
54         </xml> ";
55 
56 $posturl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
57 
58 $ch = curl_init($posturl);
59 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
60 curl_setopt($ch, CURLOPT_POST, 1);  
61 curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); 
62 $response = curl_exec($ch);  
63 curl_close($ch);
64 
65 $xmlobj = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA ))); 
66 exit($xmlobj->mweb_url);

 ------------------------------------------

wxpay_wap_notify.php

 1 // 本腳本的業務邏輯只是個例子,僅供參考
 2 
 3 // 拿到原始數據並經過xml類解析爲對象
 4 $postObj = simplexml_load_string(file_get_contents("php://input"), 'SimpleXMLElement', LIBXML_NOCDATA );
 5 // 你能夠經過下面這種方式來看一下微信究竟返回了那些參數,請保證log.php存在而且有寫權限
 6 // file_put_contents(dirname(__file__)."/log.php",file_get_contents("php://input"));
 7 $arr = array();
 8 foreach ($postObj as $key => $value) {
 9     $arr[$key] = $value;
10 } 
11 // 訂單狀態
12 $status = $arr['result_code'];
13 
14 if(trim($status) == "SUCCESS") {
15     // 微信訂單
16     $out_trade_no = $arr['transaction_id'];
17 
18         // 價格
19         $money = $arr['total_fee']/100;
20         // 在商戶訂單號中提取用戶id,上一個腳本中我說了這個商戶訂單號能夠靈活使用
21         $uid = explode("__", $arr['out_trade_no'])[1];
22 
23         // 在數據庫中檢查這個訂單號是否已經處理過了 以避免重複處理,由於不少緣由微信可能屢次觸發本腳本
24         // checkrepeat(orderid);
25 
26         /////////////////////////////////////////////////////////////
27         ////                                                    /////
28         ////    這裏處理業務邏輯....                            /////    
29         ////                                                    /////            
30         /////////////////////////////////////////////////////////////
31 
32         // 處理完邏輯 返回這個xml數據,告訴微信服務器,這個訂單號已經處理完了 不要在來騷擾我了
33         $xml = "
34                 <xml>
35                   <return_code><![CDATA[".$status."]]></return_code>
36                   <return_msg><![CDATA[OK]]></return_msg>
37                 </xml>";
38         echo $xml;
39         
40 }

 若是須要微信掃碼支付或者支付寶支付相關文章,請在個人php分類中查看

相關文章
相關標籤/搜索