前言
本篇文章主要是记录本人在微信扫码支付过程中所遇到的问题,给大家一个借鉴作用,希望对你们有帮助
开发环境
- nodejs v8.1.0
- egg v1.1.0 @H_301_11@
准备工作
微信公众号-appid
微信商户号-mch_id
key值(签名算法所需,其实就是一个32位的密码,可以用md5生成一个)(key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置)
扫码支付-统一下单
以下才用的是微信模式二,因为比较简单
以上就是我们所需要的一些参数
签名生成算法见微信官方:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=4_3
spbill_create_ip 是 终端ip地址
下面把所有的参数拼接成xml
// xml转json格式
xml2js.parseString(resultData.data,function (err,json) {
if (err) {
new Error("解析xml报错")
} else {
var result = formMessage(json.xml); // 转换成正常的json 数据
console.log(result) //打印出返回的结果
}
})
var formMessage = function (result) {
var message = {};
if (typeof result === 'object') {
var keys = Object.keys(result);
for (var i = 0; i < keys.length; i++) {
var item = result[keys[i]];
var key = keys[i];
if (!(item instanceof Array) || item.length === 0) {
continue;
}
if (item.length === 1) {
var val = item[0];
if (typeof val === 'object') {
message[key] = formMessage(val);
} else {
message[key] = (val || '').trim();
}
} else {
message[key] = [];
for (var j = 0,k = item.length; j < k; j++) {
message[key].push(formMessage(itemp[j]));
}
}
}
}
return message;
}
上面使用了egg的请求方式,原生node可以使用request
如果请求成功会最终返回一个xml,然后我们进行解析成json的格式,里面会有一个code_url和out_trade_no,我们需要把这两个返回给前端,然后通过生成二维码展示给用户扫码,完成支付
监听支付是否成功
上面操作完成之后,我们需要知道用户是否完成支付,因为用户会停留在该页面,我们需要在用户付完款之后,通知用户支付成功。
首先,用户发起支付的时候我们会生成二维码,让用户完成扫码支付,我们还要做的是,开一个定时器,每隔一段时间去发送一个请求,这个时候,我们node后台就需要写一个查询订单的接口,之前我们拿到了out_trade_no,也就是我们系统内部的订单号,我们把这个数据发送给后台查询订单的接口,然后后台接收到之后会请求微信的查询接口地址https://api.mch.weixin.qq.com/pay/orderquery,流程跟上面一样,只是接口地址和微信返回的xml不一样而已,返回的字段会有一个状态即SUCCESS和NOTPAY,我们可以通过判断是否支付返回给前端,成功之后提示给用户支付成功,关闭定时器。
回调地址
这个是非常重要的一环,大部分的操作其实在上面就可以完成,但是有特殊的情况,比如用户电脑断网发送不了请求,但是手机付款了,这就会导致我们记录不到用户支付的信息。这个时候回调地址就很重要了
设置回调地址
微信商户中心->产品中心->开发配置->扫码支付
之后我们需要做的是后端用post来接收微信发送的异步回调信息,也是xml的格式,这里注意,如果不支持接收xml,可能会得到空的数据
这里还需要注意的是,我们在保存用户支付信息的同时,得先查改订单是否支付,以免重复操作,可能会插入多条记录的情况
总结
微信扫码支付坑还是有的,如果你是第一次摸索的话,下面罗列一下需要注意的地方