前言

支付结算是 Java 面试里最容易被问深的业务场景。它不只是调用微信、支付宝接口,还包括支付单、订单状态、回调幂等、退款、对账、分账、资金流水和异常补偿。

面试官通常会追问:

  • 支付回调重复通知怎么办。
  • 用户支付成功但订单没更新怎么办。
  • 退款失败如何补偿。
  • 资金流水为什么不能直接覆盖更新。
  • 对账差异怎么处理。

支付链路

sequenceDiagram
    participant U as 用户
    participant O as 订单服务
    participant P as 支付服务
    participant C as 第三方支付
    participant M as MQ

    U->>O: 提交订单
    O->>P: 创建支付单
    P->>C: 发起支付
    C-->>U: 用户完成支付
    C->>P: 支付回调
    P->>P: 幂等校验和验签
    P->>M: 支付成功事件
    M->>O: 更新订单状态

企业中一般会把业务订单和支付单分开:订单表达买卖关系,支付单表达资金请求。一个订单可能有多次支付尝试、退款、部分退款或支付渠道切换。

支付单设计

核心字段通常包括:

字段 说明
pay_no 内部支付单号,全局唯一
order_no 业务订单号
channel 支付渠道
amount 支付金额
status INIT、PAYING、SUCCESS、FAILED、CLOSED
channel_trade_no 第三方交易号
notify_time 回调时间

支付状态更新建议用条件更新:

1
2
3
update pay_order
set status = 'SUCCESS', channel_trade_no = ?
where pay_no = ? and status in ('INIT', 'PAYING');

这样可以避免重复回调导致重复处理。

回调幂等

第三方支付回调一定要按“可能重复、可能乱序、可能延迟”设计。

常见措施:

  1. 验签,确认回调来自支付渠道。
  2. 校验金额、订单号、商户号。
  3. 以第三方交易号或支付单号做唯一约束。
  4. 支付单状态条件更新。
  5. 支付成功事件异步通知订单服务。

面试表达:

支付回调不能直接信任,也不能直接重复改订单。要先验签和校验金额,再通过支付单状态机做幂等,最后用消息或事件驱动订单状态变更。

退款设计

退款链路比支付更复杂,因为涉及原路退回、部分退款、退款失败、退款回调和资金对账。

退款单建议独立建模:

字段 说明
refund_no 内部退款单号
pay_no 原支付单
amount 退款金额
status INIT、PROCESSING、SUCCESS、FAILED
reason 退款原因

方案对比:

方案 优点 缺点
同步退款 用户体验直观 依赖第三方稳定性
异步退款 抗抖动、可补偿 状态复杂
人工退款 可处理疑难单 效率低,需要审计

对账

对账用于发现本地系统与支付渠道之间的差异。

常见流程:

  1. 下载渠道账单。
  2. 按支付单号、金额、状态匹配本地记录。
  3. 生成差异单。
  4. 自动补偿或人工处理。

差异常见类型:

  • 渠道成功,本地未成功。
  • 本地成功,渠道不存在。
  • 金额不一致。
  • 退款状态不一致。
flowchart TD
    A[渠道账单] --> C[对账任务]
    B[本地支付流水] --> C
    C --> D{是否一致}
    D -->|是| E[标记平账]
    D -->|否| F[生成差异单]
    F --> G[自动补偿/人工处理]

分账与资金流水

分账场景常见于平台型业务:平台收款后按规则把资金拆给商家、渠道、服务商。

资金流水要点:

  • 流水只能追加,不能随意覆盖。
  • 每笔资金变动都有来源单据。
  • 收入、支出、冻结、解冻、退款都要可追溯。
  • 金额字段用整数分或 BigDecimal,避免浮点误差。

高频面试题

支付回调重复怎么办?

验签后基于支付单号或第三方交易号做幂等,状态更新加条件,已经成功的回调直接返回成功。

支付成功但订单没更新怎么办?

通过 MQ 重试、支付状态补偿任务、渠道对账来修复,订单服务消费支付成功事件也必须幂等。

为什么需要支付单?

支付单隔离业务订单和资金请求,一笔订单可能有多次支付尝试或多次退款,支付单能让资金链路更清晰。

对账有什么用?

对账是支付系统的兜底能力,用来发现回调丢失、状态不一致、金额不一致等问题。

总结

支付结算场景的核心是资金安全。回答时要抓住:支付单独立建模、回调验签和幂等、退款状态机、资金流水追加、对账补偿。企业系统里不能只依赖一次回调成功,必须有补偿和对账兜底。