场景

在做pc端的支付时,我们常用的就是生成二维码让用户去扫码支付。
like this:

当然你想像我一样有个二维码支付的图片,还需要先申请微信支付的native支付功能。
native支付会提供一个二维码供用户扫码。
页面内,通常会有一个按钮,通过按钮的点击事件来调用支付接口,支付接口返回的数据如下:

这里面的qrcodeUrl是一个base64格式的图片数据,我们使用image的src属性接收这个数据就能得到一个二维码图片了。

问题

通常的话,会使用一个弹窗内嵌image标签展示二维码,这样就存在一个重复支付的隐患:
用户在扫码支付完成后,如果页面的弹窗未关闭,那二维码就会一直呈现在页面内,会给用户造成未支付的错觉。那么用户就会再次扫描二维码进行支付,这样就会造成重复支付的问题。


所以呢,我们需要在用户支付成功之后把弹窗关闭,这样就可以解决这个问题了。
具体的实现方式就是—>
弹窗内部进行支付结果监测的轮询,一旦支付结果监测出为支付成功,就把弹窗关闭。

实现

说起轮询,其实就是频繁的调取接口访问某个状态的变化。
这样的话很容易想起setInterval,但是使用setInterval会有一个问题就是:很任性!
不管不顾:在它内部执行的指令,它可不管你是执行与否,到时间就再次执行。

setInterval的机制就是执行一个异步队列,每次都会把事件添加到队列里面。当前队列为空的时候,会到事件队列里面去取,如果当前队列执行时间长了点,事件队列里面就会被添加很多事件,当前队列执行完成后,事件队列的事件就会短时间内连续触发,相较于我们使用setInterval进行轮询的初衷就会背道而驰。

所以,可以使用setTtimeout来代替setinterval进行实现。在settimeout中循环调用达到轮询的效果,并且settimeout的机制保证了每个事件都是在前一个执行完毕后再执行的。
OK,方法确定下来就可以着手效果实现了。
使用watch监听弹窗v-model绑定的属性:

visible的true和false控制弹窗的开、闭。
watch进行监听可以执行异步方法。在handle函数内使用setTimeout调用支付结果监测的接口进行轮询,并通过接口返回的支付状态字段清除定时器和关闭弹窗。
具体的代码实现就是:

