D07 退款与对账域 · 设计文档

本域总览见《账号计费中心 · 结构大纲》。本文为该域完整设计:定位与边界 / 角色与依赖 / 数据模型 / 核心流程 / 接口契约 / 关键约束与验收标准。

排序说明:先数据模型(事实结构)→ 再核心流程(结构之上的运行路径)→ 最后接口契约(流程的对外投影)。


1. 定位与边界

定位:资金流出的唯一闸门与资损防线的最后一道。回答三个问题——「这笔钱该不该退、由谁批准」(审批链与二审门禁)、「钱到底出去了多少」(以渠道实退为准的冲销口径)、「账实是否相符」(渠道账单与本地流水的双向对账)。

核心概念

概念 承载 语义
退款申请 customer_orders 的 refunding 状态 申请只改状态不动钱;申请人不等于审批人
本次定额 customer_orders.refund_amount 审批时定格,重试与人工收敛沿用;后续不得超原额
累计已退 customer_orders.refunded_amount 部分与多次退款的唯一计数器,出款成功才累计
剩余可退 派生量 refundable_of 订单金额 − 累计已退,是每单上限而非全局常量
退款请求号 customer_orders.refund_request_no 渠道幂等键(订单号加序号),同号只退一次
冲销流水 customer_transactions 的 refund 类型行 只增反转行,金额为负;账务真相源
对账差异 risk_events 台账(属风控域) 本域产生与收敛,台账归风控域
待线下打款 customer_orders.offline_paid_confirmed_at 纯台账语义,不动账、不改状态

关键口径

边界

归属口径


2. 角色与依赖

能力矩阵

能力 门户用户 运营面 计费路由(router) 数据面网关
自助申请退款 ✓(本人订单) ✓(代客申请) ✗ ✗
审批通过 / 驳回 ✗ ✓(实人门禁) ✗ ✗
二审登记 / 复审 ✗ ✓(须不同操作人) ✗ ✗
重试 / 人工结清 / 放弃 / 线下确认 ✗ ✓ ✗ ✗
触发轮询与渠道对账 ✗ ✗ ✗ ✗(部署侧定时与进程内扫描触发)

上游依赖

上游 依赖内容 语义
订购与支付域 订单行、状态与 paid_at、渠道、支付时点 可退订单来源;只退已支付、未退尽的充值单
钱包与账务域 现金余额、只增流水、欠费标记重算 冲销的落账目标;余额为负是正常态
外部资金通道 退款接口、单笔退款查询、日账单 出款真相与对账账单一侧
运营管理域 平台员工与权限范围 出款资格与四眼原则的身份真相

下游被引用

引用方 引用内容 语义
风控与合规域 退款异常与渠道差异信号 落处置台账并分级处置
通知与触达域 到账 / 失败 / 线下打款文案 成功与失败触达的投递
账户状态与准入域 冲销后的余额变更事件 退款是解封路径,须即时发布状态
订购与支付域 退款进度状态与归一原因码 订单列表与详情展示「部分已退 / 待二审」标记

3. 数据模型

本域无自有表:退款以订单行的退款相关列与资金流水的退款类型行承载,对账差异落风控处置台账。

3.1 域内关联总览

一笔订单的多笔冲销行(按退款请求号唯一)退款归属的钱包主体渠道对账差异与异常落台账(弱关联)二审登记的操作人标识(弱引用)

customer_orders

uuid

id

PK

string

order_no

UK

订单号,退款请求号的命名基

uuid

customer_id

FK

钱包主体,删除受限

string

type

仅充值类型可退

string

channel

渠道:网关型 / 对公转账

string

status

退款态:refunding / refund_processing / refunded / refund_failed / refund_unknown

decimal

amount

订单金额,元 6 位小数

decimal

refund_amount

本次退款定额,审批时定格

decimal

refunded_amount

累计已退,出款成功才累计

string

refund_request_no

