Bootstrap

uniapp前端实现微信支付(小程序、公众号H5、app)

这段时间通过uniapp开发一个三端合一的项目,涉及到不同平台的支付方式,这里为大家简单介绍一下,希望能有所帮助;
阅读: 微信支付文档

一、微信小程序支付

  1. 通过wx.login()获取code、调用后端接口获取openid;
wx.login({
  success (res) {
    if (res.code) {
      //发起网络请求获取openid,一般是访问后端封装好的接口,也可以通过访问微信官方接口获取
      uni.request({
         url: '后端接口地址,获取openid',
         method: 'GET',
         success(res) {
           //获取openid:用户真实唯一id进行保存
           console.log(res.data.openid)
        }
      })
    } else {
      console.log('登录失败!' + res.errMsg)
    }
  }
})
  1. 调用后端接口创建订单,获取orderId;
uni.request({
  url: '后端接口地址,获取订单id',
  method: 'POST',
  data: { 传入接口需要的参数,如商品金额,商品个数等 },
  success(res) {
    console.log(res.data.orderId)
  }
})
  1. 调用后端接口获取支付核心参数,预支付;
uni.request({
  url: '后端接口地址,获取支付核心数据',
  method: 'POST',
  data: { 传入接口需要的参数,如订单ID,openId等 },
  success(res) {
    console.log(res.data)
    //接口会返回以下核心参数
    //timeStamp 时间戳
    //nonceStr  随机字符串
    //package   统一下单接口返回的 prepay_id 参数值
    //signType  签名算法
    //paySign   签名
  }
})
  1. 通过支付核心参数调用wx.requestPayment()发起支付;
  //调用微信官方支付接口弹出付款界面,输入密码扣款
  wx.requestPayment({
     timeStamp,  //时间戳
     nonceStr,   //随机字符串
     package,    //prepay_id
     signType,   //签名算法MD5
     paySign,    //签名
     success (res) {
       if (res.errMsg == "requestPayment:ok"){
          console.log('支付成功', res)
       }else{
          console.log('支付失败')
       }
     },
     fail (res) { 
       console.log('支付失败', res)
     }
  })

二、公众号H5支付

支付方式可以参考两种方式:

  • JSAPI 支付:通过JSAPI下单接口获取到发起支付的必要参数prepay_id,然后使用微信支付提供的前端JS方法调起公众号支付
  1. 在获取订单id、openid后,调用预支付,获取JSAPI核心参数;
uni.request({
  url: '后端接口地址,获取支付核心数据',
  method: 'POST',
  data: { 传入接口需要的参数,如订单ID,openId等 },
  success(res) {
    //调用下方支付方法
    wxpay(res.data)
    console.log(res.data)
    //接口会返回以下核心参数
    //appId     公众号ID
    //timeStamp 时间戳
    //nonceStr  随机字符串
    //package   统一下单接口返回的 prepay_id 参数值
    //signType  微信签名方式RSA
    //paySign   微信签名
    
  }
})
  1. 通过JSAPI核心参数发起支付;
   // 检测支付环境中的 WeixinJSBridge
    function wxpay(data) {
      if (typeof WeixinJSBridge == "undefined") {
        if (document.addEventListener) {
          document.addEventListener('WeixinJSBridgeReady', onBridgeReady(data), false);
        } else if (document.attachEvent) {
          document.attachEvent('WeixinJSBridgeReady', onBridgeReady(data));
          document.attachEvent('onWeixinJSBridgeReady', onBridgeReady(data));
        }
      } else {
        onBridgeReady(data);
      }
    }

    function onBridgeReady(data) {
        WeixinJSBridge.invoke(
          'getBrandWCPayRequest', {
             // 传入第一步后端接口返回的核心参数
            "appId": data.appId, //公众号
            "timeStamp": data.timeStamp, //时间戳
            "nonceStr": data.nonceStr, //随机串
            "package": data.package, //prepay_id
            "signType": data.signType, //微信签名方式RSA
            "paySign": data.paySign //微信签名
          },
          function(res) {
            // 支付成功
            if (res.err_msg == "get_brand_wcpay_request:ok") {
              // 使用以上方式判断前端返回,微信团队郑重提示:
              //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
            }
            // 支付过程中用户取消
            if (res.err_msg == "get_brand_wcpay_request:cancel") {

            }
            // 支付失败
            if (res.err_msg == "get_brand_wcpay_request:fail") {

            }
            /**
            * 其它
            * 1、请检查预支付会话标识prepay_id是否已失效
            * 2、请求的appid与下单接口的appid是否一致
            * */
            if (res.err_msg == "调用支付JSAPI缺少参数:total_fee") {

            }
          });
      }

  • 微信公众号的JSSDK中的wx.chooseWXPay: JS-SDK说明文档;注意:目前官方文档取消了chooseWXPay接口,而是推荐JSAPI支付;
  1. 在项目中需要引入jweixin文件:http://res.wx.qq.com/open/js/jweixin-1.6.0.js
    或者通过npm i jweixin-module使用jWeixin对象;
  2. 通过config接口注入权限验证配置;
