Webhook 增加订单号查询
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import { parseJsonObject } from '../../utils/json.js'
|
||||
|
||||
export function extractAgisoTradePayload(body) {
|
||||
const normalizedBody = normalizeRecord(body)
|
||||
const rawJson = String(normalizedBody.json || normalizedBody.JSON || '').trim()
|
||||
|
||||
if (rawJson) {
|
||||
return normalizeRecord(parseJsonObject(rawJson, { preserveLargeIntegers: true }))
|
||||
}
|
||||
|
||||
return normalizedBody
|
||||
}
|
||||
|
||||
export function resolveAgisoTradePlatformOrderId(payload) {
|
||||
const normalizedPayload = normalizeRecord(payload)
|
||||
const firstItem = extractAgisoTradeOrderItemSources(normalizedPayload)[0] || {}
|
||||
|
||||
return pickFirstNonEmpty([
|
||||
normalizedPayload.biz_order_id,
|
||||
normalizedPayload.Tid,
|
||||
normalizedPayload.tid,
|
||||
normalizedPayload.Oid,
|
||||
normalizedPayload.oid,
|
||||
normalizedPayload.order_id,
|
||||
normalizedPayload.orderId,
|
||||
firstItem.Oid,
|
||||
firstItem.oid,
|
||||
])
|
||||
}
|
||||
|
||||
export function extractAgisoTradeOrderItemSources(payload) {
|
||||
const normalizedPayload = normalizeRecord(payload)
|
||||
const candidates = [
|
||||
normalizedPayload.items,
|
||||
normalizedPayload.Items,
|
||||
normalizedPayload.orders,
|
||||
normalizedPayload.Orders,
|
||||
normalizedPayload.order_list,
|
||||
normalizedPayload.OrderList,
|
||||
]
|
||||
|
||||
for (const current of candidates) {
|
||||
if (Array.isArray(current) && current.length > 0) {
|
||||
return current.map((item) => normalizeRecord(item)).filter((item) => Object.keys(item).length > 0)
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(normalizedPayload).length > 0) {
|
||||
return [normalizedPayload]
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
function normalizeRecord(value) {
|
||||
return value && typeof value === 'object' && !Array.isArray(value) ? value : {}
|
||||
}
|
||||
|
||||
function pickFirstNonEmpty(values) {
|
||||
for (const value of values) {
|
||||
if (typeof value === 'string' && value.trim()) {
|
||||
return value.trim()
|
||||
}
|
||||
|
||||
if (typeof value === 'number' && Number.isFinite(value)) {
|
||||
return String(value)
|
||||
}
|
||||
}
|
||||
|
||||
return ''
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import { extractAgisoTradePayload, resolveAgisoTradePlatformOrderId } from './agiso-trade-parsing.js'
|
||||
|
||||
test('extractAgisoTradePayload preserves large integer order ids from raw json', () => {
|
||||
const payload = extractAgisoTradePayload({
|
||||
json: '{"biz_order_id":4502259793206016214,"item_id":978102431355,"order_status":4}',
|
||||
})
|
||||
|
||||
assert.equal(payload.biz_order_id, '4502259793206016214')
|
||||
assert.equal(typeof payload.biz_order_id, 'string')
|
||||
})
|
||||
|
||||
test('resolveAgisoTradePlatformOrderId keeps exact webhook order id', () => {
|
||||
const payload = extractAgisoTradePayload({
|
||||
json: '{"biz_order_id":4502259793206016214,"item_id":978102431355,"order_status":4}',
|
||||
})
|
||||
|
||||
assert.equal(resolveAgisoTradePlatformOrderId(payload), '4502259793206016214')
|
||||
})
|
||||
|
||||
test('resolveAgisoTradePlatformOrderId falls back to tid when biz_order_id is absent', () => {
|
||||
assert.equal(
|
||||
resolveAgisoTradePlatformOrderId({
|
||||
tid: '4502251008019011224',
|
||||
orders: [{ oid: '4502251008019011888' }],
|
||||
}),
|
||||
'4502251008019011224',
|
||||
)
|
||||
})
|
||||
@@ -3,6 +3,10 @@ import crypto from 'node:crypto'
|
||||
import { runtimeConfig } from '../../config/runtime.js'
|
||||
import { createWebhookEvent, updateWebhookEvent } from '../../repositories/webhook-event-repo.js'
|
||||
import { enrichAgisoXianyuTradeOrder } from '../platforms/agiso/xianyu/order-detail-service.js'
|
||||
import {
|
||||
extractAgisoTradePayload,
|
||||
resolveAgisoTradePlatformOrderId,
|
||||
} from './agiso-trade-parsing.js'
|
||||
import { upsertOrderFromWebhook } from './order-service.js'
|
||||
import { hasConfiguredOrderItems } from './product-match-service.js'
|
||||
import { createHttpError } from '../../utils/http.js'
|
||||
@@ -305,7 +309,7 @@ function parseAgisoTradeRequest(requestLike) {
|
||||
const query = normalizeRecord(requestLike.query)
|
||||
const body = normalizeRecord(requestLike.body)
|
||||
const rawJson = String(body.json || '').trim()
|
||||
const payload = rawJson ? parsePayloadJson(rawJson) : body
|
||||
const payload = rawJson ? parsePayloadJson(rawJson) : extractAgisoTradePayload(body)
|
||||
const timestamp = String(query.timestamp || '').trim()
|
||||
const sign = String(query.sign || '').trim().toLowerCase()
|
||||
const provider = 'agiso'
|
||||
@@ -323,19 +327,7 @@ function parseAgisoTradeRequest(requestLike) {
|
||||
const shop = resolveShop(payload)
|
||||
const eventType = resolveEventType(query.aopic, payload)
|
||||
const signatureValid = verifyAgisoSignature({ rawJson, timestamp, sign })
|
||||
const itemSources = extractOrderItemSources(payload)
|
||||
const firstItem = itemSources[0] || {}
|
||||
const platformOrderId = pickFirstNonEmpty([
|
||||
payload.biz_order_id,
|
||||
payload.Tid,
|
||||
payload.tid,
|
||||
payload.Oid,
|
||||
payload.oid,
|
||||
payload.order_id,
|
||||
payload.orderId,
|
||||
firstItem.Oid,
|
||||
firstItem.oid,
|
||||
])
|
||||
const platformOrderId = resolveAgisoTradePlatformOrderId(payload)
|
||||
|
||||
return {
|
||||
provider,
|
||||
@@ -663,25 +655,6 @@ function normalizeOrderItems(payload) {
|
||||
})
|
||||
}
|
||||
|
||||
function extractOrderItemSources(payload) {
|
||||
const candidates = [
|
||||
payload.items,
|
||||
payload.Items,
|
||||
payload.orders,
|
||||
payload.Orders,
|
||||
payload.order_list,
|
||||
payload.OrderList,
|
||||
]
|
||||
|
||||
for (const current of candidates) {
|
||||
if (Array.isArray(current) && current.length > 0) {
|
||||
return current
|
||||
}
|
||||
}
|
||||
|
||||
return [payload]
|
||||
}
|
||||
|
||||
function resolveBusinessPlatform(rawPlatform) {
|
||||
const normalized = normalizePlatformKey(rawPlatform)
|
||||
|
||||
@@ -910,6 +883,10 @@ function isPlainObject(value) {
|
||||
}
|
||||
|
||||
function safeParseJson(rawValue) {
|
||||
if (rawValue && typeof rawValue === 'object' && !Array.isArray(rawValue)) {
|
||||
return rawValue
|
||||
}
|
||||
|
||||
const normalized = String(rawValue || '').trim()
|
||||
|
||||
if (!normalized) {
|
||||
|
||||
Reference in New Issue
Block a user