payStatus: {handler(newVal) {const timer = window.setInterval(() => {setTimeout(function () {//检测支付结果时需要传的数据let data = {orderCode: newVal,};//检测支付结果的接口checkPayResult(data).then((res) => {if (res.data.code == rayframework_http_success_code) {//返回的支付状态字段用来判断是否支付成功if (res.data.result.isPaymentSubmited == 1) {this.visible = false;clearInterval(timer);}}});}, 0);}, 2000);//清除定时器this.$once('hook:beforeDestroy', () => {clearInterval(timer);});},},

这里看着是不是思路清晰,逻辑无误?
可怜见的,我写好的时候也是美滋滋的,直到—>
弹窗关不了!弹窗关不了!弹窗关不了!
没关系!我自查:
我在this.visible=false下面打印this.visible
控制台显示:

这没错啊,既然是false,说明我改visible的值是改好的呀,那为什么弹窗不关闭呢?
想不通……

中午吃饭在想、路上在想、去洗手间在想、喝水在想……
小小的脑袋大大的疑惑,到底这是为什么!
电光火石之间(脑子抽抽),我在this.visible=false上面打印了this.visible
是的,把它当成三明治夹起来,上下都打印,出现了这个:

undefined!!!
很明显,我的data里面是有这个属性,否则我不可能打开弹窗,现在出现undefined是在表明什么???
我是个笨蛋:
明明函数的嵌套关系很多了,明明使用了settimeout函数,明明函数内还使用this,我还是没有考虑this的指向问题,倒是用它用的起劲,出现问题抓耳挠腮就是找不到源头,要不是脑子抽抽,今天晚上睡觉估计梦里都是我改了visible的值,弹窗还是没关,到底为什么。
好在这下找到问题了。
两个解决方案:
①settimeout等函数使用箭头函数(死去的ES6语法突然攻击我)
②在未进入定时器的函数内使用that保存this的属性值,再进行改变值的时候就能直接操作到visible本身了。
至于this.visible=false上面打印出来undefined,下面倒是false是因为这个过程相当于属性重新创建的过程。
可喜可贺,问题顺利排查出来,并且解决方法也有了,这下可以实现了(我用了第二种):

payStatus: {handler(newVal) {const timer = window.setInterval(() => {let that = this;setTimeout(function () {let data = {orderCode: newVal,};checkPayResult(data).then((res) => {if (res.data.code == rayframework_http_success_code) {if (res.data.result.isPaymentSubmited == 1) {that.visible4 = false;clearInterval(timer);}}});}, 0);}, 2000);//清除定时器this.$once('hook:beforeDestroy', () => {clearInterval(timer);});},},

效果

点击支付操作,内部的click事件调用native支付接口返回qrcodeurl,就是二维码图片

把二维码图片放在弹窗的image标签内

用户扫码,弹窗内进行轮询事件检测支付状态,支付成功弹窗关闭并刷新页面(处理支付状态显示的问题)。
整个流程是不是很清晰,并且相关问题的解决方案也有提供多种噢~
如果这篇文章对您有用,麻烦:

pc端微信二维码支付流程及问题排查相关推荐

  1. 对接微信二维码支付流程

    客户在平台下单 平台生成订单记录并且请求微信支付系统获取支付链接地址 微信支付系统响应支付地址通过平台H5技术生成支付二维码 用户扫描支付二维码跳转支付链接地址并且微信支付系统校验支付链接有效性 用户 ...

  2. 微信测试号实现个人第三方PC端网站二维码登录(代码实现篇)

    我页面使用了生成二维码的js,是网上拿到的(太多转载,具体作者是啥不知道(#^.^#)) 点击打开生成二维码js链接  直接复制js就OK. 好,正文来啦,我代码中是使用了springboot(SSM ...

  3. 微信二维码支付支付宝二维码支付(主扫模式)开发指南

    微信二维码支付 熟悉微信支付全家桶的童鞋应该都清楚,微信支付是没有提供PC网关支付的,那么传统的网站需要怎么接入微信支付产品呢? 我们可以选择微信支付中的Native支付产品,官方介绍: Native ...

  4. Java支付宝二维码支付和退款,微信二维码支付

    在蚂蚁金服开发平台下载demo 打开 TradePayDemo 项目,里面的main可以直接运行,在配置文件zfbinfo.properties中改为自己支付宝的信息 # 支付宝网关名.partner ...

  5. 微信测试号实现个人第三方PC端网站二维码登录

    这里只提及微信二维码登录PC网站的实现方面,对于微信测试号如何申请,如何授权,本篇博客不去讲解. 测试号申请:http://mp.weixin.qq.com/debug/cgi-bin/sandbox ...

  6. 微信二维码支付快速入门

    目录 一.二维码生成插件qrious 二.HttpClient 三.微信扫码支付 1.申请步骤 2.开发文档 四.入门Demo 1.工程搭建 2.myStudy-pay-interface 3.myS ...

  7. springboot整合微信二维码支付

    微信支付官方文档:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/api.shtml 下图是微信支付的一个流程图: 我们需要做的是: 1.调用 ...

  8. 关于前端调用微信二维码支付,二维码无法显示的问题

    昨天测试提交了一个bug,说是公司网站调用微信支付时无法显示微信二维码,于是去测试环境测试了一下,发现果然有问题: 此时后台日志打印了如下信息,微信接口返回的错误提示是:"invalid s ...

  9. 如何实现微信二维码支付功能???

    首先呢,要实现微信支付,首先要申请一个公众号,人家支付的money才能到你口袋噢,不然,你可以不用申请,来, 给你提供一个号,尽管支付,别客气,嚯嚯[偷笑] 咱们别造了哈, 直接开货吧!!! 一. 微 ...

  10. 百度网盘PC端扫描二维码登录时无法加载二维码问题解决方法

    问题: 今天在PC端扫描登录百度网盘时,二维码无法加载出来,具体情况如图: 解决方法: 1.打开IE浏览器 2.打开工具 3.打开Internet选项 4.打开高级选项,重置IE设置 5.点击确定,打 ...

最新文章

  1. 玲珑杯 1157 - 造物主的戒律 主席树+离散化
  2. 图像有用区域 bfs
  3. 某公司的网络管理员职责
  4. SpringMVC实现RESTful风格
  5. JavaScript 面向对象编程(二) —— 构造函数 / 原型 / 继承 / ES5 新增方法
  6. python数据结构剑指offer-反转链表
  7. 件测试专家分享III GUI自动化测试相关
  8. 排序的概念及分类实现
  9. icem合并面网格_ICEM CFD中合并多个网格
  10. 背单词App开发日记6(终章总结)
  11. 单车---------Eason
  12. 软考--后缀式(逆波兰式)的两种求法
  13. ye我们胜利了的shooow
  14. 荣耀8一下显示无服务器,买到荣耀手机后,不打开这七个功能你就亏了!
  15. 精华|风控相关欺诈防范要点(规则制定)
  16. OpenGL入门示例8——图形平移、旋转、缩放
  17. 从小市值因子策略入手,带你入门量化投资 (附年化收益率77.83%策略)
  18. geohash网格图_Geohash 网格聚合
  19. 如何提高强化学习算法模型的泛化能力?
  20. php求价格最低,php-将Woo-commerce变体销售价格调至低于实际价格

热门文章

  1. Crystal Reports基础知识
  2. vb6计算机,[计算机软件及应用]VB6.ppt
  3. RHadoop搭建(HBase)
  4. 数据可视化网页内容自动抓取工具
  5. 28个超有用的PPT小技巧,快来收藏
  6. C语言基础知识目录大纲
  7. 华罗庚杯成绩查询2021高考成绩,逆天了,这所学校的华罗庚杯成绩“臻”厉害...
  8. 智课雅思词汇---十九、前缀se是什么意思
  9. php求1000以内的素数 10个一行,1000以内的素数_php求1000以内质数
  10. linux脚本运行出现bc,Linux硬件管理命令---bc