渠道幂等键,订单号加序号

string

refund_second_review_by

第一审批人标识,非空即待二审

decimal

refund_second_review_amount

待二审金额定格,复审须一致

timestamp

refund_last_attempt_at

最近一次渠道尝试,退避与上限基准

timestamp

refund_last_polled_at

最近一次渠道查询,退避锚点

customer_transactions

uuid

id

PK

uuid

customer_id

FK

钱包主体

string

type

refund 冲销行;支出类行参与画像口径

decimal

amount

冲销行为负,元 6 位小数

string

ref_order

订单号,对账 join 键与幂等键

jsonb

detail

含退款请求号,冲销幂等键

customers

risk_events

uuid

id

PK

uuid

rule_id

FK

命中规则

timestamp

triggered_at

命中时点与去重键

platform_staff

图 1

退款请求号落流水明细而非独立表:冲销行的唯一索引以「订单号 + 明细中的退款请求号」为键,部分索引收窄到退款类型,历史无该键的行天然不受影响。

3.2 域间引用

现金余额增减与流水写入退款请求号唯一索引与逐笔对账join渠道差异与异常信号订单状态机与渠道能力二审操作人标识,弱引用冲销后余额变更事件

customer_orders
订单行的退款列

钱包与账务域
customers / customer_transactions

customer_transactions
refund 冲销行

风控与合规域
risk_events 处置台账

订购与支付域
支付回调与凭据

运营管理域
platform_staff

账户状态与准入域
准入状态发布

图 2

3.3 表清单

表 读写 关键字段
customer_orders 读写 order_no / customer_id / type / channel / status / amount / refund_amount / refunded_amount / refund_request_no / refund_failed_reason / refund_second_review_by / refund_second_review_amount / refund_last_attempt_at / offline_paid_confirmed_at
customer_transactions 写(只增)+ 读 customer_id / type / amount / ref_order / detail / created_at
customers 只读 cash_balance(画像与推负判定)/ overdue_since(派生标记,不作债务判据)
operation_logs 读(频控计数)+ 写(留痕) actor_id / action / target_id / created_at / detail
risk_events 写(差异与异常落台账) rule_id / customer_id / organization_id / status / triggered_at
platform_staff 只读 user_id / status / scopes(出款资格)

3.4 设计约束

  1. 冲销幂等唯一:部分唯一索引按「订单号 + 明细中的退款请求号」建立、仅覆盖退款类型行;同订单同请求号至多一行冲销流水,并发撞索引即收敛为幂等返回。
  2. 流水只增:冲销一律新增反转行,数据库层拒绝改写与删除既有流水;已出款的退款只能靠新增调整行更正。
  3. 金额精度:退款定额与渠道比对口径均为元、2 位小数等效值;订单金额列宽 20 位,入参越界在入口即拒。
  4. 累计口径唯一:累计已退只由出款成功路径累加,失败与未知路径不触碰该列,部分退款的可退额度不被虚高或挤压。
  5. 待二审定格非空即门禁:待二审人标识与定格金额同生命周期,出款、驳回、放弃、新一轮发起四处一并清空;带标记的订单只接受「同金额 + 不同操作人」复审。
  6. 状态取值封闭:退款相关状态仅取 refunding / refund_processing / refunded / refund_failed / refund_unknown 五值,状态列宽须容纳最长值;部分退款完成后回 paid,故不得用订单终态判退款幂等,幂等一律以退款请求号为准。

4. 核心流程

4.1 申请与审批主线

外部资金通道关系库运营面退款与对账域门户用户外部资金通道关系库运营面退款与对账域门户用户alt[超频控][受理]alt[状态非 refunding 且非 refunded 终态][金额越界或精度不符][需二审且本次为首审批][复审且金额与定格一致且操作人不同][对公转账渠道]申请退款(本人订单)频控:滚动 24h 上限 / 同单驳回冷却429 申请受限取订单咨询锁后落 refunding已受理,等待审批审批通过(可带定额)取订单咨询锁 + 行锁409 不可退款422 定额越界 / 精度不符登记第一审批人 + 定格本次金额,状态保持 refunding待二审(不落款)记复审审计并清标记出款审批即冲销并累计refunded 或 paid(部分完成)受理 / 明确拒绝 / 网络异常按回执三类分流收敛
图 3

