关注分享主机优惠活动
国内外VPS云服务器

如何用Koa2开发微信二维码扫描支付

这次给大家展示一下如何用Koa2开发微信二维码扫描支付。使用Koa2开发微信二维码扫描支付有哪些注意事项?以下是实际案例。让我们来看看。

前段时间在开发一个功能,需要通过微信二维码扫码支付。这种场景对我们来说并不少见。各种电子商城,线下自动售货机等。会有这个功能。平时只是用户,现在是开发者,也有很大的漏洞。所以我写了一篇博客来记录它。

注意:要开发微信二维码支付,必须有相应商家号的权限,否则无法开发。本文不建议在没有相应权限的情况下阅读。

两种模式

当我们打开微信支付的文档,可以看到两种支付模式:模式一和模式二。微信文档里给出了两者的流程图(不过说实话真的有点难看)。

文件指出了两者的区别:

在开发模式之前,商家必须在公众平台后台设置支付回拨URL。URL的作用:接收用户扫码后微信支付系统回调的productid和openid。

与第一种模式相比,第二种模式流程更简单,不依赖于设置的回拨支付URL。商家后台系统先调用微信支付的统一下单接口,微信后台系统返回链接参数code_url。商家后台系统将code_url值生成二维码图片,用户用微信客户端扫码后发起支付。注意:code_url的有效期为2小时。到期后,扫码不能再发起支付。

首先,这种模式在我们网上购物时很常见。会弹出一个专门的页面进行扫码支付,然后支付成功后,这个页面会再次跳转回回拨页面通知你支付成功。第二个不太正确,但是第二个开发起来相对简单。本文主要介绍模式二的发展。

Koa2构建一个简单的开发环境

我推荐你可以用koa-generator快速搭建Koa2的开发环境。脚手架可以帮助我们在Koa项目初期省去一些基本的中间件编写步骤。想学Koa,最好自己建一个。如果你已经知道Koa,你可以使用一些快速脚手架。)

首先在全球安装KOA -发电机:

NP install -g Koa-generator # or yann全局添加Koa -generator然后找一个目录存放KOA项目。我们打算把这个项目命名为koa-wechatpay,然后就可以进入koa2 koa-wechatpay了。然后脚手架会自动创建相应的文件夹koa-wechatpay,生成基本骨架。转到该文件夹并安装相应的插件。输入:

NPINSTALL #或YARN然后可以输入npm start或yarn start来运行项目(默认监听端口是3000)。

如果没有出错,您的项目运行,然后我们用postman测试它:

该路径位于routes/index.js中

如何用Koa2开发微信二维码扫描支付-主机频道

如果你看到

{ & quot标题& quot:& quotkoa2 json & quot}表示没问题。(如果有问题,检查端口是否被占用等等。)

接下来,我们将在routes文件夹中创建一个新的wechatpay.js文件来编写我们的流程。

符号

与微信的服务器通信的一个关键部分是签名必须正确。如果签名不正确,那么一切都是徒劳的。

首先我们需要去微信官方账号的后台获取下面对应的id或者我们需要的关键信息。其中,notify_url和server_ip是我们支付成功后,微信会主动将支付成功的信息发布到这个url。

签名算法如下:https://pay.weixin.qq.com/wiki/doc/api/native.php?章=4_3

为了正确签名,我们需要安装md5。

NPM install MD5 --save # or yann add MD5 const MD5 = require(& # 039;md5 & # 039)const appid = & # 039xxx & # 039const mch _ id = & # 039yyy & # 039const mch _ api _ key = & # 039zzz & # 039const notify _ url = & # 039http://XXX/API/notify & # 039;//服务器可访问的域名和接口const server _ IP = & # 039;xx . xx . xx . xx & # 039;//服务器的ip地址const trade _ type = & # 039原生& # 039;//原生对应二维码扫描支付let body = & # 039XXX的充值付款& # 039;//用于支付界面显示的提示然后开始写签名函数:

const signString = (fee,ip,nonce)= & gt;{ let tempString = ` appid = $ { appid } & amp;body = $ { body } & ampmch _ id = $ { mch _ id } & ampnonce _ str = $ { nonce } & ampnotify _ url = $ { notify _ url } & ampout _ trade _ no = $ { nonce } & ampspbill _ create _ ip = $ { ip } & amptotal _ fee = $ { fee } & amptrade _ type = $ { trade _ type } & ampkey = $ { MCH _ API _ key } ` return MD5(tempstring)。Toupper Case ()}其中fee是要充值的费用,分为多个单位。比如充值1元,手续费是100。Ip是可选的,只要测试符合规则的ip,下面我用server_ip。Nonce是微信要求的32位以内不重复的字符串,通常可以使用订单号等唯一标识符字符串。

由于与微信的服务器通信都是用xml,现在我们要手工组装post请求的xml:

const xmlBody = (fee,nonce _ str)= & gt;{ const xml = ` & ltxml & gt& ltappid & gt$ { appid } & lt/appid & gt;& ltbody & gt$ { body } & lt/body & gt;& ltmch _ id & gt$ { mch _ id } & lt/mch _ id & gt;& ltnonce _ str & gt$ { nonce _ str } & lt/nonce _ str & gt;& lt通知_ url & gt$ { notify _ url } & lt/notify _ URL & gt;& ltout _ trade _ no & gt$ { nonce _ str } & lt/out _ trade _ no & gt;& lttotal _ fee & gt$ { fee } & lt/total _ fee & gt;& ltspbill _ create _ ip & gt$ { server _ ip } & lt/sp bill _ create _ IP & gt;& lt贸易类型& gtNATIVE & lt/trade _ type & gt;& lt符号& gt${signString(fee,server_ip,nonce _ str)} & lt;/sign & gt;& lt/XML & gt;` return {xml,out _ trade _ no: nonce _ str}}如果怕自己签名的xml字符串有问题,可以提前在微信提供的签名验证工具里检查一下,看能不能通过。

