diff --git a/docs/抖音-码速达/00-总览.md b/docs/抖音-码速达/00-总览.md index bec522e5..1e830d86 100644 --- a/docs/抖音-码速达/00-总览.md +++ b/docs/抖音-码速达/00-总览.md @@ -81,6 +81,7 @@ | `routes/admin/platform-config/douyin-mashida.ts` | 49 | 后台 GET/POST + 审计 | | `services/admin/platform-config/douyin-mashida-service.ts` | 75 | 配置读写,secret 出参置空 + 掩码,掩码回写不覆盖 | | `db/migrations/094_redeem_certificates.sql` | 57 | `redeem_certificates` 表 | +| `db/migrations/095_redeem_certificates_platform_cert.sql` | 30 | 记录**平台侧实际券码**(平台会改名,核销必须用它) | | `scripts/douyin-mashida-gateway-stub.ts` | 320 | **本地网关桩**:假装码速达,校验签名并回 `code=10000` | | `scripts/douyin-mashida-push.ts` | 300 | **推送模拟器**:造签名消息打本地后端 | | `scripts/douyin-mashida-set-public-url.ts` | 290 | **公网联调切换**:改 `certLink` 为隧道地址 + 打印平台侧配置 + 自检隧道 | @@ -253,6 +254,9 @@ git add apps/backend/src/app.ts \ | 兑换页状态 | ✅ `redeemable`,展示真实商品名与真实支付时间 | | **平台自动推送**(订阅后真单付款) | ✅ 6 秒到达,来源 IP `118.31.56.230`,端到端约 7 秒完成建单+发券+同步 | | `pay_time` 字符串形态 | ⚠️ 实测发现并已修复(见 07 §4.8) | +| **核销(verifyV3)** | ✅ 真单核销成功,平台侧 `status=3 已使用 / verify_num=1` | +| **平台会改写券码** | ⚠️ 3 笔里 2 笔被平台改名 → 已修(核销改用平台侧券码 + 失败自愈,迁移 095) | +| `order.message` 发消息 | ✅ 兑换成功后已调用,无错误日志(成功日志默认被 integration 阈值 warn 挡住) | | `messagetest` 自测入口 | ⚠️ 始终 `20006 data参数内容解析异常`,未探明其 data 要求;不影响真实链路 | ## 十、自检结果(本次) diff --git a/docs/抖音-码速达/07-最小接入实现说明.md b/docs/抖音-码速达/07-最小接入实现说明.md index 168d2831..fb619844 100644 --- a/docs/抖音-码速达/07-最小接入实现说明.md +++ b/docs/抖音-码速达/07-最小接入实现说明.md @@ -167,7 +167,33 @@ applyRawBigIntegerOverrides(parsed, rawText) // p_id / order_id / s_id / s_ids `resolveOrderItemSkuNick`)和 `redeem-service.ts:buildSummary`, **只对 `source === 'douyin_mashida'` 生效**,其它平台展示逻辑不变。 -### 4.11 平台真实推送的形态(实测抓到的原文) +### 4.11 ★ 平台会**改写我们提交的券码**(最坑的一条) + +`coupons.syncV2` 返回 `10000 成功`,**不代表平台沿用了你提交的 `cert_no`**。 +实测 3 笔订单里有 **2 笔**,平台把我们的 `DYC…` 券码换成了它自己生成的券码: + +| 订单 | 我们提交的 cert_no | 平台侧实际 cert_no | +| --- | --- | --- | +| `6930318258716179555` | `DYCM7HXC1TEJGB3VC4A` | 沿用我们的 | +| `6930292726686514275` | `DYCAEPGNV5W4KDW2GJW` | `ExsweiKSgejRcM3Z06`(平台生成) | +| `6930310175251856483` | `DYC05EJH7G66VG0EVFN` | `S683sWRJXaY74DZkrT`(平台生成) | + +**连带后果**:拿自己的券码去 `coupons.verifyV3`,平台报 +`10017 卡券核销失败[isv.business-failed:010021|核销码与订单不匹配]` —— +而且这个错误**要 ~10.5 秒才返回**,越过 10 秒超时后前端只看到 +`douyin_mashida_gateway_timeout`,真实原因完全被掩盖。 + +**处理**(迁移 095 + `certificate-service`): + +1. 同步成功后立即用 `coupons.list`(按 `order_id`)回查平台侧真实券码, + 存进 `platform_cert_no` / `platform_cert_id` / `platform_status`; +2. 核销时 `resolveRedeemVerifyCertNo()`:**平台侧券码优先**,取不到才退回我方券码; +3. 核销失败自愈:回查平台 → 若平台侧已核销则按对账结果标记本地已核销(修状态漂移); + 若是券码被改名则用平台券码**重试一次**; +4. 回查不到券 → 标记 sync 失败并告警(暴露"syncV2 成功但平台无券"); +5. 出网超时默认 10s → **20s**。 + +### 4.12 平台真实推送的形态(实测抓到的原文) 订阅配好后,一笔真实付款的推送**约 6 秒**到达,来源 IP 是平台服务器(`118.31.56.230`), body 原文(注意 `p_id`/`s_ids` 是**裸数字**、`pay_time` 是**秒级**): @@ -181,13 +207,13 @@ body 原文(注意 `p_id`/`s_ids` 是**裸数字**、`pay_time` 是**秒级** - `p_id` 是 19 位裸数字 → 正好验证了 §4.1 的精度修复(落库/回执全程精确); - 端到端耗时:付款 12:55:05 → 推送 12:55:11 → 建单+发券+`syncV2` 完成 12:55:12。 -### 4.12 平台推送是**订阅制**(不配就永远收不到) +### 4.13 平台推送是**订阅制**(不配就永远收不到) 填好 `uid`/`secret` 只代表我们能调平台,平台**不会**自动推消息过来: 必须调「消息设置」`message.config` 配置 `message_url` + `topics` + `status=1`。 而且**不补推**订阅之前的历史订单。详见 [08-公网联调.md](08-公网联调.md) §2。 -### 4.13 退款/取消消息文档没列字段 +### 4.14 退款/取消消息文档没列字段 `refund_*`、`trade_TradeCanceled`、`trade_TradeSuccess` 这几条文档里 `props` 是空的(很可能只是文档缺失)。 代码按「有 `p_id` 就作废券、没有就留痕等人工」处理 —— **不抛错**,避免平台无意义重推。