app内嵌h5支付功能,跳转支付宝&微信,vue组件

这篇具有很好参考价值的文章主要介绍了app内嵌h5支付功能,跳转支付宝&微信,vue组件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、功能梳理

app内前h5涉及到支付的功能,ios非实物商品实付需要使用ios原生支付方式,实物商品则可以三方支付,主要的实现思路为后端返回跳转支付宝或微信的支付scheme链接,前端进行跳转支付,同时需要实时查询用户的支付状态。

整个过程中复杂的部分在于查询用户支付状态的体验方面,需要保证用户在支付成功、支付失败、跳转支付宝、微信回来或者没有跳转支付宝微信等未知的行为下的用户体验。

组件内容为底部升起的支付选择弹窗,可以选择支付宝或者微信。

二、实现步骤

  1. 用户进行下单操作,前端调用下单接口,成功则返回三方支付app跳转链接,前端进行跳转

  1. 跳转三方app同时进行查询订单接口轮训,实时获取订单状态,轮训时间定位30s,依据需求调整

  1. 用户如果支付时间超过了30s未返回我们app的情况下,需要针对此种情况进行处理,捕捉用户返回我们app的情况

三、组件可支配参数&事件设置

设置支持参数2个、事件4个,分别为

参数:

successStatus: {
  default: '1'
}, // 支付成功的状态码,默认1
errorStatus: {
  default: '2'
} // 支付失败的状态码,默认2

事件:

@payMoney="payMoney" // 下单事件
@payStatus="payStatus" //查询支付状态事件
@succcessFunction="succcessFunction" // 成功支付操作
@errorFunction="errorFunction" // 失败实付操作

四、从支付app返回,事件捕获方法

为了防止用户在支付时间超过我们设置轮训时长情况,需要监听用户从支付app返回当前页面,来进行查询支付状态操作。方法为监听页面显示or隐藏事件文章来源地址https://www.toymoban.com/news/detail-464306.html

reloadState () {
  // 添加监听器
  if (typeof document.hidden !== 'undefined') {
    this.hidden = 'hidden';
    this.visibilityChange = 'visibilitychange';
  } else if (typeof document.mozHidden !== 'undefined') {
    this.hidden = 'mozHidden';
    this.visibilityChange = 'mozvisibilitychange';
  } else if (typeof document.msHidden !== 'undefined') {
    this.hidden = 'msHidden';
    this.visibilityChange = 'msvisibilitychange';
  } else if (typeof document.webkitHidden !== 'undefined') {
    this.hidden = 'webkitHidden';
    this.visibilityChange = 'webkitvisibilitychange';
  }
  document.addEventListener(this.visibilityChange, this.forceUpdate);
},
forceUpdate () {
  if (document.visibilityChange === this.hidden) {
  } else {
    this.searchTimer();
  }
},

五、组件源码

<template>
    <div class="pay-info">
        <div class="pay-content">
            <span class="pay-left"><img class="pay-icon" src="../assets/zfb.png" alt=""> 支付宝支付</span>
            <img class="radio-icon" src="../assets/radio2.svg" alt="">
        </div>
        <div class="pay-content">
            <span class="pay-left"><img class="pay-icon" src="../assets/wx.png" alt=""> 微信支付</span>
            <img class="radio-icon" src="../assets/radio2.svg" alt="">
        </div>
        <div class="pay-button" @click="payFun"><span>支付</span></div>
        <div class="loading-dom" v-if="loadingPay">
          支付中
          <van-loading color="#ffffff" style="margin-left: 5px"/> 
        </div>
    </div>
</template>

