1. 程式人生 > >論微信公眾號支付到底有多坑

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

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

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

首先要區分的是你接的是不是公眾號支付:公眾號支付指的是在微信公眾號或者微信瀏覽器內調起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生成規則,再來生成一次,是不是坑!!!!雖然,引數文件裡也時那麼寫的,細想想,人家確實沒說是微信返回的,那邊還寫了簽名生成規則~~~~

怨自己吧,,,,

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

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