签名成功

This commit is contained in:
yml2213
2026-05-13 19:16:19 +08:00
parent b120924263
commit c2fd9078b9
11 changed files with 57 additions and 39 deletions
@@ -24,7 +24,7 @@ export async function createOpen91Order(payload = {}, { requestId = '' } = {}) {
assertOpen91CreatePayload(normalized, config)
assertOpen91Timestamp(normalized.timestamp, config.timestampToleranceSeconds)
assertOpen91Signature(normalized, config)
assertOpen91Signature(payload, config)
const now = nowIso()
const items = [
@@ -26,7 +26,7 @@ export async function queryOpen91Order(payload = {}, { requestId = '' } = {}) {
assertOpen91QueryPayload(normalized, config)
assertOpen91Timestamp(normalized.timestamp, config.timestampToleranceSeconds)
assertOpen91Signature(normalized, config)
assertOpen91Signature(payload, config)
const order = await findOrderByPlatformOrderId({
provider: OPEN_91_PROVIDER,
+8 -13
View File
@@ -28,13 +28,6 @@ export function getOpen91Config() {
export function assertOpen91Config() {
const config = getOpen91Config()
if (!config.userId) {
throw createHttpError('91卡券 userId 未配置', {
statusCode: 500,
errorCode: 'open91_missing_user_id',
})
}
if (!config.secret) {
throw createHttpError('91卡券 secret 未配置', {
statusCode: 500,
@@ -154,13 +147,15 @@ export function assertOpen91Timestamp(timestamp, toleranceSeconds = assertOpen91
}
}
export function buildOpen91SignSource(params = {}, { userId, secret } = assertOpen91Config()) {
const entries = Object.entries({
...params,
userId: normalizeOpen91String(userId),
})
export function buildOpen91SignSource(params = {}, { secret } = assertOpen91Config()) {
const entries = Object.entries(params)
.filter(([key]) => key !== 'sign')
.sort(([left], [right]) => left.localeCompare(right))
.sort(([left], [right]) => {
if (left === right) {
return 0
}
return left < right ? -1 : 1
})
const queryString = entries
.map(([key, value]) => `${key}=${stringifyOpen91SignValue(value)}`)
@@ -10,7 +10,7 @@ import {
verifyOpen91Signature,
} from './shared.js'
test('signOpen91Payload matches documented md5 signing rule', () => {
test('signOpen91Payload signs only request body fields', () => {
const config = {
userId: '1001',
secret: 'rste57w8rsubsnxsb384ur3u9kn5fzhr',
@@ -28,7 +28,7 @@ test('signOpen91Payload matches documented md5 signing rule', () => {
const source = buildOpen91SignSource(payload, config)
assert.equal(
source,
'rste57w8rsubsnxsb384ur3u9kn5fzhrbuyNum=1&callbackUrl=https://cb.example.com/notify/91/order&maxAmount=0.0000&orderNo=P91KS202605040001&productNo=KS-CLOUD-SKU-001&timestamp=1777867200&userId=1001&version=1.0rste57w8rsubsnxsb384ur3u9kn5fzhr',
'rste57w8rsubsnxsb384ur3u9kn5fzhrbuyNum=1&callbackUrl=https://cb.example.com/notify/91/order&maxAmount=0.0000&orderNo=P91KS202605040001&productNo=KS-CLOUD-SKU-001&timestamp=1777867200&version=1.0rste57w8rsubsnxsb384ur3u9kn5fzhr',
)
const sign = signOpen91Payload(payload, config)
@@ -36,6 +36,26 @@ test('signOpen91Payload matches documented md5 signing rule', () => {
assert.equal(verifyOpen91Signature({ ...payload, sign }, config), true)
})
test('signOpen91Payload does not add missing optional fields or configured userId', () => {
const config = {
userId: '1001',
secret: 'rste57w8rsubsnxsb384ur3u9kn5fzhr',
}
const payload = {
orderNo: '2613300083829561',
productNo: '183999074510936',
buyNum: 1,
maxAmount: '0.01',
timestamp: 1778670308,
version: '1.0',
}
assert.equal(
buildOpen91SignSource(payload, config),
'rste57w8rsubsnxsb384ur3u9kn5fzhrbuyNum=1&maxAmount=0.01&orderNo=2613300083829561&productNo=183999074510936&timestamp=1778670308&version=1.0rste57w8rsubsnxsb384ur3u9kn5fzhr',
)
})
test('encryptOpen91Cards matches documented AES ECB base64 sample', () => {
const cards = [
{