48 lines
1.9 KiB
JavaScript
48 lines
1.9 KiB
JavaScript
// 虚拟支付签名与下单参数(纯函数,index.js 与 test.js 共用)
|
||
const crypto = require('crypto')
|
||
|
||
// 道具价目表(单位:分),必须与 MP 后台【虚拟支付 → 道具管理】的价格一致
|
||
const GOODS = {
|
||
// 0.1 元的测试道具,只给管理员用
|
||
90001: { name: '补单专用', price: 10, adminOnly: true, note: '0.1 元测试用,iOS 最低 1 元买不了' },
|
||
10001: { name: '基础激活码', price: 3900 },
|
||
10002: { name: '高级激活码', price: 6900 },
|
||
10000: { name: '永久激活码', price: 9900 },
|
||
}
|
||
|
||
function hmacSha256(key, message) {
|
||
return crypto.createHmac('sha256', key).update(message, 'utf8').digest('hex')
|
||
}
|
||
|
||
// outTradeNo:8-32 位,仅数字/大小写字母/_-|*@,不能以下划线开头,每单都要换新号
|
||
function newOutTradeNo(now) {
|
||
return 'T' + (now || Date.now()) + Math.random().toString(36).slice(2, 8).toUpperCase()
|
||
}
|
||
|
||
// 返回的字符串要原样传给 wx.requestVirtualPayment,签名与传参必须是同一串原文
|
||
function buildSignData(params) {
|
||
return JSON.stringify({
|
||
offerId: params.offerId,
|
||
buyQuantity: params.buyQuantity || 1,
|
||
env: params.env === undefined ? 0 : params.env, // 0 现网,1 沙箱(沙箱还要换沙箱 AppKey)
|
||
currencyType: 'CNY',
|
||
productId: String(params.productId),
|
||
goodsPrice: params.price, // 单位分,不要换算成元
|
||
outTradeNo: params.outTradeNo,
|
||
attach: params.attach,
|
||
})
|
||
}
|
||
|
||
// paySig = HMAC-SHA256(AppKey, uri + '&' + body)
|
||
// C 端下单 uri 固定为 requestVirtualPayment;B 端接口用实际路径,如 /xpay/query_order
|
||
function paySig(appKey, uri, body) {
|
||
return hmacSha256(appKey, uri + '&' + body)
|
||
}
|
||
|
||
// 用户态签名 = HMAC-SHA256(sessionKey, signData)
|
||
function userSignature(sessionKey, signData) {
|
||
return hmacSha256(sessionKey, signData)
|
||
}
|
||
|
||
module.exports = { GOODS, hmacSha256, newOutTradeNo, buildSignData, paySig, userSignature }
|