論微信公眾號支付到底有多坑
先吐個嘈,接個微信支付,斷斷續續一個多星期。。。。。。要是趕著上線的話,黃花菜都涼了,哪裡錯了根本不給提示。。。
好了,我們來梳理一下介入流程,其實極其簡單!
首先要區分的是你接的是不是公眾號支付:公眾號支付指的是在微信公眾號或者微信瀏覽器內調起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生成規則,再來生成一次,是不是坑!!!!雖然,引數文件裡也時那麼寫的,細想想,人家確實沒說是微信返回的,那邊還寫了簽名生成規則~~~~
怨自己吧,,,,
之後將例子給的調起函式放到前端適當位置,將引數填寫正確,微信的公眾號支付就完成了。。。。。。
慶祝一下吧!!!!!!!!!!