小程序支付


小程序API不再支持新商户。之前使用的商户,随时可能停用,请尽早做好迁移工作


小程序发起支付的解决方案有两种,仅供测试使用

  • 方案一:使用小程序消息,结合收银台模式,可以解决小程序支付
  • 方案二:使用小程序跳转到 PAYJS 小程序,支付后返回(下文详细介绍的方案)

接入整体流程

一、后端按照下面参数构造订单参数

字段名称 字段类型 必填参数 说明
mchid string(16) Y 商户号
total_fee int(16) Y 金额。单位:分
out_trade_no string(32) Y 用户端自主生成的订单号
body string(32) N 订单标题
attach string(128) N 用户自定义数据,在notify的时候会原样返回
notify_url string(255) N 异步通知地址
nonce string(128) Y 随机字符串
sign string(32) Y 数据签名 详见签名算法

二、小程序携带上述参数跳转到 PAYJS 小程序

三、支付后自动返回,后端判断订单状态

代码参考:https://gist.github.com/payjscn/bab36ca1c7dea241890bca82d7b567a2

// 本代码为演示碎片代码
// 需与文档中小程序章节结合使用 https://help.payjs.cn

// 跳转
// 为小程序的支付按钮绑定事件

bindPay: function() {
    // 待传入的
    wx.request({
        url: '商户侧后端请求支付参数的网址',
        success: response => {
            let extraData = {
              'mchid': response['mchid'], // 商户号
              'total_fee': response['total_fee'],
              'out_trade_no': response['out_trade_no'],
              'body': response['body'],
              'notify_url': response['notify_url'],
              'attach': response['attach'],
              'nonce': response['nonce'],
              'sign': response['sign']
            }

            wx.navigateToMiniProgram({
              appId: 'wx959c8c1fb2d877b5',
              path: 'pages/pay',
              extraData: extraData,
              success: () => {
                console.log('等待返回支付结果')
                // 做已经点击过支付的标记
                this.setData({
                    paying: true
                })
              },
              fail: () => {
                // 小程序跳转失败
                // 做好错误处理
              }
            })

        }
    })
  },

// 支付动作判断
// 在全局的 onShow 内,针对场景值为 1038、来源 appid 为 wx959c8c1fb2d877b5、跳转到的页面 id 为发起支付的页面,则标记为支付成功、记录支付的 payjs_order_id

// app.js
App({
  onShow: function (options) {
    if (options.scene === 1038 && options.referrerInfo && options.referrerInfo.appId === 'wx959c8c1fb2d877b5') { 
      // 还应判断请求路径
      let extraData = options.referrerInfo.extraData
      this.globalData.paySuccess = extraData.success
      this.globalData.resultCode = extraData.resultCode
      this.globalData.msg = extraData.msg
      this.globalData.payjsOrderId = extraData.payjsOrderId
    }
  },
  globalData: {
    resultCode: 'WAITING',
    msg: '等待支付',
    paySuccess: false,
  }
})

// 在本页面的 onShow 内,如果已经点击过支付,则开始判断小程序是否返回成功,继而判断是否支付成功

onShow: function (options) {
    console.log(options)

    if (this.data.paying) { // 标记:已经点击过支付
        // 注意轮询判断或延时判断支付
        // 从跳转后状态取值
        let payjsOrderId = app.globalData.payjsOrderId
        // 注意请求后端判断是否支付成功而非通过前端判断
        wx.request({
            method: 'POST',
            url: '后端检测是否支付成功的 url',
            data: {
                payjsOrderId
            },
            success: response => {
                if (response.data.paySuccess) {
                    // 后端返回支付成功
                    // 执行成功后逻辑
                } else {
                    // 后端返回尚未支付
                    // 提醒用户重新支付或点击「我已支付」发起重检查
                }
            }
        })
    }
  },

// 注意事项

// 页面内 onShow 检查小程序 app.js onShow 时建议使用轮询或延时,因为 app.js 的 onShow 和小程序页面的 onShow 均为异步,所以存在执行页面 onShow 时 app.js 的 onShow 还未执行的可能
// 请勿以小程序跳转结果作为判断订单状态的依据,须后端查询订单状态

接入前准备

1.详细阅读小程序运营规范、小程序支付规范,并遵照其中内容

2.在app.json中将 PAYJS 小程序的 APPID: wx959c8c1fb2d877b5 加入 navigateToMiniProgramAppIdList 配置项

3.在后台设置开通


完整小程序示例代码:https://github.com/ImSingee/payjs_test 感谢 王轩 Bryan 同学

powered by Gitbook最后更新: 2022-05-26