4.2 二审门禁与金额定格

是(复审)否是是否否(首审批)否是

审批通过:按本次定额取风险画像

待二审标记是否非空

定格金额是否可核验且等于本次金额

409 金额与定格不符:fail-closed,不清标记

操作人是否与第一审批人同一

幂等返回待二审(网络抖动重试不误放)

落复审审计,清标记与定格,继续出款

金额达阈值或带推负标记

直接出款

登记第一审批人 + 定格本次审定金额

保持 refunding,返回待二审

图 4

4.3 审批前风险画像(只读,不持锁)

是是是否是否是否

画像入参:订单 + 本次退款金额

读钱包现金余额

退款金额是否大于现金余额

标记推负:将负债,并给出超额金额

订单是否已支付

支付后是否存在支出类流水

标记支付后已有消费

是否在支付后短时窗内

标记零消费的充值即退特征

不加该标记

读历史退款笔数

笔数是否达阈值

标记高频退款

组装画像

按定额 + 标记判定是否需二审,附待二审定格值

图 5

4.4 部分与多次退款

否是

订单已支付 paid

申请:refunding

审批出款成功

累计已退 += 本次定额

累计已退是否达订单金额

状态回 paid:可再次发起,剩余可退为新差额

状态 refunded 终态:剩余可退为零

本轮二审标记与定格一并清空

图 6

4.5 渠道出款三阶段与实退金额比对

外部资金通道关系库退款与对账域外部资金通道关系库退款与对账域alt[实退金额与本地定额一致][金额不符或渠道未回金额][查询不可用]alt[渠道报有资金变化][受理但无资金变化记录][渠道明确拒绝][网络异常]审批持锁:定额、生成退款请求号、清二审标记落 refund_processing 并提交(关闭双提交窗口,后到审批即 409)锁外提交退款按退款请求号查询单笔实退金额冲销 + 累计 + 落审计 + 站内信,提交后发布准入状态全额 refunded / 部分回 paid转结果未知 + 告警(不冲销)留未比对审计 + 告警,保持处理中交轮询回执落档,保持处理中交轮询置失败 + 归一原因码 + 告警(不冲销)保持处理中,绝不置失败
图 7

4.6 异常三分支收敛

明确拒绝且原因不可重试类明确拒绝且原因可重试类结果未知是否,且确认渠道未出款无法核实且已过 24 小时上限

终态与原因

409 不可重试:只能人工结清或放弃

重试:沿用同一退款请求号重提

渠道账单是否已核实资金已出

人工结清,依据取账单核实

人工线下打款 + 人工结清,依据取线下已打款

结果未知终态:告警,禁止按失败走线下

刷新最近尝试时点:退避与 24h 时钟重置

重提后按回执重新分流

放弃:回 paid,余额保留

已结清单只得转入待线下打款清单闭环

图 8

4.7 轮询收敛与退避

是否否是渠道不可达或凭据缺失查询成功且实退金额一致查询成功但实退金额不符或缺失查询成功但渠道未确认成功

周期扫描:取处理中订单

距最近尝试是否已达 24 小时上限

转结果未知 + 告警,不再查询

距退避锚点是否已达当前档间隔

本轮跳过,等下轮

按渠道查询单笔退款

刷新查询锚点防热循环,保持处理中

冲销并收敛为终态

转结果未知 + 告警(不冲销)

回执落档,保持处理中

图 9

4.8 线下打款与待核对清单

对公转账订单审批通过

审批即冲销,状态置已退款

