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

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

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

 

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

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

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

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

 
 

**
* 文件: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 app

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

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

// 微信支付調用方法
  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)要一致,不然會出現莫名的簽名錯誤

相關文章
相關標籤/搜索