使用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)
验签的时候可以使用官方的验签工具查看参数是否正确
官方验签工具
验签通过后支付流程就完成了