使用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)

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 

生成 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)

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

uni.requestOrder({
	data: data,
	byteAuthorization: byteAuthorization,
	success: (res) => {
		//调起收银台,发起支付
		uni.getOrderPayment({
			orderId: res.orderId
		})
	}
})

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

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


//验证签名
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)

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值