論微信公衆號支付到底有多坑

先吐個嘈,接個微信支付,斷斷續續一個多星期。。。。。。要是趕着上線的話,黃花菜都涼了,哪裏錯了根本不給提示。。。

好了,我們來梳理一下介入流程,其實極其簡單!

首先要區分的是你接的是不是公衆號支付:公衆號支付指的是在微信公衆號或者微信瀏覽器內調起H5支付,不要跟其他瀏覽器的H5支付混淆了。

流程:申請公衆號---服務號-----申請支付商戶----在線簽署協議,這個時商家自己搞,不過需要強調的是,有些商家有開發者商戶和運營商戶,一定要用跟服務號進行綁定的商戶。

開發步驟:

商戶:在商戶平臺設置公衆號支付目錄, 在產品中心----開發配置

公衆號:業務域名,請自行查看對域名的要求。     JS 安全域名    授權回調頁面域名  如果沒有特殊要求,都寫備案域名就好了。

以上就把開發配置做完了。

下面就是代碼開發了。

第一步:獲取code。這個需要將當前頁面跳轉到微信的授權頁面

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxe????????&redirect_uri=http%3a%2f%2f???????.com%2fchargeforcards&response_type=code&scope=snsapi_base&state=123#wechat_redirect

,有兩種,一種是彈出一個確認框的,大家在登錄第三方平臺時,給授權權限的那個就是。另外一種是 微信直接給你授權,但是不能給你提供用戶多餘的信息。支付我們直接用簡單的直接授權方式。 上邊的地址 appid爲服務號appid ,redirect_uri就是你想跳轉到的地址,即前端的路由地址。response 就是code  scope選擇base直接授權,state隨便寫就行。

這樣,當頁面跳轉完之後,當前頁面url中就有了code了,接下來就是從url中拿到code

function getQueryString(name) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
    var r = window.location.search.substr(1).match(reg);
    if (r != null) return unescape(r[2]); return null;
    }

拿到code之後,我們就時下一步的openid了,要在服務器端進行操作了,如果你是一個前端,學習下服務器後端~~~

這一步驟,需要code

https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxedf69f9306bc876a&secret=9c7e8cf23f5735ba30e16e326baa9af2&code="+code+"&grant_type=authorization_code"

從response中得到openid

之後就是調起微信統一支付接口了,坑就來了。。。。。

裏面需要好多參數,一定仔細讀參數要求,否則,奇坑無比。

強調 type  JSAPI   還有opid 時必傳參數,仔細看

ip通過ip = req.headers['x-real-ip'] ? req.headers['x-real-ip'] : req.ip.replace(/::ffff:/, ''); 這是nodejs的寫法,其他語言,請自行查找寫法。

之後,就時簽名算法了,簽名時區分大小寫的,請注意!

首先,先將參數字典排序,排序完之後,拼接,拼接完之後進行簽名算法,默認爲MD5,下面時nodejs的簽名算法,其他語言請自行書寫:

function raw(args) {
  var keys = Object.keys(args);
  keys = keys.sort()
  var newArgs = {};
  keys.forEach(function(key) {
    // newArgs[key.toLowerCase()] = args[key];
    newArgs[key] = args[key];
  });


  var string = '';
  for (var k in newArgs) {
    string += '&' + k + '=' + newArgs[k];
  }
  string = string.substr(1);
  return string;
};


function paysign(appid1, attach1, body1, mch_id1, nonce_str1, notify_url1, openid1, out_trade_no1, spbill_create_ip1, total_fee1, trade_type1) {
  var ret = {
    appid: appid1,
    attach: attach1,
    body: body1,
    mch_id: mch_id1,
    nonce_str: nonce_str1,
    notify_url: notify_url1,
    openid: openid1,
    out_trade_no: out_trade_no1,
    spbill_create_ip: spbill_create_ip1,
    total_fee: total_fee1,
    trade_type: trade_type1
  };
  var string = raw(ret);
  var key = "Tuokengzhilu******666666"  //這個key在商戶API設置,數字字母大小寫,32位
  string = string + '&key=' + key; //key爲在微信商戶平臺(pay.weixin.qq.com)-->賬戶設置-->API安全-->密鑰設置
  console.log(string + '--------1111111-------');
  var crypto = require('crypto');
  return crypto.createHash('md5').update(string).digest('hex').toUpperCase();
  // sign=MD5(stringSignTemp).toUpperCase()
};

簽名簽好之後,你就可以將內容填入xml中了,JS可以選擇字符串拼接。

然後將XML   post  到https://api.mch.weixin.qq.com/pay/unifiedorder

在這個過程中,可能會出現一直是簽名錯誤,如果你反覆確認,什麼都對,那就去重置一下APIkey,注意數字,字母大小寫結合的32位

之後,奇蹟就發生了,你獲得了SUCCESS,得到了prepay_id,那麼到這個時候,已經完成了一大半了,馬上就成功了~~~

微信返回給我們的是xml格式,我nodejs express 將xml轉化爲json

xml2js.parseString(resorder.data, {

          explicitArray: false
        }, function(err, json) {})

這樣我們得到了prepay_id

下邊就是微信內調起H5支付了,不過這裏還有一個小坑。。。這裏傳的sign並不是微信返回給我們的sign,而是我們根據前面sign生成規則,再來生成一次,是不是坑!!!!雖然,參數文檔裏也時那麼寫的,細想想,人家確實沒說是微信返回的,那邊還寫了簽名生成規則~~~~

怨自己吧,,,,

之後將例子給的調起函數放到前端適當位置,將參數填寫正確,微信的公衆號支付就完成了。。。。。。

慶祝一下吧!!!!!!!!!!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章