进入待线下打款清单(未确认)

运营按清单执行线下打款

打款确认:落确认时点,幂等

转入已确认视图,闭环

渠道失败单经人工线下打款后结清

图 10

4.9 渠道退款对账与差异分类

外部资金通道关系库对账服务日频扫描外部资金通道关系库对账服务日频扫描alt[汇总无差异][存在差异]alt[渠道无账单能力][账单暂态失败][账单终态失败][拿到账单]判断是否跨入新自然日且已过对账时点按渠道逐个拉取账单拉取指定日账单跳过,不计失败标记可重试,至多 30 分钟后重试,累计达上限即当日落定告警后当日落定,重试无出口本地侧只统计本次对账渠道的退款流水双向比对笔数与金额,分类差异平账,落审计自动升级逐笔:请求号精确配对 → 金额贪心配对 → 逐个查询核对落审计 + 差异告警
图 11

5. 接口契约

5.1 门户自助(/api/account)

方法 路径 语义
POST /api/account/orders/{order_no}/refund-apply 客户自助退款申请:本人已支付充值订单 → 待审批;跨用户订单按订单不存在处理;滚动 24h 上限超限与同单驳回冷却内分别拒绝;期望金额仅审计参考

5.2 内部退款与对账(/internal)

方法 路径 语义
POST /internal/orders/{order_no}/refund-request 运营侧发起退款申请(对账冲正 / 代客申请)
POST /internal/orders/{order_no}/refund-approve 审批通过:金额定额 + 二审门禁 + 渠道出款;返回已退款 / 回已支付 / 处理中 / 失败
POST /internal/orders/{order_no}/refund-reject 审批驳回:待审批 → 已支付,无冲销
POST /internal/orders/refunds/poll 退款轮询(幂等):扫处理中到点单查渠道收敛;供部署侧定时与手动兜底
POST /internal/orders/refunds/reconcile-channel 渠道退款对账(汇总级 + 逐笔,幂等):指定账单日、模式与渠道;供手动补跑
GET /internal/orders/refunds/offline-pending 待线下打款核对清单:对公转账已退款单,可按已确认过滤

5.3 运营面退款处置(/api/account/ops)

方法 路径 语义
POST /api/account/ops/orders/{order_no}/refund-request 运营发起退款(实人令牌,操作人恒为令牌本人)
POST /api/account/ops/orders/{order_no}/refund-approve 审批通过(同 5.2 语义)
POST /api/account/ops/orders/{order_no}/refund-reject 审批驳回
POST /api/account/ops/orders/{order_no}/refund-retry 同号重提;不可重试类拒绝
POST /api/account/ops/orders/{order_no}/refund-manual-settle 人工结清:依据与状态强绑定;幂等
POST /api/account/ops/orders/{order_no}/refund-abandon 终止退款:失败态回已支付;处理中与未知态拒绝
POST /api/account/ops/orders/{order_no}/refund-offline-confirm 线下打款确认:台账语义,幂等
GET /api/account/ops/orders/{order_no}/refund-risk 审批前风险画像(只读)
GET /api/account/ops/orders/refunds/offline-pending 待线下打款核对清单(与 5.2 同源)

6. 关键约束与验收标准