<script type="text/javascript">
export default {
  data () {
    return {
      isApp: !!browers.appUA,
      timer: null,
      loadingPay: false,
      orderNo: '', // 订单号
      payStatus: '' // 订单支付状态
    };
  },
  props: {
    successStatus: {
      default: '1'
    }, // 支付成功的状态码,默认1
    errorStatus: {
      default: '2'
    } // 支付失败的状态码,默认2
  },
  mounted () {
    this.$once('hook:beforeDestroy', () => {
      clearInterval(this.timer);
      this.timer = null;
    });
  },
  methods: {
    reloadState () {
      // 添加监听器
      if (typeof document.hidden !== 'undefined') {
        this.hidden = 'hidden';
        this.visibilityChange = 'visibilitychange';
      } else if (typeof document.mozHidden !== 'undefined') {
        this.hidden = 'mozHidden';
        this.visibilityChange = 'mozvisibilitychange';
      } else if (typeof document.msHidden !== 'undefined') {
        this.hidden = 'msHidden';
        this.visibilityChange = 'msvisibilitychange';
      } else if (typeof document.webkitHidden !== 'undefined') {
        this.hidden = 'webkitHidden';
        this.visibilityChange = 'webkitvisibilitychange';
      }
      document.addEventListener(this.visibilityChange, this.forceUpdate);
    },
    forceUpdate () {
      if (document.visibilityChange === this.hidden) {
      } else {
        this.searchTimer();
      }
    },
    payFun () {
      this.$emit('payMoney', (res) => {
        this.reloadState();
        // 下单接口的回调,执行轮训结果
        this.orderNo = res.order_no;
        this.loadingPay = true;
        this.searchPay();// 监听从其他app返回,为了解决从支付宝回来不轮训的问题
        setTimeout(() => {
          location.href = res.pay_address;
        }, 200);
      });
    },
    searchPay () {
      this.$emit('payStatus', (res) => {
        if (this.payStatus === '') {
          this.searchTimer();
        }
        // 下单接口的回调,执行轮训结果
        this.payStatus = res;
      });
    },
    searchTimer() {
      if (this.timer) {
        return;
      }
      if (this.orderNo) {
        let times = 0;
        this.searchPay();
        if (this.payStatus === '') {
          this.timer = setInterval(res => {
            times++;
            this.searchPay();
            if (this.payStatus === this.$props.successStatus) {
              clearInterval(this.timer);
              this.timer = null;
              this.loadingPay = false;
              document.removeEventListener(this.visibilityChange, this.forceUpdate);
              // 支付成功事件
              this.$emit('succcessFunction', (res) => {
              });
            }
            if (this.payStatus === this.$props.errorStatus) {
              clearInterval(this.timer);
              this.timer = null;
              this.loadingPay = false;
              document.removeEventListener(this.visibilityChange, this.forceUpdate);
              // 支付失败事件
              this.$emit('errorFunction', (res) => {
              });
            }
            if (times > 30) {
              this.$toast('未查询到支付状态,请重新支付');
              clearInterval(this.timer);
              this.timer = null;
              this.loadingPay = false;
              document.removeEventListener(this.visibilityChange, this.forceUpdate);
            }
          }, 1000);
        }
      }
    }
  }
};
</script>

<style lang="less" scoped>
.pay-info {
    .pay-content {
        background: #fff;
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 8px 0;
        font-size: 28px;
        color: #222;
        .pay-left {
            display: flex;
            align-items: center;
        }
        .pay-icon {
            width: 60px;
            height: 60px;
            margin-right: 10px
        }
        .radio-icon {
            width: 34px;
            height: 34px;
        }
    }
    .pay-button {
        width: 100%;
        text-align: center;
        margin-top: 30px;
        span {
            display: inline-block;
            background: #4e88f6;
            color: #fff;
            width: 100%;
            font-size: 32px;
            height: 88px;
            line-height: 88px;
            border-radius: 50px;
            display: inline-block;
        }
    }
    .loading-dom {
      width: 100%;
      height: 100vh;
      background: rgba(0,0,0,.5);
      color: #fff;
      text-align: center;
      font-size: 34px;
      font-weight: 500;
      position: fixed;
      display: flex;
      align-items: center;
      justify-content: center;
      top: 0;
      left: 0
    }
}
</style>

六、父组件调用

<Pay 
    @payMoney="payMoney"
    @payStatus="payStatus"
    @succcessFunction="succcessFunction"
    @errorFunction="errorFunction"
    :success-status='1'
    :error-status='2'
></Pay>
// 下单事件
    payMoney (callback) {
      this.$axios.post(`url`, params).then((res) => {
        let data = res.data;
        if (Number(data.code) === 0) {
            // 执行支付操作,跳转url,结果回调给收银台组件
          this.currentOrder = data.data.order_no;
          callback(data.data);
        } else {
          this.$toast(data.message);
        }
      }).catch((e) => {
      });
    },
    // 轮训状态接口
    payStatus (callback) {
      this.$axios.get(`url`).then((res) => {
        let data = res.data;
        if (Number(data.code) === 0) {
            // 执行支付结果查询,结果回调给收银台组件
          callback(data.data.pay_result);
          if (data.data.list && data.data.list.length) {
            this.resultData = data.data.list;
          }
        } else {
          this.$toast(data.message);
        }
      }).catch((e) => {
      });
    },
    succcessFunction () {
      // 支付成功父组件操作事件
      this.$toast('支付成功');
      // 先弹出支付成功提示,延时1秒出结果弹窗
      setTimeout(() => {
        // 支付成功后刷新一下接口
      }, 1000);
    },
    errorFunction () {
      // 支付失败父组件操作事件
      this.$toast('支付失败,请重新发起支付');
    },

