基于vue2的h5页面实现拉起支付宝app支付且轮询支付结果

news/2024/12/19 20:44:10/文章来源:https://www.cnblogs.com/nangras/p/18617908

*只有前端部分

 

1.首先data需要储存几个值:

      payUrl: "", // 订单支付跳转链接
      isFetchCode: false, //正在生成订单
      payStatus: "", // 订单状态,用于判断是否还需要继续请求订单支付结果接口
      userDown: false, // 用户点击已支付完成按钮
      timer: null, // 轮询计时器
      goZfbSrc: null, // 用于解决ios系统下safari浏览器不支持window新开窗口的计时器

以及其他订单进行中弹窗、支付成功弹窗等状态管理

 

2.用户点击支付后,请求后端接口,拿到支付宝跳转链接:

// 点击购买,获取商品支付地址async showQrCode() {if (this.isFetchCode) return;this.isFetchCode = true;try {const { code, msg, data } = await api.createOrder({...传参});if (code === 0 && data) {const { jump_url, orderno, create_dt } = data;// 获取订单编号及下单时间this.orderno = orderno;this.createTime = create_dt;this.payUrl = jump_url;// 关闭下单弹窗this.payVisible = false;// 打开订单进行中弹窗this.codeVisible = true;// 支付宝支付if (this.payType === "alipay_mobile") {// 微信浏览器中选择支付宝支付,弹窗复制支付链接,提示用户在外部浏览器打开进行支付const browser = window.navigator.userAgent.toLowerCase();if (browser.match(/MicroMessenger/i) == "micromessenger") {this.copyVisible = true;} else {// 跳转支付宝this.payStatus = "waiting";this.pollOrder();this.goZfbSrc = setTimeout(() => {window.open(jump_url, "_blank");clearTimeout(this.goZfbSrc);});// window.location.replace(jump_url);// const a = document.createElement("a");// a.setAttribute("href", jump_url);// a.setAttribute("target", "支付");// document.body.appendChild(a);// a.click();// document.body.removeChild(a);// const form = document.createElement("form");// form.action = jump_url;// form.target = "_blank";// form.method = "POST";// document.body.appendChild(form);// form.submit();// const tempPage = window.open("_blank");// tempPage.location = jump_url;// window.open(jump_url, "_ blank");}} else {// 微信支付this.$toast("微信支付");// this.initiatePayment();}} else if (code === 87) {// 限购,打开限购弹窗this.$refs.fail.visible = true;} else if (code === 83) {this.$toast("订单生成失败,请重新选择商品购买,如有疑问请咨询客服查询");} else {this.$toast(msg || "获取失败");}} catch (err) {//} finally {this.isFetchCode = false;}},

  

肉眼可见为了这个该死的sarari尝试了多少种方案= =无论是创建a标签手动触发点击事件,还是通过创建表单通过提交表单的方式拉起,还是直接使用window.open开新窗口,都不可以,最终是利用了setTimeout这个利器才解决这个问题。

而safari不允许的原因也很简单,它默认开启了阻止弹出窗口的策略,禁用了通过代码调用超链接在新标签打开页面的功能,避免window.open被滥用。但这个阻止弹出窗口的操作,并不是完全禁止,而是会根据用户的行为来判断这次window.open()是否属于流氓操作。

所以,聪明的程序员利用setTimeout运行于主线程的这个特点,把打开链接的操作放到setTimeout里运行即可,这样就不会被浏览器认定为代码操作,避免了被拦截。

谢谢你,大佬。(虎目含泪)

 

2.实现拉起app之后,接着就是页面轮询了:

    // 间隔刷新订单支付状态pollOrder() {this.timer = setInterval(() => {if (this.payStatus === "waiting" && this.codeVisible) {// 未完成且订单进行中的弹窗未关闭,则继续请求this.queryPayStatus();} else {// 已成功完成/关闭弹窗,清空计时器clearInterval(this.timer);this.timer = null;}}, 3000);},

  

    // 查询支付状态async queryPayStatus() {try {const { code } = await api.orderPolling({orderno: this.orderno,});if (code === 0) {this.payStatus = "success";this.codeVisible = false;this.sucVisible = true;clearInterval(this.timer);} else if (code === 22) {this.payStatus = "";this.$toast("订单已失效,请重新购买");this.codeVisible = false;clearInterval(this.timer);} else {// 如果是用户手动查询,弹出状态提示if (this.userDown) {this.$toast("订单未完成支付,请确认支付状态");this.userDown = false;}}} catch (err) {//} finally {//}},

  

3.以及手动点击查询:

    // 用户点击刷新支付状态userSearchStatus() {this.userDown = true;this.queryPayStatus();},

  

 那么简单的h5页面拉起支付宝支付就完成鸟~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/855580.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

