此文章为记录学习使用。如有谬误,烦请各位大佬指教(鞠躬

介绍

h5页面,集成了

  • 微信浏览器环境支付(wx_pub
  • 支付宝手机网站支付(alipay_wap
  • 微信小程序支付(wx_lite
  • app支付(与我司app交互,由app调起微信appwx/支付宝appalipay支付)

支付流程

先附上文档👉PING++ H5 SDK 接入指南

大致流程如下:
准备后端接口参数=>调起后端接口获取ping++ charge对象 => 拿charge对象调用ping++ sdk => 获取ping++ 支付结果/处理支付结果

环境判断

因为是h5嵌在各种平台里面,所以需要判断当前是哪个平台。至于怎么判断的,自行解决哈哈哈哈

created() {
    const channels = [
      {
        icon: 'ic_wechat',
        title: '微信支付',
        tips: '推荐安装微信5.0及以上版本的用户使用',
        name: 'wx_pub'
      },
      {
        icon: 'ic_alipay',
        title: '支付宝支付',
        tips: '推荐有支付宝账户的用户使用',
        name: 'alipay_wap'
      },
    ]
    if(this.$env.wechatApplet) {
      this.paySubChannel = 'wx_lite' // 默认实际支付渠道
      this.paySubChannels = [] // 实际可选的支付渠道数组
    } else if(this.$env.wechat) {
      this.paySubChannel = 'wx_pub'
      this.paySubChannels = channels.slice(0, 1)
    } else if(this.$env.alipay) {
      this.paySubChannel = 'alipay_wap'
      this.paySubChannels = channels.slice(1)
    } else { // app
      this.paySubChannel = ''
      this.paySubChannels = channels
    }
  },

准备后端接口参数以获取ping++ charge对象

在调用后台接口获取ping++ charge对象前,一些不同渠道支付的所需参数要准备好。

tips: params是请求后端接口需要的参数对象

wx_pub支付

if(this.paySubChannel === 'wx_pub') {
  params.openId = getOpenId() // 关于openId如何获取本篇不讨论
}

alipay_wap支付

因为ping++会在successUrl后面添加参数?result=success/fail等等,导致我们无法在这里先配置参数:

params.successUrl = `${window.location.origin}/#/payResult?serialNo=${this.payInfo?.serialNo}`

所以采用动态路由的形式去传递支付结果页所需的参数:

if(this.paySubChannel === 'alipay_wap') {
  params.successUrl = `${window.location.origin}/#/payResult/${this.payInfo?.serialNo}/${this.otherProp}`
}

路由配置

{
  path: '/payResult/:serialNo/:otherProp',
  name: 'payResult',
  component: () => import('views/common/payResult/index.vue'),
  meta: {
    title: '缴费结果'
  }
},

然后我们在支付结果页就可以通过this.$route.params获取到serialNo otherProp这两个参数。所以你的业务如果需要带token可以直接加个/:token查看文档# 动态路由获取更多关于动态路由的知识o( ̄▽ ̄)ブ

wx_lite支付

背景:h5嵌在小程序webview里边

h5代码:

// 先引入wx sdk
import wx from 'weixin-js-sdk'

if(this.paySubChannel === 'wx_lite') { // 直接重定向到小程序支付页
  wx.miniProgram.redirectTo({
    url: `/pages/webview/pay?params=${JSON.stringify(params)}`
  })
}

然后所有流程交给小程序自己处理,即:准备后端接口参数=>调起后端接口获取ping++ charge对象 => 拿charge对象调用ping++ sdk => 获取ping++ 支付结果/处理支付结果。

注意:小程序支付params也需要openId,这个可以在小程序里边获取。

与app交互,让app调起支付

这个很简单,就是把参数给到app,让app调起对应微信/支付宝支付即可。

我们页面是有让用户选择微信还是支付宝支付的,所以选定后,把ping ++ charge对象给app

async handleAppPay(params) {
  try {
    let channel
    switch (this.paySubChannel) {
      case 'wx_pub':
        channel = 'wx'
        break;
      case 'alipay_wap':
        channel = 'alipay'
        break;
      default:
        break;
    }
    params.paySubChannel = channel
    
    if(!this.pingPayParams) {
      const { data } = await api.req(JSON.stringify(params), 'payRequest')
      this.pingPayParams = data
    }
    
    // appPay是与app交互的一个协议
    appPay({
      PingParam: JSON.stringify(this.pingPayParams),
    })
    // 注册让app回调的js函数
    methodCalledByNative('handlePayResult', (result) => this.handlePayResult(result))
    this.$on("hook:beforeDestroy", () => (window.handlePayResult = null));
  } catch (error) {
    console.log(error)
  }
},

获取Ping++支付结果/处理支付结果

支付宝网页支付完成会直接走successUrl,上面已经处理了

// app/微信js api/微信小程序支付完会走这里
async handlePayResult(result) {
  console.log('ping++支付结果:', result);
  switch (result) {
    case 'success':
      this.$router.push({
        name: 'payResult',
        params: {
          otherProp: this.otherProp,
          serialNo: this.payInfo.serialNo
        }
      })
      break
    case 'fail':
      this.$router.push({
        name: 'payResult',
        params: { result: 'fail' }
      })
      break
    case 'cancel':
      console.log('取消支付')
      break
    case 'invalid':
      this.$toast.fail(this.paySubChannel === 'wx_pub' ? '用户没有安装微信' : '用户没有安装支付宝')
      break
    default:
      break
  }
},

支付结果页

async created() {
    const { serialNo, otherProp, result  } = this.$route.params
    if(result === 'fail') { // 可以直接展示支付失败
      return
    }
    this.otherProp = otherProp
    this.serialNo = serialNo
    this.queryPayResult()
  },

此文章为记录学习使用。如有谬误,烦请各位大佬指教(鞠躬


ever
323 声望6 粉丝