這兩天完成了公司網站手機和PC端的支付對接,就是支付寶和微信.
對接完后有所感觸,我們來聊一聊,微信支付的坑,為什么這么說呢,因為我在對接完支付寶后是很愉快的,基本上在demo上稍加修改就ok了,
對於支付寶我覺得基本上都沒什么可以說的,而微信支付...
網上搜了一下,基本上沒有看到有針對h5支付的成功教程,全都是復制粘貼官方文檔,有意思嗎.
恰好今天空了,來聊一聊微信支付的坑,當然本文也不是光吐槽了事,我會把完整的代碼放到文末尾處,並加以適當的注釋.
------------------------------
首先第一步去微信商戶平台開通h5支付的.
因為公司的app中的微信支付是我對接的,所以在開始做手機網站的微信支付前,我首先想到去微信開放平台,新建了一個網站應用,
最后審核下來居然沒有支付接口,只有獲取用戶信息的接口,我有點蒙筆,然后我打了一下客服電話,那邊客服說h5支付在公眾號平台中完成(注意:這里客服mm向我扔了一個巨坑,接着往下看)
既然這樣,我就去了微信公眾號平台,我們有服務號,拿着appid和mch_id就開始搞,一切都很好,但是提示[商戶號該產品權限預開通中,請等待產品開通后重試],
我趕緊登錄商戶平台看一下,確定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分類中查看