feat(douyin-mashida): 抖音码速达最小接入后端(消息建单/券码同步/兑换核销/退款作废)

- 签名:出网 md5(secret+Σ(名+值)+secret) 与推送 md5(secret+data+pub_time+topic+secret)
  两套独立实现,含文档 golden 向量单测(与 91 大写 / affiliate_dash HMAC 都不通用)
- 进单:trade_TradePaid 推送 → 验签 → webhook_events 幂等 → order.orderDetail
  → upsertOrderFromSource(provider=douyin_mashida / platform=doudian)
- 精度:19 位订单号超出 JS 安全整数,JSON.parse 会把 p_id 抹成 ...000;
  故解析后从原始 JSON 文本用正则抓回精确数字(单测同时证明"不修会错")
- 券码:迁移 094 redeem_certificates((provider,order_id) 唯一做发券幂等)
  + DYC 券码生成 + coupons.syncV2 同步(子单号优先、父单兜底)
- 兑换:POST /api/v1/redeem/lookup|confirm,按 orderNo+IP 限流;
  核销成功后 order.message 通知买家(best-effort,失败只记错误日志)
- 退款/取消:作废未核销券;券已核销时打 WARN 资损告警(已消费不可回滚)
- 后台:GET/POST /api/v1/admin/platform-config/douyin-mashida,
  secret 出参置空 + 掩码,掩码回写不覆盖原值
- 消息路由挂在全局 body parser 之前(app.ts),验签必须用 body 原始字符串
This commit is contained in:
yml2213
2026-10-09 12:00:50 +08:00
parent 893388b37f
commit 72606796b3
21 changed files with 2806 additions and 0 deletions
@@ -12,4 +12,6 @@ export const APP_CONFIG_KEYS = {
kuaishouIndustrySource: 'kuaishou_industry_source',
affiliateDash: 'affiliate_dash',
pddSource: 'pdd_source',
/** 抖音码速达(抖店中转开放平台)接入配置:uid/secret/baseUrl/certLink 等 */
douyinMashida: 'douyin_mashida',
} as const