微信支付

做微信支付有一段时间了,在做微信支付时遇到很多坑,比如code失效,code已使用、微信授权code获取不到的问题等,今天有时间梳理一下流程,其实下面流程官网都有详解,在这我只是简单梳理一下毕竟是小白,解释一下自己遇到的一些问题,希望大家不要喷我~_~。

1、首先开通微信支付,即申请或复用微信支付商户号 申请完小程序后,登录小程序后台(mp.weixin.qq.com)。点击左侧导航栏的微信支付,在页面中进行开通。(开通申请要求小程序已发布上线)

2、点击开通按钮后,有2种方式可以获取微信支付能力,新申请微信支付商户号或绑定一个已有的微信支付商户号,请根据你的业务需要和具体情况选择,只能二选一。开通指引:kf.qq.com/faq/140225M…

业务流程


商户系统和微信支付系统主要交互:

1、小程序内调用登录接口,获取到用户的openid,api参见小程序登录API

2、商户server调用支付统一下单,api参见统一下单API

3、商户server调用再次签名,api参见再次签名

4、商户server接收支付通知,api参见支付结果通知API

5、商户server查询支付结果,api参见查询订单API

支付流程
后台流程图



前端流程
  • 点击立即支付先创建订单生成订单编号
  • (第二次以后再次使用)先判断本地的OpenId是否有效,有效的话直接请求加签接口,无效则重新登录
  • 通过 wx.login() 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。
  • 拿到code请求后台接口获取OpenId并存到本地
  • 拿到OpenId请求后台加签接口并唤起微信支付

注意: 调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key。

该接口应在服务器端调用。 链接:auth.code2Session

接下来贴代码

// 1、获取code
getlogin() {
  let _this = this;
  wx.login({
    success: function (res) {
      if (res.code) {
        //发起网络请求
        console.log(res.code)
        // 签名校验以及数据加解密涉及用户的会话密钥 session_key。 开发者应该事先通过 wx.login 登录流程获取会话密钥 session_key 并保存在服务器。为了数据不被篡改,开发者不应该把 session_key 传到小程序客户端等服务器外的环境。
        _this.gtOpenid(res.code);
      } else {
        console.log('获取用户登录态失败!' + res.errMsg)
      }
    }
  });
}
复制代码
// 2、获取openid
async gtOpenid(_c){
  let _data = {
    code: _c,
  }
  let obj = await gtopenid(_data);
  if(obj.openid){
    // 3、代金券加签接口
    this.getBuyCashCoupon(obj.openid)
    this.$apply()
  } else {
    if (obj.errcode == 40125) {
      wx.hideToast({
        title: 'appsecret失效',
        icon: 'fail',
        duration: 2000
      })
    }
  }
}
复制代码
// 3、代金券加签 并唤起微信支付
async getBuyCashCoupon(openid) {
      let _this = this;
      let params = {
        memberId: wx.getStorageSync('memberId'),
        mallId: wx.getStorageSync('mall').mallId,
        sellerId: this.detail.sellerId,
        orderType: '3', // 1普通订单 2停车缴费3代金券订单
        paymentMethod: '2', // 1支付宝 2微信
        oppenId: openid,
        serviceVersion: this.$parent.globalData.serviceVersion,
        // couponCode: this.detail.couponCode,
        poolId: this.detail.couponPoolId,
      }
      let res = await buyCashCoupon(params)
      // 返回订单编号以及唤起微信支付需要的参数
      if (res.resultCode == 200){
        let paySignObj = res.resultInfo.paySign
        this.orderFormNumber = res.resultInfo.orderFormNumber
        wx.requestPayment({
          appId: paySignObj.appid,          // 小程序ID
          timeStamp: paySignObj.timestamp,  // 时间戳
          nonceStr: paySignObj.noncestr,    // 随机串不长于32位。
          package: paySignObj.prepayid,     // 统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=wx2017033010242291fcfe0db70013231072
          signType: 'MD5',                  // 签名类型,默认为MD5,支持HMAC-SHA256和MD5。注意此处需与统一下单的签名类型一致
          paySign: paySignObj.sign,         // 签名
          success(res) { 
            // 调用支付成功
            wx.navigateTo({
              url: './paysuccess?type=1&resultMoney='+_this.detail.couponPrice+'&voucher=1'
            })
          },
          fail(res) { 
            // 用户取消支付 | 调用支付失败,其中 detail message 为后台返回的详细失败原因
            _this.isDisabled = false
            _this.getupdateOrderStatus(_this.orderFormNumber)
          }
        })
        this.$apply()
    } else {
        wx.showModal({
          title: '提示',
          content: res.resultMsg
        })
    }
}
复制代码

结尾

目前我是这样做的 有问题 希望大家留言指出, 我会及时回复。谢谢!