当前位置: 首页 > Web前端 > vue.js

vue递归轮询实现扫码支付

时间:2023-03-31 19:13:47 vue.js

本文是Vue的SPA与外部设备驱动的交互。需要从后台接口获取支付链接,传给外部设备(大屏智能设备)生成二维码。(当然你也可以通过支付链接自己转成二维码。)首先定义一个广播群,有“微信”和“支付宝”两种支付方式。如果paySucceed为true,表示支付成功,则提示支付成功,并隐藏支付radio微信支付宝payWayChange验证是因为外部设备的电脑驱动服务数据交互主要是通过websocket,所以需要在一开始通过webSocket.OPEN验证当前websocket浏览器和驱动/设备是否正常连接,如果连接不上,会提示并中断当前操作。当然,验证时需要重新设置(初始化)外部设备、支付状态、定时器。开始支付获取一些支付参数并通过接口(getPayStatus)获取支付url链接,调用openQRcode将链接传递给外部设备,显示支付二维码(这里可以使用qrcode的js库来实现)将其转换为二维码图像(二维码以跳转页面的形式显示)。这里调用openQRcode方法只是一个例子。外接设备一般都有js提供自己的驱动和对接驱动,根据自己的实际情况。支付(轮询)当二维码显示成功后,立即调用queryStatus(),以获取到的订单号为参数,进入支付状态查询(使用setTimeout轮询)。queryStatus内部是一个未打包的请求。当请求ReturningpayStatus时表示当前支付未完成,或者正在支付中,否则支付成功。每3秒轮询一次(尾递归queryStatus获取支付状态成功或失败):window.pollTimer=setTimeout(()=>{returnqueryStatus();//轮询查询支付状态3s},3000)inqueryStatus请求使用axios因为在post打包请求的pending过程中自动添加了“loading...”的全屏界面动画,因为轮询是连续的,无法显示loading动画,否则会导致每次获取status都会一直显示关闭/显示加载动画的闪屏效果,所以这里使用原来的axios支付来完成支付,支付成功后会有提示。满足递归终止条件,清零定时器,重置支付状态。last5stimer是给一个小的延时,防止支付成功后设备秒级关闭界面。if((res.payStatus==2)||(res.payStatus==1)){//支付成功,关闭弹窗that.paySucceed=true;window.pollTimer&&window.clearTimeout(window.pollTimer);//支付成功后做一些事情。..setTimeout(()=>{that.common.cancelAll();that.resetPay();},5000)}payWayChange(val){//清除定时器轮询状态clearTimeout(window.pollTimer);window.pollTimer=null;if(webSocket.readyState!=webSocket.OPEN){this.$message({message:'请正确连接设备或设备驱动未启动,请检查',type:'error'});this.resetPay();返回;}this.common.cancelAll();//关闭电子屏支付页面//参数letparams={type:val==='wechat'?'WeChatPay':'AliPay',data:{paymentType:1,id:'123',payMoney:'30.0',payWay:this.payWay,}}letthat=this;functionqueryStatus(){window.clearTimeout(window.pollTimer)axios({//使用axios,不显示loading提示method:'post',url:'getPayStatus',withCredentials:true,timeout:0,hideLoading:true,headers:{"Content-Type":"application/json;charset=UTF-8","token":sessionStorage.getItem('token')},data:{typeCode:val==='微信'?'WeChat':'ali',token:sessionStorage.getItem('token'),data:{order:params.order,}},}).then((res)=>{if(res.payStatus==0){window.pollTimer=setTimeout(()=>{returnqueryStatus();//轮询查询支付状态3s},3000)}if((res.payStatus==2)||(res.payStatus==1)){//支付成功,关闭弹窗that.paySucceed=true;window.pollTimer&&window.clearTimeout(window.pollTimer)//支付成功后做点什么..setTimeout(()=>{that.common.cancelAll();that.resetPay();},5000)}})}that.post({params,//parameters}).then(res=>{//获取支付链接和订单信息params=params.data;params.order=res.order;window.delayTimer=null;window.clearTimeout(window.delayTimer);window.delayTimer=setTimeout(()=>{//开启支付二维码this.common.openQRcode(encodeURI(JSON.stringify(params)),encodeURI(res.url))},1000);queryStatus();//开始轮询支付状态});},resetPay(){this.paySucceed=false;window.pollTimer&&window.clearTimeout(window.pollTimer);//清除定时器轮询状态},