2018年10月9日 星期二

微信支付 by APP 備忘

首次接內地的金流,恩恩...看來跟呆灣差不多? 總之這個案例又有個整合的服務,WEB請求APP支付所以於是這般有了這篇...

參考文件
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1

關係圖


幾個陷阱註記一下:
1. 開通前要先接sandbox這裡面就存在呼叫XML裡面的key得改用sandbox簽署的而不是跟微信申請下來的"支付API秘钥"。
參考文件: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_1

2. sign簽名檔的生成得將"所有要傳送的資料"都帶入計算,依照文件說明的做會得到簽名錯誤的回覆。
參考文件:  https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3

3. micropay是信用卡付費的,接APP付費得帶unifiedorder,prepay_id在micropay是沒有回傳的。
https://api.mch.weixin.qq.com/sandboxnew/pay/micropay
https://api.mch.weixin.qq.com/sandboxnew/pay/unifiedorder

4. 呼叫時SSL關掉會比較單純(不然會有憑證上的錯誤回傳),微信會給證書檔記得匯入到WEB SERVER環境內。
$url = $weixin_url;
$header[] = "Content-type: text/xml"; 
$ch = curl_init ($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlData);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$response = curl_exec($ch);

5. 交換格式是使用XML,所以接收時這邊的接法是...
$post_data = file_get_contents("php://input");
libxml_disable_entity_loader(true);
$msg = json_encode(simplexml_load_string($post_data , 'SimpleXMLElement', LIBXML_NOCDATA));
$rtn_data = json_decode($msg, true);

6. 驗證回傳值(key需先進行排序,以免因順序不同而造成sign不一致)真偽後,告知微信已收到。
ksort($rtn_data);
$buff ='';
foreach($rtn_data as $k=>$v){
  if ($k != 'sign'){
$buff .= $k.'='.$v . '&';
  }
}
//若是沙箱模式則$weixin_key須重新透過getsignkey來取得,不然SIGN算出來還是錯的。
$stringSignTemp = $buff . 'key='. $weixin_key;
$sign=strtoupper(md5($stringSignTemp));
if ($sign == $rtn_data['sign']){
  $err_code = '00';
  echo '<xml>
              <return_code><![CDATA[SUCCESS]]></return_code>
              <return_msg><![CDATA[OK]]></return_msg>
          </xml>';
}

7. APP要導頁進行付費,透過JS進行FUNC呼叫,這部分若是要使用 $(document).ready(function(){});進行呼叫時,務必Include jquery-XXX.js 不然不會動作。

echo '<script type="text/javascript" language="javascript">
window.onload = function() {
window.weixin.startWechatPay('".$prepay_id."','".$nonce_str."','".$saletime."','".$sign."')";
    }
  </script>';