less5

1.在URL处输入 ?id=1 ?id=1 ?id=1" ?id=1/1发现回显只有you are in......和报错 报错:判断回显是布尔类型 使用order by发现回显有三栏 ?id=1 order by 4%23 ?id=1 order by 1%23 ?id=1 order by 3%23判断数据库长度:8位 ?id=1 and length((select database()))&g…

Java-递归查询部门下所有子部门(包括本部门)

Java-递归查询部门下所有子部门(包括本部门),会得到一个部门id的集合:List deptIds具体代码如下: //递归1public List<Long> queryAllSubInstitutionIds(Long institutionId) {List<Long> subInstitutionIds = new ArrayList<>();querySubInstitutionIds…

生物医学信息

生物信息学基础 生物医学信息学的概念的掌握生物信息学很大一部分工作体现在生物数据的收集、存储、管理与提供 利用多组学数据(基因组,转录组,表观遗传组、蛋白组等)和机器学习、数据挖掘的方法 ,挖掘潜在的生物学、医学的知识和模式,用于解决诊断和治疗。中心法则是什么…

5、导出表

5、导出表 typedef struct _IMAGE_EXPORT_DIRECTORY {DWORD Characteristics;DWORD TimeDateStamp;WORD MajorVersion;WORD MinorVersion;DWORD Name; // 指向 导出表的文件名DWORD Base; // 导出函数的起始序号DWORD NumberOfFunctions; // 所有导…

4、文件与内存转换相关

4、文件与内存转换相关 FileBufferToImageBuffer 也是一样的长话短说。这里涉及了一点,就是内存对齐 PE头与节区之间 节区与节区时间会发生内存对齐。在文件中有一个文件对齐 ​​ 在可选PE头中有这两个进行标识,之前也写过这个内存对齐的博客,这里就不多说了 下面贴几个代…

1、PE 初识

1、PE 初识 概论 首先 PE头部分主要是学习PE结构的前半部分,每一个是做什么的,以及重点是什么,每一个是做什么用的。并使用Cpp代码来解析该PE头 注意这里用了一个Windows.h的头文件,后面再说。 PE是Windows系统 PE结构(Portable Executable),即可移植可执行文件格式,是…

交换空间swap

交换空间: 交换空间是硬盘上的一部分,被用作虚拟内存,当系统的物理内存(RAM)不足时,系统会使用交换空间来存储暂时不用的数据。1.关闭交换空间 1)关闭所有交换空间 swapoff -a2)关闭特定的交换空间 swapoff /dev/sdb12.开启交换空间 1)开启所有交换空间 swapon -a2…

2024 IDEA 2024.3 安装使用教程(附激活至2099年,以及常见问题处理)

IntelliJ IDEA简介 IntelliJ IDEA是一款非常强大的Java集成开发环境(IDE),由JetBrains公司开发。它提供了丰富的功能和工具,帮助开发者更高效地编写、调试和部署代码。 下面这种方式仅供交流学习,如果有能力还请支持正版 下载安装 下载 IDEA 2024.3 版本的安装包 为了方便,也…

第十六次作业

1、通过华为云沃土云创计划免费薅云服务器 打开链接:https://developer.huaweicloud.com/programs/dev-program.html 使能⽅向选择个⼈在这个 计划权益中申请优惠券免费购买成功2、复现windows、linux权限维持技巧 windows权限维持: 隐藏⽂件:利⽤⽂件属性 ⽂件右键属性,勾…

OpenCL 编程步骤 2. 获取设备

clGetDeviceIDs 查询支持OpenCL设备列表: cl_int clGetDeviceIDs(cl_platform_id platform ,cl_device_type device_type ,cl_uint num_entries ,cl_device_id *devices ,cl_uint *num_devices )与clGetPlatformIDs函数类似,第一次调用时,devic…

记录一下:小华半导体HC32F448建立MDK工程

1.先到官网上下载文件 a>下载驱动库:HC32F448_DDL_Rev1.1.0.zip 驱动库中是包括了例程的。 b>下载样例:HC32F448_Template_Rev1.0.1.zip 可以直接复制官方的样例,就不用自己创建工程了。 c>下载芯片支持包:HC32F448_IDE_Rev1.0.1.zip 下载后双击安装即可。否则KEI…

4大应用场景揭秘:AI视频监控在养老院中的智能化管理与安全保障

随着人口老龄化的加剧,养老院的管理面临着越来越多的挑战。传统的人工巡查方式不仅难以做到全天候监控,而且存在响应迟缓、效率低下等问题。为了解决这些问题,思通数科推出的AI视频监控系统,利用人工智能技术提供了一种高效、智能化的解决方案。尤其在养老院的老人体征监控…