主机参考:VPS测评参考推荐/专注分享VPS服务器优惠信息!若您是商家可以在本站进行投稿,查看详情!此外我们还提供软文收录、PayPal代付、广告赞助等服务,查看详情! |
我们发布的部分优惠活动文章可能存在时效性,购买时建议在本站搜索商家名称可查看相关文章充分了解该商家!若非中文页面可使用Edge浏览器同步翻译!PayPal代付/收录合作 |
这次,我将为您带来如何使用Koa2开发微信二维码扫描支付。使用Koa2开发微信二维码扫描支付有哪些注意事项?下面是一个实际案例。让我们来看看。
前段时间我在开发一个功能,需要通过微信二维码扫码支付。我们无时无刻不在看到这样的场景,各种电子商城、线下自动售货机等都会有这个功能。通常只有用户,但现在的开发商,没有小坑。所以我在此写了一篇博客来记录它。
注意:要开发微信二维码支付,必须拥有相应商户号的权限,否则无法开发。没有相应的权限,本文不建议阅读。
两种模式
当我们打开微信支付的文档时,我们可以看到两种支付模式:模式1和模式2。微信文档中给出了两者的流程图(但说实话,真的很丑)。
该文件指出了两者之间的区别:
在开发第一个模型之前,商家必须在公共平台的后台设置支付回调URL。URL实现的功能:接收用户扫码后微信支付系统回调的productid和openid。
与模式1相比,模式2的流程更简单,并且不依赖于设置的回调支付URL。商家后台系统首先调用微信支付的统一点餐接口,微信后台系统返回链接参数code_url。商家后台系统根据code_url值生成二维码图片,用户使用微信客户端扫码后发起支付。注:code_url的有效期为2小时。到期后,扫码无法再发起支付。
模式1在平时网购中比较常见。会弹出一个专门的页面进行扫码支付,然后在支付成功后,该页面会再次跳转回回调页面通知您支付成功。第二个不太正确,但第二个开发起来相对简单。本文主要介绍模式2的发展。
为Koa2构建简单的开发环境
快速搭建Koa2的开发环境。我推荐使用KOA -生成器。脚手架可以帮助我们在Koa项目开始时节省一些基本的中间件编写步骤。如果你想学Koa,你最好自己建一个。如果你已经知道Koa,你可以使用一些快速脚手架。)
首先,全球安装KOA -发电机:
NPM安装-G Koa -发电机# ORYAN GLOBAL添加Koa -发电机,然后找到一个目录来存储Koa项目。我们计划将这个项目命名为KOA -微信支付,然后我们可以输入KOA 2 KOA -微信支付。然后脚手架会自动创建相应的文件夹koa-wechatpay并生成基本骨架。进入该文件夹并安装相应的插件。输入:
Npm install # oryarn然后您可以输入npm start或yarn start来运行项目(默认情况下监听端口3000)。
如果没有任何问题,您的项目将运行,然后我们将使用postman测试它:
该路径位于routes/index.js中
如果你看到
{“title“:“KOA 2 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 yarn add MD5 const MD5 = require(‘MD5‘)const appid =‘XXX‘const mch _ id =‘yyy‘const mch _ API _ key =‘zzz‘const notify _ URL =‘http://XXX/API/notify‘/服务器和接口可访问的域名const server _ IP =‘xx . xx . xx . xx‘/IP地址const trade _ type =‘Native‘//Native对应于二维码扫描支付let body =‘XXX
const sign string =(fee,ip,nonce)=》{ let tempString = ` appid = $ { appid } & body = $ { body } & mch _ id = $ { mch _ id } & nonce _ str = $ { nonce } & notify _ URL = $ { notify _ URL } & out _ trade _ no = $ { nonce } & Sp bill _ create _ IP = $ { IP } & total _ fee = $ { fee } & trade _ type = $ { trade _ type } & key = $ { mch _ API _ key }toupper case()}其中fee是要充值的费用,以分钟为单位。比如充值1元,手续费是100。Ip是一个可选选项,只要测试符合规则的ip,我将在下面使用server_ip。Nonce是微信要求的32位以内的不重复字符串,通常可以使用订单号等唯一标识字符串。
由于与微信服务器的通信都是xml格式的,现在我们需要手动组装post请求的xml:
const xml body =(fee,nonce _ str)=》{ const XML = ` $ { appid } $ { body } $ { mch _ id } $ { notify _ URL } $ { nonce _ str } $ { fee } $ { server_ip } NATIVE $ { sign string(fee,Server _ IP,nonce _ str)} ` return { XML,out _ trade _ no: nonce _ str}}如果您担心签名的XML字符串有问题,可以提前检查一下
即时战略游戏
因为我需要向微信服务器发送请求,所以我选择了axios,这是一个可以在浏览器和节点上发送ajax请求的库。
安装过程将不再详细描述。继续在微信支付中写发送请求的逻辑
因为微信也会给我们返回一个xml格式的字符串。所以我们需要提前编写一个解析函数,将xml解析成js对象。为此,您可以安装一个xml2js。安装过程和上面类似,我就不重复了。
微信将返回以下格式的xml字符串:
我们的目标是转换成以下js对象,以便我们可以使用js操作数据:
{ return _ code:‘SUCCESS’,//SUCCESS or fail return _ msg:‘ok’,appid:‘wx 742 xxxxxxxx’,mch _ id:‘14899 xxxxxxxx’,nonce _ str:‘r 69 q xxxxxxxx x 60’,sign:‘79f 0891 xxxxx x 189507 a 184 xxxxxxxx’,result _ code:‘SUCCESS’,prepay _ id:‘wx 152316 xxxxxxxx’,trade _ type:‘NATIVE’,code _ URL:‘weixin://wx pay/pr = dqnakh‘///用于生成付款二维码的链接}因此我们编写一个函数并调用xml2js来解析xml:
//将XML转换为JS对象const parse XML =(XML)=》{ Return New Promise((RES,rej)=》{ xml2js . parse string(XML,{trim: true,explicit array: false},(err,JSON)=》{ if(err){ rej(err)} else { RES(JSON。XML)} } }上面的代码返回了一个Promise对象,因为xml2js的操作是回调函数中返回的结果,所以为了配合Koa2的async和await,我们可以将其封装到Promise对象中,并通过RESOLUTION传递解析后的结果。因此您可以使用await来获取数据:
consta xios = require(‘axios‘)const URL =‘https://api.mch.weixin.qq.com/pay/unified订单‘//微信服务器地址const pay = async(CTX)。=》{ const form = CTX。request.body//Data常量订单号=‘xxxxxxxxxxxxxxxxx’//非重复订单号常量费用= form.fee //费用值常量数据= XML body(fee,orderNo)//通过前端传输的费用是费用,订单号是订单号(唯一)常量RES = await axios . post(URL,{data: data.xml})。然后(async RES =》{ const resjson = await parse XML(RES . data)return resjson//get the returned data })。catch(err =》{ console . log(err)})If(RES . return _ code = =‘success’){//If返回的returnctx.body = {success: true,message:‘请求成功’,code_url: res.code_url,// code_url是链接order_no: orderNo //订单号}} CTX。body = {success: false,message:‘请求失败‘} }路由器。过帐(“/API/pay”,支付)模块。出口=路由器。然后,我们将把这个路由器安装到根目录中的应用程序。
找到前面默认的两个路由,一个索引和一个用户:
Const index = require(。/routes/index‘)const users = require(。/routes/users‘)const we chat pay = require(。/routes/we chat pay‘)//在此处添加并转到页面底部以装载此路线:
//RoutesApp。使用(索引。路由(),索引。允许的方法())App。使用(用户。路由(),用户。允许的方法())App。使用(微信支付。路由(),用户。allowed Methods())//添加到这里,这样就可以。(如果有一个跨域的解决方案需要你自己考虑,你可以把它放在与Koa相同的域中,你也可以打开一层代理来转发它,你也可以打开一个CORS头等。)
请注意,在本例中,前端用于生成QR码。事实上,也可以通过后端生成二维码,然后将其返回到前端。但是,为了简单演示起见,本例使用前端在获取code_url后生成二维码。
显示付款二维码
我用Vue做前端。当然,你可以选择你喜欢的前端框架。这里的重点是通过获取刚刚从后端传递的code_url来生成一个二维码。
在前端,我使用库@ xke Shi/vu E-二维码生成二维码。它的呼唤特别简单:
从“@ xke Shi/vue -二维码”导入vue二维码导出默认{组件:{vue二维码},//...其他代码}然后您可以使用前端的组件来生成二维码:
将它放入对话框时会发生以下情况:
文字是我自己加的。
付款成功后自动刷新页面。
有两种方法可以成功地将付款写入数据库。
一种是打开扫码对话框后继续向微信服务器轮询支付结果。如果支付成功,它将向后端发送请求,告诉后端支付成功,并让后端写入数据库。
一种是后端保持接口开放,等待微信向后端的notify_url发起post请求,告知后端支付结果,让后端写入数据库。然后当前端轮询后端时,它应该去数据库获取轮询订单的支付结果,如果支付成功则关闭对话框。
第一种简单但不安全:想象一下,如果用户在成功支付时关闭了页面,或者用户成功支付,但出现了网络问题,导致前端无法将成功支付的结果发送到后端,那么后端已经无法写入成功支付的数据。
第二个比较麻烦,但是可以保证安全。所有支付结果必须通过微信主动通知后端,后端保存数据库后再返回前端消息。这样,即使用户在成功支付时关闭了页面,下次打开时,由于数据库已被写入,他也将获得成功支付的结果。
因此,这部分页面会在支付成功后自动刷新。我们将其分为两部分:
前端部分
Vue的数据部分
数据:{payStatus: false,//不成功的重试次数:0,//轮询次数,从0-200 order no:‘XXX‘,// order _ nocodeurl从后端:‘XXX‘//code _ URL }从后端}编写一个方法以在方法中查询订单信息:
// ...handleCheckBill(){ return setTimeout()=》{ if(!this . pay status & & this . retry count { if(RES . data . success){ this . pay status = true location . reload()//如果你懒的话用reload刷新页面} Else {this。HandleCheckBill()} })。catch(err =》{ console。log(err )} } Else { location。reload()},1000)}此方法在打开二维码对话框时启用。然后开始投票。我预定了一个时间,如果仍然没有支付信息,则在200秒后自动刷新页面。其实你可以根据项目的需要自己定义这个时间。
后端部分
前端到后端只有一个接口,后端却有两个接口。一个用来接收微信的推送,一个用来接收前端的查询请求。
先写微信最关键的推送请求处理。因为我们接收微信的请求是在Koa的路由中,并且是以流的形式传输的。Koa需要支持解析xml格式的主体,因此您需要安装一个rawbody来获取xml格式的主体。
//处理微信支付并发回通知//如果收到的消息需要发回微信,是否收到const Handle notify = async(CTX)=》{ const XML = await raw body(CTX . req,{length: ctx.request.length,limit:‘1mb‘,Encoding:CTX . request . charset | |‘ut F-8‘})cons RES = await parse XML(XML)//parse XML If(RES . return _ code = =‘success‘65{ If(RES . result _ code = =‘SUCCESS‘){//如果所有支付都成功则成功//...以下是与写入数据库相关的操作//开始发回微信ctx . type =‘application/XML‘//指定发送的请求类型为xml //发回微信,告知您已收到返回的CTX . body = ` ` ` } }//如果支付失败,也发回微信CTX。状态= 400 CTX。type =‘application/XML‘CTX。Body = ``}路由器。post(“/API/notify”,处理通知)。这里的坑是XML Koa处理微信返回。如果你不知道它是以raw -体的形式发回的,那么它将被调试很长时间。。
接下来,这是一个相对简单的前端回归。
const check bill = async(CTX)=》{ const form = CTX。请求。body const orderno = form。orderno const result = await数据库操作If(result){//如果订单支付成功,则返回CTX。body = {success: true}} CTX。状态= 400 CTX。body = {success: false}}路由器。post(‘/API/check -bill,checkbill)相信你看完这个案例已经掌握了方法。更多精彩请关注主机参考其他相关文章!
推荐阅读:
Koa2微信微信官方账号开发的本地开发调试环境如何操作?
Koa2微信微信官方账号如何操作实现消息管理?
以上就是如何使用Koa2开发微信二维码扫码支付的细节。更多资讯请关注主机参考其他相关文章!
这几篇文章你可能也喜欢:
- 最适合Android开发的Linux发行版是什么?(linux android开发)
- 哪个Linux系统最适合Android开发?
- linux在嵌入式系统开发领域的广泛应用(嵌入式Linux应用场景)
- 微信官方账号开发详细介绍(微信官方账号开发方法)
- 传智和黑马微信公众平台开展视频资料共享(传智黑马培训学校怎么样)
本文由主机参考刊发,转载请注明:如何用Koa2开发微信二维码扫码支付 https://zhujicankao.com/105289.html
评论前必须登录!
注册