// 虚拟支付签名与下单参数(纯函数,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 }