微信公眾號內H5調用微信支付國內服務商模式


最近在折微信公眾號內H5用JSAPI調用微信支付,境內服務商版支付,微信支付給出的官方文檔以及SDK不夠詳細,導至我們走了一些彎路,把他分享出來,我這邊主要是用PHP開發,所以未加說的話示例都是PHP代碼

微信的官方文檔  https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=7_1

 

1.服務商模式下調用統一下單

獨立商戶模式統一下單:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

服務商模式下統一下單:https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_1

統一下單與與獨立商戶模式之間有一點點修改,兩個參數,sub_mch_id,sub_appid,原來的openid 參數改為sub_openid

 
         

**
* 文件:WxPayPubHelper.php * 統一支付接口類 * Class UnifiedOrder_pub */ class UnifiedOrder_pub extends Wxpay_client_pub { public function __construct() { //設置接口鏈接 $this->url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; //設置curl超時時間 $this->curl_timeout = WxPayConf_pub::getParams('curl_timeout'); } /** * 生成接口參數xml * @return string|void */ public function createXml() { try { //檢測必填參數 if ($this->parameters["out_trade_no"] == null) { throw new SDKRuntimeException("缺少統一支付接口必填參數out_trade_no!" . "<br>"); } elseif ($this->parameters["body"] == null) { throw new SDKRuntimeException("缺少統一支付接口必填參數body!" . "<br>"); } elseif ($this->parameters["total_fee"] == null) { throw new SDKRuntimeException("缺少統一支付接口必填參數total_fee!" . "<br>"); } elseif ($this->parameters["notify_url"] == null) { throw new SDKRuntimeException("缺少統一支付接口必填參數notify_url!" . "<br>"); } elseif ($this->parameters["trade_type"] == null) { throw new SDKRuntimeException("缺少統一支付接口必填參數trade_type!" . "<br>"); } elseif ($this->parameters["trade_type"] == "JSAPI" && $this->parameters["openid"] == NULL ) { throw new SDKRuntimeException("統一支付接口中,缺少必填參數openid!trade_type為JSAPI時,openid為必填參數!" . "<br>"); } /************************************服務商模式修改***********************************/ if(WxPayConf_pub::getParams('sub_mchid')){ //服務商模式 $this->parameters["sub_mch_id"] = WxPayConf_pub::getParams('sub_mchid'); $this->parameters["sub_appid"] = WxPayConf_pub::getParams('sub_appid'); $this->parameters["sub_openid"] = $this->parameters["openid"]; unset($this->parameters["openid"]);//去掉原來的openid } /************************************服務商模式修改結束***********************************/

$this->parameters["appid"] = WxPayConf_pub::getParams('appid');//公眾賬號ID $this->parameters["mch_id"] = WxPayConf_pub::getParams('mchid');//商戶號 $this->parameters["spbill_create_ip"] = $_SERVER['REMOTE_ADDR'];//終端ip $this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串 $this->parameters["sign"] = $this->getSign($this->parameters);//簽名 return $this->arrayToXml($this->parameters); } catch (SDKRuntimeException $e) { die($e->errorMessage()); } }

  

2.服務商模式下JSAPI調用微信支付

官方給出H5調用API支付文檔:https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=7_7&index=6 

而我們之前一直立商戶模式,用的是JSSDK :https://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html

調試統一下單時還算比較順利,因為獲取prepay_id不成功無非就是參數的問題,並且返回給我們的錯誤也非常詳細,可以很快定位問題。可是這個JSAPI可就把我弄慘了,先看代碼(javascript)

// 微信支付調用方法
  function weixinpayFun() {
  var buildformUrl = 'http://local.test/pay/getparams?orderid=訂單號';//獲取微信支付相關參數 $.post(buildformUrl, {},
function (res) { $.hideLoading(); if (res.status) { var wxpayParam = res.data; // 發起一個支付請求 wx.chooseWXPay({ timestamp: wxpayParam.timeStamp, nonceStr: wxpayParam.nonceStr, package: wxpayParam.package, signType: wxpayParam.signType, paySign: wxpayParam.paySign, trigger: function (res) { }, complete: function (res) { }, success: function (res) { $.alert('支付成功'); }, cancel: function (res) { $.alert('支付已取消'); }, fail: function (res) { alert(JSON.stringify(res)); $.alert('支付失敗'); } }); } else { $.alert('微信支付失敗!'); } }, 'json'); }

由這段代碼可以看到,我們是通過Ajax方式調用微信支付統一下單並獲取到JSAPI的支付參數的,這在獨立商戶模式下是沒有問題的,並且是使用了很長一段時間。

改用服務商模式后,奇怪的問題就來了,每次請求從日志中看到統一下單是成功的,也就是說我的參數與簽名也都是沒有問題的,但是返回給我的錯誤見下圖

從各方了解到,出現這個錯誤的原因是簽名錯誤,於是我就各種各樣的調整簽名參數,把sub_appid ,appid 換來換去,或者一起結合起試,都不行。中間有咨詢過微信支付的技術人員,對方也是幫忙分析了一下確認是簽名錯誤,但根據他要求提供了相關參數檢查后簽名是正確的。最終也是沒有完全搞定。

今天上午因為要處理另外一個問題,公眾號從公眾平台授權會引起獨立商戶支付出錯,完全調不出支付界面,(因為之前我們都是讓客戶填寫url,token appid,appsecret之類的參數的,現在改成了公眾平台授權) 發現我們在一個初始的地方做了個JSSDK的初始化主要用於調用分享 ,見下面的代碼

 <script>
    window.onload = function onload() {
      jwx.initialize({
        appId: '{$sys_params.jsapi_param.appId}',
        timestamp: '{$sys_params.jsapi_param.timestamp}',
        nonceStr: '{$sys_params.jsapi_param.nonceStr}',
        signature: '{$sys_params.jsapi_param.signature}'
      }, function () {
        jwx.setShareData({
          title: '分享標題',
          desc: '描述',
          link: "分享的鏈接",
          imgUrl: '分享顯示的圖片'
        });
        if ("function" === typeof jwxCallback) {
          jwxCallback();
        }
      });
    };
  </script>

由於是授權所以沒有了appsecret這個參數,導致無法正常獲取JSAPI初始化參數,經過一番代碼修改,終於授權的公眾號可以正常使用獨立商戶的微信支付了,改完突然想起,中間咨詢微信支付的技術大神有提到過config文件中的nonceStr和timestamp,由此想到會不會是這個JSAPI初始參數用的appid與appsecret 用的是子商戶的appid和appsecret引起的呢?把他換成服務商的試試呢,這一試可不就把問題給解決了.

3.總結

微信支付使用JSAPI發起支付時要注意: JSAPI初始化參數與調用統一下單時的參數(appid,appsecret)要一致,否則會出現莫名的簽名錯誤

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM