// https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/industry/general_trade/create_order/requestOrder#87daf5bf
const createConfig = require('uni-config-center')
const shareConfig = createConfig({ // 获取配置实例
pluginId: 'mymp-pay' // common/uni-config-center下的插件配置目录名
})
const payConfig = shareConfig.requireFile('config.js');
const getNotifyUrl = function (cloudInfo, payid, notify) {
let notifyUrl = '';
if (cloudInfo.provider == 'tencent') {
notifyUrl = `https://${cloudInfo.spaceId}.service.tcloudbase.com/tt-pay/${notify}/${payid}`;
} else if (cloudInfo.provider == 'aliyun') {
notifyUrl = `https://fc-${cloudInfo.spaceId}.next.bspapp.com/tt-pay/${notify}/${payid}`;
}
return notifyUrl;
};
function getSignature(privateKeyStr, method, uri, timestamp, nonce, data) {
const sign = crypto.createSign('SHA256');
const rawStr = method + "\n" +
uri + "\n" +
timestamp + "\n" +
nonce + "\n" +
data + "\n";
sign.update(rawStr);
sign.end();
const signature = sign.sign(privateKeyStr, 'base64');
return signature;
}
function _getByteAuthorization(privateKeyStr, data, appId, nonceStr, timestamp, keyVersion) {
try {
const signature = getSignature(privateKeyStr, "POST", "/requestOrder", timestamp, nonceStr, data);
const byteAuthorization = `SHA256-RSA2048 appid=${appId},nonce_str=${nonceStr},timestamp=${timestamp},key_version=${keyVersion},signature=${signature}`;
return byteAuthorization;
} catch (ex) {
console.error(ex);
return "";
}
}
const getOrderData = function (out_order_no, skuId, title, price, image) {
const cloudInfo = uniCloud.getCloudInfos()[0];
const data = {
skuList: [{
skuId: skuId,
title: title,
price: price,
quantity: 1,
imageList: [image],
type: 401, // 内容消费类商品
tagGroupId: "tag_group_7272625659888041996", // 内容消费: 虚拟商品不支持退款
entrySchema: {
path: 'pages/index/index'
}
}],
outOrderNo: out_order_no,
totalAmount: price,
payExpireSeconds: 0, // 支付超时时间,单位秒,例如 300 表示 300 秒后过期;不传或传 0 会使用默认值 300,不能超过48小时。
payNotifyUrl: getNotifyUrl(cloudInfo, '', 'tt_callback'),
orderEntrySchema: {
path: 'pages/index/index'
}
}
return JSON.stringify(data);
}
/**
* 签名
* @param {string} data
* @returns
*/
const getByteAuthorization = function (data) {
const privateKeyStr = payConfig.toutiao['mp-toutiao'].privateKey; // 从文件中读取私钥
const timestamp = Math.floor(Date.now() / 1000);
const appId = ttConfig.app_id;
const nonceStr = uuidv4();
const keyVersion = "1";
const byteAuthorization = _getByteAuthorization(privateKeyStr, data, appId, nonceStr, timestamp, keyVersion);
return byteAuthorization;
}
// https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/server/signature-algorithm#%E7%AD%BE%E5%90%8D%E9%AA%8C%E8%AF%81
function verify(httpBody, publicKeyPem, signStr, timestamp, nonce) {
const message = `${timestamp}\n${nonce}\n${httpBody}\n`;
// 使用RSA和SHA256进行验签
const verifier = crypto.createVerify('RSA-SHA256');
verifier.update(message);
// 验证签名
return verifier.verify(publicKeyPem, Buffer.from(signStr, 'base64'));
}
const httpInfo = this.getHttpInfo();
// uniCloud.logger.log(`httpInfo:`, httpInfo);
const bodyStr = httpInfo.body;
const nonce = httpInfo.headers['byte-nonce-str'];
const timestamp = httpInfo.headers['byte-timestamp'];
const signature = httpInfo.headers['byte-signature'];
const publicKey = payConfig.toutiao['mp-toutiao'].platformPublicKey;
if (!verify(bodyStr, publicKey, signature, timestamp, nonce)) {
uniCloud.logger.log(`verify error`);
return {
mpserverlessComposedResponse: true,
statusCode: 200,
headers: {
'content-type': 'application/json'
},
body: {
"err_no": 1, //非0
"err_tips": "verify error" //非success
}
};
}
标签: 抖音支付
发表评论 登录: