当前位置:   article > 正文

使用uniapp云开发对接抖音小程序通用交易系统

使用uniapp云开发对接抖音小程序通用交易系统

使用uniapp云开发对接抖音小程序通用交易系统

1、使用tt.requestOrder(options)生成一个抖音的订单
2、使用tt.getOrderPayment(options);调起收银台完成支付
3、服务端接收支付回调完成
注意:开发者工具中可能会有 requestOrder 未定义的报错,直接使用真机调试就好了
注意:使用前记得把抖音的通用交易那些需要开通的都开通了

抖音官方文档

1、tt.requestOrder(options)

这个方法里有需要两个参数,data和byteAuthorization,这两个都是需要服务端去返回的,
data的内容

//data离得内容主要是商品相关的内容
const skuList = [{
        skuId: '你的商品id',
        price: '商品价格',
        quantity: '商品数量',
        title: '商品名称',
        imageList: ['商品图片地址'],//这里需要一个数组
        type: xxx,//商品类型,这是固定的,根据商品的类型直接去官方文档查一下就可以了
        tagGroupId: 'tag_group_xxxxxxxxxxxxx',//这个可以动态获取,也可以直接去官方文档查一下,商品种类只有一种的话,也可以直接写死,这个和上一个参数商品类型是对应的
      }]

      const data = {
        skuList: skuList,
        outOrderNo: 'xxxxxxx',//你自己的订单id
        totalAmount: '订单总金额',
        orderEntrySchema: {
          path: 'xxxxxx',//你的订单详情页面路径,前面不要加'/'
          params: JSON.stringify({
            id: '订单id'
          })//路径后面携带的参数
        }
      }
      //最后拿到一个data对象,转换成json格式的字符串,返回给客户端,这个就是前端需要的data参数
      const dataStr = JSON.stringify(data)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

byteAuthorization的生成
先安装一个openssl,这个安装随便查一下就可以了,不是很复杂
openssl下载
我安装的是3.0的版本,所以命令行和官方文档有点区别,每一个命令需要分开

openssl genrsa -out private_key.pem 2048
openssl rsa -in private_key.pem -pubout -out public_key.pem
openssl pkcs8 -topk8 -inform PEM -in private_key.pem -outform PEM -nocrypt -out rsa_private_key.pem
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
// 注:生成出来的私钥文件为rsa_private_key.pem, 公钥文件为rsa_public_key.pem 
  • 1
  • 2
  • 3
  • 4
  • 5

生成 byteAuthorization

//这两个组件需要安装一下,直接去搜索下载或者npm下载都可以
const crypto = require("crypto");
const forge = require('./node-forge');

// 获取签名
function getByteAuthorization(privateKeyStr, data, appId, nonceStr, timestamp, keyVersion) {
  return new Promise((resolve, reject) => {
    const key = forge.util.decode64(privateKeyStr.replace(/\n/g, ''));
    const privateKey = forge.pki.privateKeyFromAsn1(forge.asn1.fromDer(key));

    // Generate signature
    const targetStr = `POST\n/requestOrder\n${timestamp}\n${nonceStr}\n${data}\n`;
    const md = forge.md.sha256.create();
    md.update(targetStr, 'utf8');
    const digest = md.digest();
    const signBytes = privateKey.sign(md);
    const signature = forge.util.encode64(signBytes);

    // Construct byteAuthorization
    const byteAuthorization =
      `SHA256-RSA2048 appid=${appId},nonce_str=${nonceStr},timestamp=${timestamp},key_version=${keyVersion},signature=${signature}`;
    resolve(byteAuthorization);
  });
}
// 获取随机字符串
function randStr(length) {
  const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  let result = "";
  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * characters.length));
  }
  return result;
}

//示例
//你生成的应用私钥
const privateKeyStr = 'AAoIBAQD......MN00MxNNp/hAg=='
const appId = 'xxxx' // 抖音appid
const nonceStr = randStr(10); //随机字符串
const timestamp = Math.floor(Date.now() / 1000).toString() //请求时间戳
const keyVersion = "1" //公钥版本
// 这个就是返回给客户端的 byteAuthorization 
const byteAuthorization = await getByteAuthorization(privateKeyStr, dataStr, appId, nonceStr, timestamp, keyVersion)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

把生成的data和byteAuthorization 返回给前端

uni.requestOrder({
	data: data,
	byteAuthorization: byteAuthorization,
	success: (res) => {
		//调起收银台,发起支付
		uni.getOrderPayment({
			orderId: res.orderId
		})
	}
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

然后就是支付回调了,先在小程序控制台—开发----解决方案配置通用交易系统支付结果消息能力,配置完成后发布上线,上线后才可以接收到回调,上线之前也可以使用调试测试一下你的接口

支付回调接收到以后需要验证一下签名是否正确,防止收到假通知
官方文档


//验证签名
function verifySign(httpBody, timestamp, nonceStr, sign, publicKey = '') {
    // 如果 httpBody 是数组,将其转换为 JSON 字符串
    if (Array.isArray(httpBody)) {
        httpBody = JSON.stringify(httpBody);
    }

    // 创建要验证的数据字符串
    const data = `${timestamp}\n${nonceStr}\n${httpBody}\n`;

    // 验证签名
    const verifier = crypto.createVerify('sha256');
    verifier.update(data);
    verifier.end();

    const signature = Buffer.from(sign, 'base64');
    const isValid = verifier.verify(publicKey, signature);

    return isValid;
}



//获取headers中的随机字符串、时间戳、签名
const byteTimestamp = httpInfo.headers['byte-timestamp']
        const byteNonceStr = httpInfo.headers['byte-nonce-str']
        const byteSignature = httpInfo.headers['byte-signature']
        //注意这里用的是控制台中的 平台公钥,不是应用公钥和私钥
        const publicKeyStr = `-----BEGIN PUBLIC KEY-----\nANBgkqhk...IDAQAB\n-----END PUBLIC KEY-----`
        //得到了验证的结果
        //httpInfo.body 需要的是json字符串格式
        const verified = verifySign(httpInfo.body, byteTimestamp, byteNonceStr, byteSignature, publicKeyStr)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

验签的时候可以使用官方的验签工具查看参数是否正确
官方验签工具

验签通过后支付流程就完成了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/683346
推荐阅读
相关标签
  

闽ICP备14008679号