fix(refund): pay_id 严格正则 + OCR 金额降级为参考
动机
生产上发现三类误拒,都是 OCR 金额/pay_id 不可靠导致:
- OCR 把 9.90 看成 7.70 → 老逻辑 fee_mismatch 误拒
- 反光/截断读不出金额 → 老逻辑金额为 0 被拒
-
OCR 截断 pay_id(如
CC12T2026041711344278001少一位)→ 老逻辑静默丢弃无告警
改动
app/refund/ocr.py
- prompt 加强 pay_id 识别规则:精确 25 位,多/少一位/任何一位数字模糊一律返 null
- 金额允许 null(反光/截断常见)
app/refund/service.py
- 新增
PAY_ID_REGEX = ^CC12T[0-9]{20}$预校验 - 金额上限改用 CMS pay_fee 判定(不再看 OCR 金额)
- 删除 fee_mismatch 分支,OCR 金额仅 log 参考
- 回复消息使用 CMS 金额
app/refund/notifier.py
- 新增
suspicious_pay_id()告警:OCR 识别到 pay_id 但正则不过 → 飞书卡片提醒人工看原图 - 补齐之前"正则挡下但无人知道"的盲区
测试(tests/refund/test_service.py)
- 删除
test_fee_mismatch -
test_over_limit改用 CMS 场景 - 新增 4 个 case:
- OCR 金额缺失仍按 CMS 金额退款
- OCR 金额错识 (770 vs CMS 990) 仍按 CMS 退款
- pay_id 短截 (
CC12T123) → 飞书告警不调 CMS - 交易单号 (4200 开头 28 位) → 飞书告警不调 CMS
风险兜底
- 最坏损失 ≤
max_amount_fen(50 元/单) - CMS 为金额单一真源,OCR 金额仅日志
- 疑似格式错误必告警,不再静默
测试
``` 99 passed in tests/refund/ ```
上线前建议
用两张反光/截断的真实样例截图做实机 OCR 验证一次,确认 prompt 调整后 pay_id 识别稳定。