fix(douyin-mashida): 平台会改写券码 —— 核销改用平台侧券码 + 失败自愈
真实联调踩到的坑(已用真单复现并定位): `coupons.syncV2` 返回 `10000 成功` **并不代表平台沿用了我们提交的 cert_no**。 实测 3 笔订单里有 2 笔,平台把我们的 DYC 券码换成了它自己生成的券码。 我们却一直拿**自己的**券码去 `coupons.verifyV3`,平台回 `10017 卡券核销失败[isv.business-failed:010021|核销码与订单不匹配]`; 更坑的是这个错误平台要 **~10.5 秒**才返回,正好越过当时的 10 秒超时, 前端只看到 `douyin_mashida_gateway_timeout`,完全看不出真实原因。 修复: - 新增 `coupons.list` 出网封装;同步成功后按 order_id 回查平台侧 `cert_no`/`cert_id` 并落库(迁移 095 新增 platform_cert_no / platform_cert_id / platform_status / platform_synced_at) - 核销时用 `resolveRedeemVerifyCertNo()`:**平台侧券码优先**,取不到才退回我方券码 - 核销失败后自愈 `tryRecoverVerify()`: ① 回查平台,若平台侧已核销 → 按对账结果标记本地已核销(修复"平台已核销、我们报失败"的漂移) ② 若是券码被平台改过 → 用平台券码**重试一次** - 回查不到该订单的券 → 标记 sync 失败并告警(暴露"syncV2 成功但平台无券"的幽灵券) - 默认出网超时 10s → 20s(平台业务错误要 ~10.5s 才返回,10s 会把业务错误伪装成超时) 实测验证:对一笔「平台侧已核销、本地仍是 synced」的订单调确认兑换, 10.7s 后返回 `status=verified`,platform_cert_no 成功回填为平台券码、 platform_status=3,并打出「对账发现平台侧已核销,按平台状态标记本地已核销」告警。
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
-- 095_redeem_certificates_platform_cert.sql —— 记录**平台侧实际券码**。
|
||||
--
|
||||
-- 背景(真实联调发现):`coupons.syncV2` **不保证平台沿用我们提交的 `cert_no`**。
|
||||
-- 实测 3 笔订单里有 2 笔,平台把我们的券码(DYC…)换成了它自己生成的券码;
|
||||
-- 而我们一直拿**自己的**券码去调 `coupons.verifyV3`,平台返回
|
||||
-- `10017 卡券核销失败[isv.business-failed:010021|核销码与订单不匹配]`。
|
||||
-- 更坑的是:这个错误平台要 **~10.5 秒**才返回,正好越过我们当时 10 秒的出网超时,
|
||||
-- 于是前端只看到 `douyin_mashida_gateway_timeout`,完全看不出真实原因。
|
||||
--
|
||||
-- 处理:`syncV2` 成功后立即用 `coupons.list`(按 order_id 查)取回平台侧的
|
||||
-- `cert_no` / `cert_id` 存到本表,核销时**优先用平台侧券码**。
|
||||
--
|
||||
-- 量级预期:同 094,一单一券;这两列只读不索引(检索都走 cert_no / order_id)。
|
||||
|
||||
ALTER TABLE redeem_certificates
|
||||
-- 平台侧实际券码;为空表示"尚未从平台取回",此时退回用我方 cert_no
|
||||
ADD COLUMN IF NOT EXISTS platform_cert_no TEXT NOT NULL DEFAULT '',
|
||||
-- 平台侧卡券ID(coupons.list 的 cert_id),用于排查对不上号的情况
|
||||
ADD COLUMN IF NOT EXISTS platform_cert_id TEXT NOT NULL DEFAULT '',
|
||||
-- 平台侧状态快照(coupons.list 的 status:1 未激活 / 2 未使用 / 3 已使用 / 4 已废弃 / 5 已过期 / 6 已完成)
|
||||
ADD COLUMN IF NOT EXISTS platform_status INTEGER,
|
||||
-- 最近一次成功从平台取回券码的时间
|
||||
ADD COLUMN IF NOT EXISTS platform_synced_at TIMESTAMPTZ;
|
||||
|
||||
COMMENT ON COLUMN redeem_certificates.platform_cert_no IS
|
||||
'平台侧实际券码(syncV2 后由 coupons.list 取回;平台可能不用我们提交的 cert_no),核销优先用它';
|
||||
COMMENT ON COLUMN redeem_certificates.platform_cert_id IS '平台侧卡券ID(coupons.list 的 cert_id),排查用';
|
||||
COMMENT ON COLUMN redeem_certificates.platform_status IS '平台侧券状态快照:1未激活/2未使用/3已使用/4已废弃/5已过期/6已完成';
|
||||
Reference in New Issue
Block a user