主机参考:VPS测评参考推荐/专注分享VPS服务器优惠信息!若您是商家可以在本站进行投稿,查看详情!此外我们还提供软文收录、PayPal代付、广告赞助等服务,查看详情! |
我们发布的部分优惠活动文章可能存在时效性,购买时建议在本站搜索商家名称可查看相关文章充分了解该商家!若非中文页面可使用Edge浏览器同步翻译!PayPal代付/收录合作 |
这次给大家展示一下如何用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 -微信支付,然后就可以进入KOA 2 KOA -微信支付了。然后脚手架会自动创建相应的文件夹koa-wechatpay,生成基本骨架。转到该文件夹并安装相应的插件。输入:
NPINSTALL #或YARN然后可以输入npm start或yarn start来运行项目(默认监听端口是3000)。
如果没有出错,您的项目运行,然后我们用postman测试它:
该路径位于routes/index.js中
如果你看到
{ 标题 : koa2 json }表示没问题。(如果有问题,检查端口是否被占用等等。)
接下来,我们将在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( # 39;md5 # 39)const appid = # 39xxx # 39const mch _ id = # 39yyy # 39const mch _ api _ key = # 39zzz # 39const notify _ url = # 39http://XXX/API/notify # 39;//服务器可访问的域名和接口const server _ IP = # 39;xx . xx . xx . xx # 39;//服务器的ip地址const trade _ type = # 39原生 # 39;//原生对应二维码扫描支付let body = # 39XXX的充值付款 # 39;//用于支付界面显示的提示然后开始写签名函数:
const signString = (fee,ip,nonce)= gt;{ let tempString = ` appid = $ { appid } ;body = $ { body } mch _ id = $ { mch _ id } nonce _ str = $ { nonce } notify _ url = $ { notify _ url } out _ trade _ no = $ { nonce } spbill _ create _ ip = $ { ip } total _ fee = $ { fee } trade _ type = $ { trade _ type } key = $ { 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订单号: # 39;xxx # 39,//order _ nocodeurl来自后端: # 39;xxx # 39//code_url} from the back end}在methods中写一个查询订单信息的方法:
// ...handleCheckBill(){ return setTimeout(()= gt;{如果(!this.payStatus this.retryCount lt120){ this . retry count+= 1 axios . post( # 39;/API/check -bill # 39;,{//向后端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: # 39;1mb # 39,编码:CTX . request . charset | | # 39;ut F-8 # 39;})consters = await Parse XML(XML)//Parse XML if(RES . return _ code = = # 39;成功 # 39;){ if(RES . result _ code = = = # 39;成功 # 39;){//如果支付成功则为成功//...下面是写入数据库的相关操作//开始发回微信ctx.type = # 39应用程序/XML # 39;//指定发送的请求类型为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 = # 39;应用程序/XML # 39;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( # 39;/API/notify # 39;,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( # 39;/API/check -bill # 39;,checkBill)相信你看完这个案例已经掌握了方法。更多精彩请关注主机参考其他相关文章!
推荐阅读:
Koa2微信微信官方账号开发的本地开发调试环境如何操作
如何操作Koa2微信微信官方账号实现消息管理?以上是如何使用Koa2开发微信二维码扫描支付的细节。请多关注主机参考其他相关文章!
这几篇文章你可能也喜欢:
本文由主机参考刊发,转载请注明:如何用Koa2开发微信二维码扫描支付 https://zhujicankao.com/80350.html
评论前必须登录!
注册