Bootstrap

uniapp app端跳转微信小程序,调用支付,支付成功后可以返回APP,并携带参数

前言 

最近在开发公司的一个uniapp项目, 兼容APP端和微信小程序端的一个商城小程序;

遇到了一个比较奇葩的需求🤣

APP端下单支付时,选择微信支付时,需要跳转到小程序进行支付

(是不是很奇葩~在微信支付和在小程序支付都是微信支付,但是为什么要再额外跳转到微信小程序支付呢?)

有点脱裤子放屁的意思;但是得做啊😅

需求分析

  • 跳转微信小程序可以使用HTML5的方法实现;可以指定小程序的路径,并且可以携带参数;
  • 那么可以使用条件编译,在app端点击支付时跳转到微信小程序,并携带订单参数;
  • 微信小程序可以在onload生命周期函数中拿到app端传来的参数;
  • 通过订单参数调后端接口,拿到调用 uni.requestPayment 所需的参数即可;
  • 支付成功后,可以通过点击按钮返回APP;

代码实现

App端
  • 先在manifest.json中 “App模块配置” share分享中配置 开放平台的appid 

<script>
export default {
  methods: {
    handlePayment() {
      // #ifdef APP-PLUS
      plus.share.getServices((res) => {
        let sweixin = null
        for (let i = 0; i < res.length; i++) {
          if (res[i].id == 'weixin') {
            sweixin = res[i]
          }
        }
        if (sweixin) {
          const payData = {
            id: 1,
            _from: 'mini',
            //...
          }
          // path : 要跳转的微信小程序的页面路径 可通过 ? 拼接的形式传参
          const path = `/order/order/order?payData=${JSON.stringify(payData)}`
          sweixin.launchMiniProgram(
            {
              id: 'gh_xxxxx', // 原始id:gh_开头 要跳转的微信小程序原始ID(在微信小程序网页获取)
              path,
              type: 0, // 默认为0, 0: 正式版 1:测试版 2:体验版
            },
            (success) => {},
            (err) => {
              console.log(err)
              return uni.showToast({
                title: '请检查手机是否有微信应用~',
                icon: 'none',
              })
            },
          )
        }
      })
      // #endif

      // ...其他代码
    },
  },
}
</script>

plus.share.getServices 方法可以已封装好的分享平台信息

launchMiniProgram 方法需要拿到分享平台的信息才可以调用 

 微信小程序
  • app端跳转到 /order/order/order页面,在onLoad的 options 可以app携带的参数;
  • 拿到参数,调用后端接口,获取 uni.requestPayment 所需的信息即可;
  onLoad(options) {
    if (options.payData) {
      const payData = JSON.parse(options.payData)
      // 拿到订单数据,调用后端接口,换取 requestPayment方法 所需的字段信息
      this.$requsetAll.order.payData(payData).then((res) => {
        uni.requestPayment({
          provider: 'wxpay', //  可通过uni.getProvider获取,这里只用微信支付,所有我就没调用该方法取值
          orderInfo: res.data.res,
          timeStamp: res.data.timeStamp,
          nonceStr: res.data.nonceStr,
          package: res.data.package,
          paySign: res.data.paySign,
          success: (res) => {
            // 支付成功后会执行该回调
          },
          fail: (error) => {
            console.log(error)
            return uni.showToast({
              title: '微信支付失败~',
              icon: 'none',
            })
          },
        })
      })
    }
    // 其他代码...
  }
支付完成返回APP并携带参数
//**小程序中button  的open-type="launchApp"  触发跳转回App**
<button type="primary" open-type="launchApp" :app-parameter="appParameter" binderror="launchAppError">点击返回APP </button>
// 微信小程序返回APP时,APP如何取到微信小程序的参数
// 在微信小程序点击 返回APP 的 按钮时,会返回APP

// order.vue APP端取参数

onShow() {
  // # ifdef APP-PLUS
  const args = plus.runtime.arguments  // 当从第三方进入此页面时,plus.runtime.arguments 会携带参数, 在APP端 路由跳转进入此页面时, 会拿到 空字符串
  if (args !== '') {
    // ... 拿到小程序返回APP的参数 做一些事情...

    // 注意: 当你从微信小程序返回APP携带的参数存在 plus.runtime.arguments 里。但是它是只读的
    // 会出现一个严重的问题, 当你再次进入此页面时, plus.runtime.arguments 里的参数不会清空!! 会一直存在,除非后台关闭APP,重新打开APP
    // 官方也没有明确的解决办法
    // 可以通过以下方法清空
    plus.runtime.arguments = null
    plus.runtime.arguments = ''
  }
  // # endif
}

总结

  • 总的来说,需求有些奇葩;
  • 不过好在实现啦~
;