详解基于Koa2开发微信二维码扫码支付相关流程

2020-06-17 06:55:42易采站长站整理

orderNo: 'xxx', // 从后端传来的order_no
codeUrl: 'xxx' // 从后端传来的code_url
}

在methods里写一个查询订单信息的方法:


// ...
handleCheckBill () {
return setTimeout(() => {
if (!this.payStatus && this.retryCount < 120) {
this.retryCount += 1
axios.post('/api/check-bill', { // 向后端请求订单支付信息
orderNo: this.orderNo
})
.then(res => {
if (res.data.success) {
this.payStatus = true
location.reload() // 偷懒就用reload重新刷新页面
} else {
this.handleCheckBill()
}
}).catch(err => {
console.log(err)
})
} else {
location.reload()
}
}, 1000)
}

在打开二维码Dialog的时候,这个方法就启用了。然后就开始轮询。我订了一个时间,200s后如果还是没有付款信息也自动刷新页面。实际上你可以自己根据项目的需要来定义这个时间。

后端部分

前端到后端只有一个接口,但是后端有两个接口。一个是用来接收微信的推送,一个是用来接收前端的查询请求。

先来写最关键的微信的推送请求处理。由于我们接收微信的请求是在Koa的路由里,并且是以流的形式传输的。需要让Koa支持解析xml格式的body,所以需要安装一个rawbody 来获取xml格式的body。


// 处理微信支付回传notify
// 如果收到消息要跟微信回传是否接收到
const handleNotify = async (ctx) => {
const xml = await rawbody(ctx.req, {
length: ctx.request.length,
limit: '1mb',
encoding: ctx.request.charset || 'utf-8'
})

const res = await parseXML(xml) // 解析xml

if (res.return_code === 'SUCCESS') {
if (res.result_code === 'SUCCESS') { // 如果都为SUCCESS代表支付成功
// ... 这里是写入数据库的相关操作

// 开始回传微信
ctx.type = 'application/xml' // 指定发送的请求类型是xml
// 回传微信,告诉已经收到
return ctx.body = `<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
</xml>
`
}
}

// 如果支付失败,也回传微信
ctx.status = 400
ctx.type = 'application/xml'
ctx.body = `<xml>
<return_code><![CDATA[FAIL]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
</xml>
`
}

router.post('/api/notify', handleNotify)

这里的坑就是Koa处理微信回传的xml。如果不知道是以

raw-body
的形式回传的,会调试半天。。

接下来这个就是比较简单的给前端回传的了。