//调用后端接口获取配置参数
uni.request({
  url: '后端接口地址,获取验证配置',
  method: 'POST',
  data: { 传入接口需要的参数,如页面路径url },
  success({data}) {
    //注入权限验证配置
    jWeixin.config({
      debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。(测试记得关掉)
      appId: data.appId, // 公众号的唯一标识
      timestamp: data.timestamp, // 生成签名的时间戳
      nonceStr: data.nonceStr, // 生成签名的随机串
      signature: data.signature, // 签名
      jsApiList: ['chooseWXPay'], // JS接口列表
    })
  }
})
  1. 通过ready接口处理成功验证,调用支付;
    jWeixin.ready(function () {
    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
      jWeixin.chooseWXPay({
        timestamp: data.timeStamp,
        package: data.package,
        nonceStr: data.nonceStr,
        signType: data.signType,
        paySign: data.paySign,
        success: function (res: any) {
          if (res.errMsg == "chooseWXPay:ok") {
            console.log('支付成功')
          } else {
           console.log('支付失败')
        },
        fail: function (res: any) {
          console.log('支付失败')
        },
      });
    });

三、app小程序支付

App支付适用于在移动端App中集成微信支付功能的场景。商户App调用微信提供的SDK调用微信支付模块,商户App会跳转到微信中完成支付,支付完后跳回到商户App内,最后展示支付结果。具体操作流程如下(流程与小程序类似):

  1. 登录获取openId后,创建订单获取订单ID;(这里需要注意的是使用uni.login唤起微信登录需要在manifest.json进行相关配置: 链接查看
//登录
uni.login({
	"provider": "weixin",
	success: function(event){
		// 登录成功,获取openid
		const {openid,access_token}= event.authResult
		//获取用户信息
        uni.getUserInfo({
            provider: 'weixin',
            success: function(info) {
                // 获取用户信息成功, 调用后端接口进行完成登录
            }
        })
	},
	fail: function (err) {
        // 登录授权失败
        // err.code是错误码
    }
})

//登录成功后在下单时创建订单
```javascript
uni.request({
  url: '后端接口地址,获取订单id',
  method: 'POST',
  data: { 传入接口需要的参数,如商品金额,商品个数等 },
  success(res) {
    console.log(res.data.orderId)
  }
})
  1. 调用后端接口获取支付核心参数,预支付;
uni.request({
  url: '后端接口地址,获取支付核心数据',
  method: 'POST',
  data: { 传入接口需要的参数,如订单ID},
  success(res) {
    console.log(res.data)
    //接口会返回以下核心参数
    //timeStamp 时间戳
    //nonceStr  随机字符串
    //package   统一下单接口返回的 prepay_id 参数值
    //signType  签名算法
    //paySign   签名

    //通过下方api发起支付
  }
})
  1. 调用uni.requestPayment()发起支付:支付平台功能申请 -> manifest.json 里配置支付参数 -> uni-app 里调用 API 进行支付 官网流程阅读
uni.requestPayment({
    provider: 'wxpay',
    orderInfo: data.orderInfo, //微信、支付宝订单数据 【注意微信的订单信息,键值应该全部是小写,不能采用驼峰命名】
    nonceStr: data.noncestr,
    package: data.package,
    timeStamp: data.timestamp,
    signType: data.signType,
    paySign: data.paySign,
    success: function (res) {
        if (e.errMsg == "requestPayment:ok") {
          console.log('支付成功')
        }else{
          console.log('支付失败')
        }
    },
    fail: function (err) {
        console.log('支付失败:' + JSON.stringify(err));
    }
});

总结

  1. 登录:调用uni.login/wx.login调用微信接口,获取code,调用后端后台获取openid;
  2. 订单:调用后端接口获取订单ID,再调用后端接口传入openid、商品id、商品单价、商品数量等参数获取预支付的重要参数(时间戳timeStamp,随机字符串nonceStr,预支付id package,签名算法signType,签名paySign)
  3. 支付:调用uni/wx.requestPayment微信支付方法,传递5个重要参数,获取支付结果(成功或失败)
  4. H5支付因为无法直接调用微信api,需要通过JSSDK配置后调用对应的接口;

在开发中如果涉及到多端支付,需要通过条件编译处理多端差异,可以参考 官网文档,在实际开发中可以多参考各位大佬的文档找到适合自己项目开发的方法,也欢迎各位大佬讨论、提供建议补充…

;