微信、抖音、快手支付API

662 阅读7分钟

微信

公众号JS-SDK接入:

微信jsSDK:developers.weixin.qq.com/doc/offiacc…

一:绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
备注:登录后可在“开发者中心”查看对应的接口权限。

步骤二:引入JS文件
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js
如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)。
备注:支持使用 AMD/CMD 标准模块加载方法加载
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js" type="text/javascript" charset="utf-8"></script>

步骤三:通过config接口注入权限验证配置
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。
wx.config({
  debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  appId: '', // 必填,公众号的唯一标识
  timestamp: , // 必填,生成签名的时间戳
  nonceStr: '', // 必填,生成签名的随机串
  signature: '',// 必填,签名
  jsApiList: [] // 必填,需要使用的JS接口列表
});

步骤四:通过ready接口处理成功验证
wx.ready(function(){
  // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});

步骤五:通过error接口处理失败验证
wx.error(function(res){
  // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开configdebug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});


发起一个微信支付请求
请参考微信支付文档,JSAPI调起支付API:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_4.shtml
备注:
微信支付V2的开发文档:https://pay.weixin.qq.com/wiki/doc/api/index.html
微信支付V3的开发文档:https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml

快速输入

公众号支付WeixinJSBridge

image.png

    ajax({
      url: "下单接口",
      data: {},
      success: function(res){
        // 下单成功
        wechatPay(res.data)
      }
    })
    
    /**
     * 微信公众号支付
     * @param json 微信支付相关数据
     */
    function wechatPay(json) {
        if (typeof WeixinJSBridge == "undefined") {
            if (document.addEventListener) {
                document.addEventListener('WeixinJSBridgeReady', function () {
                    onBridgeReady(json);
                }, false);
            } else if (document.attachEvent) {
                document.attachEvent('WeixinJSBridgeReady', function () {
                    onBridgeReady(json);
                });
                document.attachEvent('onWeixinJSBridgeReady', function () {
                    onBridgeReady(json);
                });
            }
        } else {
            onBridgeReady(json);
        }
    }

    /**
     * 微信环境内唤起充值窗口
     * @param json 
     * json格式:
       {
          "appId": "wx2420ec43b",     // 公众号ID,由商户传入     
          "timeStamp": "1395712654",     // 时间戳,自1970年以来的秒数     
          "nonceStr": "e61463f8efa94090b1f366cccfbbb444",      // 随机串     
          "package": "prepay_id=up_wx212018557123400",
          "signType": "RSA",     // 微信签名方式:     
          "paySign": "oR9d8PuCGDmLhLw4jq/xDg==" // 微信签名 
       }
    */
    function onBridgeReady(json) {
        WeixinJSBridge.invoke(
            'getBrandWCPayRequest', json,
            function (res) {
                switch (res.err_msg) {
                    case 'get_brand_wcpay_request:ok': //成功
                          console.log('充值成功');
                        break;
                    case 'get_brand_wcpay_request:cancel': //取消
                          console.log('您已取消充值');
                        break;
                    case 'get_brand_wcpay_request:fail': //失败
                        console.log('充值失败,请尝试重新充值或试试其他充值方式');
                        break;
                    case 'stopMonitoringBeacons:ok': //成功
                          console.log('充值成功');
                        break;
                    default:
                        if (typeof res.err_msg == 'undefined' && res.errMsg == 'chooseWXPay:fail, the permission value is offline verifying') {
                            console.log('充值失败,原因:模拟器无法充值');
                        } else {
                            console.log('异常错误,请刷新页面重试');
                        }
                        break;
                }
            }
        );
    }

微信小程序支付

image.png

    // 下单接口
    ajaxPay(){
      request({
        url: 'recharge/pay',
        header: app.globalData.header,
        data: {
            goods_id: goodsId,
            scene
        }
      }).then(res=>{
        this.wxPay(res)
      })
    }
    // 微信支付api
    wxPay(data){}
      wx.requestPayment({
          'timeStamp': data.timeStamp, // 时间戳
          'nonceStr': data.nonceStr, // 随机字符串
          'package': data.package, // 统一下单返回的prepay_id参数值,prepay_id=***
          'signType': data.signType, // 签名算法
          'paySign': data.paySign, // 签名
          'success': function (res) {
              // 充值成功
          },
          'fail': function (err) {
              if (err.errMsg == 'requestPayment:fail cancel') {
                  // 取消充值
              } else {
                  let iosErrMsg = 'jsapi has no permission';
                  let AndroidErrMsg = 'access denied';
                  let iosBan = err.errMsg.indexOf(iosErrMsg) !=-1;
                  let AndroidBan = err.errMsg.indexOf(AndroidErrMsg) !=-1;
                  if(iosBan || AndroidBan){
                      // 支付能力被平台封禁
                  }
              }
          },
      })
    }

微信小程序自动续费

续费签约页面返回小程序时,可在app.js的onshow中接收到相关参数[referrerInfo——object]

    wx.navigateToMiniProgram({ // 跳转微信签约续费小程序
      appId: "wxbd687630cd02ce1d", // 固定值
      path: "pages/index/index", // 固定值
      extraData: {
          'timeStamp': data.timeStamp, // 时间戳
          'nonceStr': data.nonceStr, // 随机字符串
          'package': data.package, // 统一下单返回的prepay_id参数值,prepay_id=***
          'signType': data.signType, // 签名算法
          'paySign': data.paySign, // 签名
      },
      envVersion: 'release', // develop-开发版,trial-体验版,release-正式版
      success(res) {
        // 进入续费签约页面成功
      }, 
      fail(err){
        console.log(err, "失败&&&&&&&&&&&&&&&&&&&&&&&&")
      }
    })

app.js

App({
    onShow(info) {
        if(info.scene === 1038 && info.referrerInfo.appId == 'wxbd687630cd02ce1d'){
            /**
             * 场景值scene固定1038,referrerInfo.appId固定值'wxbd687630cd02ce1d'时,为续费页面返回
             * info.referrerInfo.extraData.return_code SUCCESS-签约成功,FAILED-未签约
             * 从续费页面跳转回小程序,此处做一些回调处理
             */ 
        }
    }
})

抖音

自动续费:
tt.createSignOrder({ // 生成相关签约单
    success: ()=>{
        tt.sign({}) // 拉起签约页面
    }
})

正常支付:
tt.requestOrder({ // 生成订单
    success: ()=>{
        tt.getOrderPayment({}) // 拉起收银台
    }

})

抖音中不支持IOS虚拟支付,但是支持钻石和IM支付

IOS配置钻石支付时,requestOrderAPI新增data.currency字段,iOS必须指定currency=DIAMOND(安卓可不传此字段)

钻石支付文档:developer.open-douyin.com/docs/resour…

IM支付 文档:

1.在小程序开发者平台开通抖音IM客服能力:developer.open-douyin.com/docs/resour…

2.接入H5支付能力:

developer.open-douyin.com/docs/resour…

3.客服私信能力能力配置:developer.open-douyin.com/docs/resour…

developer.open-douyin.com/docs/resour…

4.接入抖音IM客服且传order相关参数信息:developer.open-douyin.com/docs/resour…

下单

    // 下单接口
    rechargeApi(){
      request({
        url: 'recharge/pay',
        header: header,
        data: {
            // 下单参数
        }
      }).then(res=>{
        // 自动续费
        autoPay(res.data)
        // 正常充值
        defaultPay(res.data)
      })
    }

自动续费


    // 自动续费
    function autoPay(data){
      tt.createSignOrder({ // 生成相关签约单,用于后续唤起签约页面
        businessType: 2, // 2 - 周期代扣
        data: {
          outAuthOrderNo: "开发者侧签约单的单号",
          serviceId: "签约模板ID",
          openId: "用户 openId",
          expireSeconds: "签约或签约支付超时时间,不传默认5分钟,最少30秒,不超48小时",
          notifyUrl: "签约结果回调地址,https开头",
          authPayOrder: {}, // 扣款信息,传入则会走签约支付流程,否则走纯签约流程
          signWay: "签约渠道:2 - 支付宝, 3 - 抖音支付"
        },
        byteAuthorization: "签名信息,由开发者服务端返回",
        success: function (data){
          console.log("createSignOrder-_成功:", data)
          tt.sign({ // 唤起签约页面,用户签约授权后返回调用结果。
            businessType: 2,// 预授权模式,枚举值 1 - 信用免押,2 - 周期代扣
            orderId: "订单 id",
            success: (data)=>{
              console.log("sign-_成功:", data)
            },
            fail: (e)=>{
              console.log("sign-_失败:", e)
            }
          })
        },
        fail: (e)=>{
          console.log("createSignOrder-_失败:", e)
        }
      })
    }


    // 轮询订单查询,5次调用
    function orderInquiry(order){
      ajax()
    }

正常支付

   // 正常充值
    function defaultPay(data){
      tt.requestOrder({ // 生成订单,返回订单号和订单信息
          data: {
            skuList: [],// 下单商品信息
            outOrderNo: "外部订单号",
            totalAmount: "订单总金额",
            payExpireSeconds: "支付超时时间,单位秒,默认值300,不能超过48小时",
            orderEntrySchema: "订单详情页",
            // currency: "钻石支付:iOS必须指定currency=DIAMOND(安卓可不传此字段)"
          },
          byteAuthorization:"由开发者服务端返回",
          success (data) {
            if (isIos) { // ios
              tt.getOrderPayment({ // 拉起用户支付收银台
                orderId: data.orderId,
                imId: imId || '', // IM支付ID,仅在IOS支付时有
                success () {
                  //成功进入IM支付页面,但不知支付结果
                },
                fail (e) {
                  console.log('tt.getOrderPayment fail', e)
                }
              })
            } else {  // 安卓
              tt.getOrderPayment({
                orderId: "交易订单号",
                success () {
                  // 支付成功,走订单查询
                  orderInquiry(res.orderNo)
                },
                fail (e) {
                  if(e.errMsg == 'getOrderPayment:fail payment is cancelled'){
                    // 取消支付
                  } 
                }
              })
            }
          },
          fail (e) {
            console.log('tt.getOrderPayment fail', e)
          }
        })
    }

    // 轮询订单查询,5次调用
    function orderInquiry(order){
      ajax()
    }

快手支付

ks.pay(options)

    // 下单接口
    rechargeApi(){
      request({
        url: 'recharge/pay',
        header: header,
        data: {
            // 下单参数
        }
      }).then(res=>{
        requestPaymentFn(data)
      })
    }

    function requestPaymentFn(data, callback) {
      let payOptions = {
        serviceId: '1', // 服务类型 id(固定值为 '1')
        // payType: "IAPPurchase", // 支付类型(仅IAP(苹果支付)场景下传递)
        orderInfo: { // 订单数据
          order_no: "订单号",
          order_info_token: "订单 token"
        },
        'success': function(res){
          console.log(res, '下单成功');
          orderInquiry(data.orderNo, callback) // 查单 
        },
        'fail': function(err){
          console.log(err, '下单失败');
        }
      }
      //12.0.20及以上苹果支付
      if(isIos){
        try {
          let systemInfo = ks.getSystemInfoSync()
          // systemInfo.version
          if("版本号" >= '12.0.20'){
            Object.assign(payOptions,{payType:'IAPPurchase'}) // 支付类型(仅IAP(苹果支付)场景下传递)
          }
        } catch (error) {
          console.log('error',error)
        }
      }
      ks.pay(payOptions)
    }

    // 轮询订单查询,5次调用
    function orderInquiry(order){
      ajax()
    }