即时战略游戏

因为需要用微信服务器发出请求,所以选择了axios,一个可以在浏览器和节点发起ajax请求的库。

将不详细描述安装过程。继续在wechatpay.js写发送请求的逻辑

因为微信也会返回一个xml格式的字符串给我们。所以我们需要提前编写解析函数,把xml解析成js对象。为此,您可以安装一个xml2js。安装过程和上面类似,这里不再赘述。

微信将返回如下格式的xml字符串:

& ltxml & gt& ltreturn _ code & gt& lt!

付款成功自动刷新页面。

有两种方法可以成功地将付款写入数据库。

一种是扫码对话框打开后继续轮询微信服务器支付结果。如果支付成功,它会向后端发送请求,告诉后端支付成功,让后端写入数据库。

一种是后端保持接口开放,等待微信向后端的notify_url发起post请求,告知后端支付结果,让后端写入数据库。然后前端轮询后端的时候要去数据库获取订单的支付结果,如果支付成功就关闭对话框。

第一种相对简单但不安全:想象一下,如果用户在支付成功的同时关闭页面,或者用户支付成功,但由于网络问题,前端无法将支付成功结果发送到后端,那么后端始终无法写入支付成功数据。

第二种虽然麻烦,但是保证了安全。所有支付结果都要等微信主动通知后台,后台会保存数据库再返回前端消息。即使用户在支付成功的同时关闭页面,下一次打开时,数据库已经被写入,那么他得到的就是支付成功的结果。

因此,我们可以将这部分支付成功分为两部分:

前端部分

Vue的数据部分

数据:{payStatus: false,//不成功重试次数:0,//轮询次数,从0-200订单号:& # 039;xxx & # 039,//order _ nocodeurl来自后端:& # 039;xxx & # 039//code_url} from the back end}在methods中写一个查询订单信息的方法:

// ...handleCheckBill(){ return setTimeout(()= & gt;{如果(!this.payStatus & amp& ampthis.retryCount & lt120){ this . retry count+= 1 axios . post(& # 039;/API/check -bill & # 039;,{//向后端OrderNo: this.orderNo}请求订单的付款信息)。然后(RES = >;{ if(RES . data . success){ this . pay status = true location . reload()//懒的话用reload刷新页面} else {this.handleCheckBill ()}}。catch(err = >;{ console . log(err)} } else { location . reload()} },1000)}打开二维码对话框时启用此方法。然后开始轮询。我订了一个时间,200s后如果还是没有支付信息,页面会自动刷新。其实这个时间你可以根据项目需要自己定义。

后端部分

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

先写微信最关键的推送请求处理。因为我们从微信收到的请求是在Koa的路由中,并且是以流的形式传输的。Koa需要支持解析xml格式的body,所以需要安装rawbody来获得xml格式的body。

//处理微信支付返回通知//如果收到消息,要返回给微信。收到const handle notify = async(CTX)= >;{ const xml = await rawbody(ctx.req,{ length: ctx.request.length,limit:& # 039;1mb & # 039,编码:CTX . request . charset | | & # 039;ut F-8 & # 039;})consters = await parse XML(XML)//parse XML if(RES . return _ code = = & # 039;成功& # 039;){ if(RES . result _ code = = = & # 039;成功& # 039;){//如果支付成功则为成功//...下面是写入数据库的相关操作//开始发回微信ctx.type = & # 039应用程序/XML & # 039;//指定发送的请求类型为xml //发回微信,告知returnctx.body = ` < xml & gt& ltreturn _ code & gt& lt![CDATA[成功]]& gt;& lt/return _ code & gt;& ltreturn _ msg & gt& lt![CDATA[OK]]& gt;& lt/return _ msg & gt;& lt/XML & gt;`} }//如果支付失败,也会发回微信CTX . status = 400 CTX . type = & # 039;应用程序/XML & # 039;ctx.body = ` & ltxml & gt& ltreturn _ code & gt& lt![CDATA[失败]]& gt;& lt/return _ code & gt;& ltreturn _ msg & gt& lt![CDATA[OK]]& gt;& lt/return _ msg & gt;& lt/XML & gt;`} router . post(& # 039;/API/notify & # 039;,handleNotify)这里的坑是Koa处理微信返回的xml。不知道是不是以raw -体的形式返回,就调试半天。。

接下来送回前端就相对简单了。

const check bill = async(CTX)= & gt;{ const form = CTX . request . body const orderno = form . orderno const result = await数据库操作if (result) {//如果订单支付成功,返回CTX . body = { success:true } } CTX . status = 400 CTX . body = { success:false } } router . post(& # 039;/API/check -bill & # 039;,checkBill)相信你看完这个案例已经掌握了方法。更多精彩请关注即时码站其他相关文章!

推荐阅读:

Koa2微信微信官方账号开发的本地开发调试环境如何操作

如何操作Koa2微信微信官方账号实现消息管理

未经允许不得转载:主机频道 » 如何用Koa2开发微信二维码扫描支付

评论 抢沙发

评论前必须登录!