退款闸门 Refund Guard(业务规则 v1.0)
在 Agent 真正调用退款/放款工具之前同步调用本闸门。它不碰你的订单库:订单真伪、归属、实付、已退、退款次数、账龄等事实由调用方 OMS 在鉴权后作为入参传入,闸门只对这些事实做规则裁决并签发防篡改收据。
三态裁决
allow:硬规则全部满足,形状安全可执行(最终放款仍由商家 OMS 执行,allow 不是放款指令)。deny:非法或必然资损,必须拒绝。escalate:转人工审核,暂不放款。
规则(金额单位:分,CNY)
allow 需全部满足:
- 订单存在且属于该用户;
- 退款金额 ≤ 剩余可退金额;
- 金额 < 100 元(10000 分);
- 该订单未退过款;
- 未超可退期限;非重复提交;账号非新号;近 30 天退款次数 < 3。
deny(命中任一,优先级最高):
| code | 条件 |
| --- | --- |
| ORDER_INVALID | 订单不存在 / 不属于该用户 |
| OVERPAY | 退款金额 > 剩余可退金额 |
| REFUND_WINDOW_EXPIRED | 超过 30 天可退期限 |
| DUPLICATE_SUBMISSION | 同一退款请求重复提交(request_id 幂等) |
| INPUT_INVALID | 关键事实缺失/非法(fail-closed) |
escalate(无 deny 时命中任一):
| code | 条件 |
| --- | --- |
| AMOUNT_HUMAN_REQUIRED | 金额 ≥ 100 元 |
| FREQUENT_REFUND_30D | 近 30 天退款 ≥ 3 次 |
| PRIOR_REFUND_REVIEW | 该订单之前退过款/部分退款后再申请 |
| NEW_ACCOUNT_REVIEW | 账号注册 < 7 天 |
判定优先级:deny > escalate > allow;边界为严格不等(正好 100 元转人工、正好 30 天可退、正好 7 天号龄不转人工、正好 3 次转人工)。
输入(JSON:文件路径或 stdin)
{
"trace_id": "可选,链路ID",
"order": {
"order_id": "ORD20261012001",
"exists": true,
"belongs_to_user": true,
"paid": 20000,
"refundable_amount_cents": 20000,
"already_refunded": false,
"signed_days_ago": 2,
"currency": "CNY"
},
"request": {
"request_id": "uuid-幂等键",
"amount_cents": 5000,
"currency": "CNY"
},
"user": { "refund_count_30d": 0, "account_age_days": 30 }
}
字段说明:
- 金额推荐显式用 *_cents(整数=分)。为兼容旧系统:number 整数按「分」,字符串按「元」(如 "88.5"→8850)。为 fail-safe,整数 number 不做元/分猜测,一律按分。
- order.exists / belongs_to_user 缺省视为 true,但建议 OMS 显式传入,不要让闸门替你判断订单真伪。
- signed_days_ago 省略则不做超期判定(订单未签收等场景)。
- request.request_id 强烈建议传:服务端据此做跨实例幂等;不传时退化为订单+金额指纹。
用法
export REFUND_GUARD_KEY='<渠道方分配的 key,勿写进代码/仓库>'
# 可选:export REFUND_GUARD_ENDPOINT='https://refund-guard-poc.pages.dev'
# 可选:export REFUND_GUARD_CHANNEL='oem_shangkeda'
python3 scripts/refund_decide.py case.json
cat case.json | python3 scripts/refund_decide.py
python3 scripts/refund_decide.py case.json --json # 机器可读
退出码:0=allow,10=escalate,20=deny,2=本地错误/调用失败(按 fail-closed 处理)。
fail-closed 铁律(客户端已内置)
- 3 秒同步超时(
REFUND_GUARD_TIMEOUT可调,默认 3); - 网络异常、超时、非 200、HTTP 402(key 无效/未付费)、响应非法、收据验签失败、收据过期、外层 verdict 与签名收据不一致 → 一律当
deny,禁止放款; - 收据用脚本内嵌的 Ed25519 公钥离线验签(零第三方依赖,RFC 8032 纯 Python 实现),私钥永不下发到客户端。
收据(6 字段,Ed25519,5 分钟有效)
order_id、refund_amount_cents、currency、verdict、nonce(防重放)、expires_at。规范化为递归按 key 排序的无空白 JSON(JCS RFC 8785 风格),UTF-8 后 Ed25519 签名。deny 也出收据,便于审计追溯。
计费
接口为收费接口:无有效凭证返回 HTTP 402 + Payment-Needed。PoC 渠道测试 key 在联调期免费旁路(响应 billing.tier=test_free)。正式集成请联系 wangguigui@correctover.com 开通付费 key。
边界与免责
闸门不读取聊天记录、不做内容合规、不直连订单库、不实际打款。自动裁决仅为辅助风控/合规手段,不构成退款授权、审计或法律意见;最终放款由商家 OMS 执行。