6.1 约束

  1. 申请不动钱:申请与驳回只改订单状态,不写流水、不动余额;资金动作只发生在审批出款与人工结清;可退额度 = 订单金额 − 累计已退,两道都校验,无全局常量上界。
  2. 金额定格不可漂移:本次定额在审批时确定并落订单行,重试与人工结清一律沿用,复审只能审定格值。
  3. 四眼原则不可退化:需二审的单必须由两个不同操作人标识先后审批;首审批人不得自行复审;同人重试按幂等返回而非放行。
  4. 出款资格统一:出款类端点在两条令牌路径上共用同一份资格事实(在册 + 在用 + 持有出款权限),资格回收与停用即时生效。
  5. 不确定即不收敛:渠道报成功但实退金额无法核实时保持处理中并告警,绝不以本地定额自证冲销。
  6. 失败与未知账务等价:两类状态都不冲销,区别只在处置路径(失败可放弃、未知只能按账单核实结清);重试一律沿用同一退款请求号。
  7. 幂等键是请求号不是订单终态:部分退款完成后订单回到已支付态,故幂等一律以退款请求号与冲销流水唯一索引承载。
  8. 对账同源同渠道:两侧必须同一渠道、同一自然日(本地按中国标准时间归日),本地侧不得按渠道全集过滤,同日重跑结果一致;本地流水找不到对应订单行时必须显式落为孤儿差异。
  9. 对账可重试与终态分清:账单未生成、网络类暂态失败可重试并有次数上限;凭据失效、渠道不支持、账单日非法为终态,告警后当日落定,不留无出口的空转。
  10. 线下确认不动账:清单与确认动作只承载执行台账,不改状态、不写流水、不动余额。
  11. 只回现金:不恢复赠金、不动信用额度;退款可把现金推为负,负债回潮交由欠费标记的单一重算规则处理。

6.2 验收标准

# 验收口径
1 非已支付状态或非充值类型订单申请退款:拒绝,状态不变、无流水落库、不进入待审批;剩余可退为零时同样被拒
2 同一客户滚动 24h 内申请次数达上限:门户路径被拒、运营路径不受限;同单驳回后冷却窗内再次申请被拒
3 审批定额超过剩余可退或精度超过等效 2 位小数:拒绝且不落款、不改状态
4 首笔大额退款(达阈值):返回待二审,订单保持待审批、不落流水、余额不变
5 第一审批人自行复审或换金额复审:均不给过且标记保留;第二位操作人按定格金额复审:出款成立、标记清空
6 部分退款出款成功:累计已退等于本次定额、订单回已支付、剩余可退为差额并可再审批;全部退完后置已退款终态、再申请被拒
7 渠道明确拒绝:置失败并带归一原因码、余额与流水均不变、产生告警
8 渠道报成功但实退金额不符:不冲销、转结果未知、出告警与审计;查询不可用或网络异常:保持处理中交轮询收敛,绝不置失败
9 未知单按「线下已打款」结清被拒、按「渠道账单核实已退」结清成功且幂等;处理中订单终止或人工结清均被拒;可能已退过的原因终止被拒而重试可行
10 轮询:自最近尝试起超 24 小时无结论的单转结果未知并告警且不再查询;同日重复触发不产生新流水与状态变更
11 并发两次收敛同一笔退款:恰有一条冲销流水、累计已退不重复累加,后到者返回幂等
12 对公转账审批通过即冲销并进入待线下打款清单(未确认视图),确认后转入已确认视图且不产生新的资金动作
13 对账:本地侧只统计本次对账渠道(另一渠道不落假差异);渠道独有行归为账单独有、本地流水无对应订单行时归为孤儿差异且不被忽略;两侧皆同时平账并同日重跑一致
14 渠道无账单能力时跳过且不计失败;暂态失败在累计重试达上限后当日落定并告警、终态失败告警后当日落定、跨日计数归零
15 全程落审计(申请 / 驳回 / 首审批 / 复审 / 退回 / 放弃);出款类端点缺操作人、非标识格式、不在册、已停用或无出款权限时一律按无权限拒绝;凭据缺失的网关型退款直接置失败且不动账

6.3 待后续设计细化的开放项

  1. 自动退款(无人工审批的小额自动放行)的阈值分级与风控信号闭环。
  2. 退款通知的通道编排与去重窗口:站内信同事务落库、外部通道异步发送的失败重投口径。
  3. 人工结清的复核留痕升级:现为单操作人动作,是否纳入双人复核。
  4. 对账差异处置台账的处置状态回写与关闭条件(依赖风控与合规域的处置台能力)。