到了这里,关于app内嵌h5支付功能,跳转支付宝&微信,vue组件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【微信小程序内嵌H5调用wx.miniProgram.navigateTo跳转无效问题】

    之前项目遇到的,各种判断逻辑都走通了,代码走到wx.miniProgram.navigateTo面前了就是跳转不了,试了很多种方法,都怀疑是这个api不适用了,结果一次尝试,发现还是地址的问题。 客户给的跳转地址: “pages/check/index/index.html?type=1” 试过但没成功的地址: “/pages/check/index/i

    2024年02月16日
    浏览(55)
  • 微信小程序webview内嵌H5跳转页面后没有返回按钮完美解决方案

    简单的讲就是我们可以在小程序内放置一个web-view组件来链接我们的HTML页面了。 但是点击跳转页面的时候。页面左上角没有!!返回按钮!!导致回不去了,这不是搞笑的吗。 看了下其他的小程序,发现如果是两个小程序页面跳转的话,第二个页面的左上角是会有返回按钮

    2024年02月08日
    浏览(53)
  • ThinkPHP 5 支付宝微信支付(支付宝H5,微信H5、APP支付、公众号支付)

     Pay.php支付控制器 模型:Weixin.php Weixin.php Alipay.php 支付宝需要的submit文件: 点击下载 wx.html在使用微信客户端支付时需要的页面    

    2024年02月08日
    浏览(44)
  • vue3引入JS-SDK实现h5分享小卡片、跳转微信小程序功能

    微信js-sdk官方文档: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 想要实现的效果: 1.登录微信公众平台,进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。 2.通过npm引入js-sdk 安装成功后,可以在package.json中找到\\\"weixin-js-sdk\\\" 3.在main.js中,将js-sdk挂载

    2024年02月11日
    浏览(53)
  • 利用webview 内嵌实现小程序,h5 ,app 页面跳转和数据通讯,附带实现pdf文件的预览(兼容ios和安卓)

    承载网页的容器。会自动铺满整个小程序页面, 个人类型的小程序暂不支持使用。 客户端 6.7.2 版本开始,navigationStyle: custom 对 web-view 组件无效 相关的属性说明:开放能力 / web-view (qq.com) 2.bindmessage 可以实现网页端和小程序之间通讯, 但只在特定时机触发 网页端向小程序

    2024年02月02日
    浏览(65)
  • H5页面内嵌到微信小程序和APP,做分享操作

    最近接到项目新需求,H5项目需要内嵌到微信小程序和APP里,然后将H5页面分享出去,被分享的人可以点击消息跳转到H5页面。H5页面不难,难的是要与微信小程序和APP进行交互,因为以前也没有接触过,所以这里卡的时间有点长。现分享出来 介绍 这里小编使用的是 uinapp 写的

    2024年02月06日
    浏览(92)
  • 微信小程序内嵌H5页面获取openid+分享功能

    主要实现功能:1.通过webview实现小程序内嵌H5页面                          2.在H5页面获取到用户的openid                          3.在H5页面实现分享获取到分享人的openid和被分享者的openid 代码实现: 1.通过webview实现小程序内嵌H5页面 传参:在地址后面加入的参数就是我

    2024年04月23日
    浏览(48)
  • 微信小程序内嵌h5页面,实现动态设置顶部标题的功能

    一、需求描述 使用HBuilder X作为开发工具,vue作为开发语言,开发微信小程序。微信小程序页面内嵌h5页面,即web-view/web-view标签。通过设置不同url连接地址,设置不同的标题。 二、失败做法 页面A嵌入h5页面,需要给A设置标题。最开始写法是在lonload页面内,使用如下语句实现

    2024年02月04日
    浏览(51)
  • app跳转至微信小程序进行支付

    app端代码:(app两套代码做参考) ios开发工具包(SDK) 前往下载  官方文档   官方文档  

    2024年02月16日
    浏览(57)
  • uni-app | 小程序嵌入H5页面实现支付功能

    前一阵在做公司小程序时,有个需要对接支付的功能。但是本着订单数据和支付统一入口的设计原则,计划是对接公司商城现有的支付体系。故本方案是分析对接商城支付几种可行方案以及每种方案的可行性,最后综合选出一种最佳的方案。 实现方式 跳转商城小程序支付 跳

    2024年02月07日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包