3. 支付订单核心状态定义
支付订单状态机是整个聚合支付系统的核心骨架。状态定义是否清晰,直接决定了后续交易处理、对账、退款、风控等模块的复杂度和可靠性。本节将定义六个核心状态:待支付、支付中、支付成功、支付失败、已退款、已关闭,并给出每个状态的准入条件、业务含义和典型停留时长。
3.1 六状态总览
| 状态名称 | 状态码 | 业务含义 | 典型停留时长 | 是否终态 |
|---|---|---|---|---|
| 待支付 | PENDING | 订单已创建,等待用户发起支付 | 15分钟~24小时(超时关闭) | 否 |
| 支付中 | PROCESSING | 用户已提交支付,等待渠道异步结果 | 几秒~几分钟(渠道超时) | 否 |
| 支付成功 | SUCCESS | 渠道确认资金已划转完成 | 长期(可发起退款) | 是(可退款) |
| 支付失败 | FAILED | 渠道明确返回支付未成功 | 长期 | 是 |
| 已退款 | REFUNDED | 原支付订单已全额或部分退款 | 长期 | 是 |
| 已关闭 | CLOSED | 订单超时未支付或用户主动取消 | 长期 | 是 |
设计要点:“支付成功”虽然是终态,但允许通过退款操作转移到“已退款”状态。在状态机建模中,这种“终态但可转移”的设计需要特殊处理,通常通过子状态机或补偿事件来实现。
3.2 状态转换关系
六个状态之间的合法转换路径如下:
- 待支付 → 支付中:用户点击支付按钮,系统向渠道发起支付请求。
- 待支付 → 已关闭:用户主动取消,或订单超过支付有效期。
- 支付中 → 支付成功:渠道异步通知或轮询确认支付成功。
- 支付中 → 支付失败:渠道明确返回失败,或超时未收到确认。
- 支付中 → 待支付:渠道返回需要用户重新操作(如密码错误、卡信息错误)。
- 支付成功 → 已退款:用户发起退款,系统完成退款流程。
- 支付成功 → 支付失败:极少见,如渠道后续对账发现该笔交易实际失败,需人工介入。
关键约束:“支付中”状态不允许直接跳转到“已关闭”。如果用户在支付中阶段取消订单,系统必须先等待渠道结果,再根据结果决定进入“支付成功”或“支付失败”,最后再执行关闭逻辑。这是防止资金丢失的重要设计。
3.3 状态机 SVG 图
下图展示了六个核心状态及其合法转换关系。图中使用不同颜色区分初始态、中间态和终态,箭头上的标签表示触发事件。
3.4 状态定义详细说明
3.4.1 待支付 (PENDING)
- 创建时机:用户提交订单后,系统生成支付记录。
- 数据要求:订单号、金额、支付方式、渠道ID、商户ID、商品描述。
- 超时策略:通常设置15~30分钟超时,超时后自动进入“已关闭”。
- 幂等性:同一订单不可重复发起支付,需做防重校验。
3.4.2 支付中 (PROCESSING)
- 进入条件:系统已向渠道发送支付请求,等待异步回调。
- 风险点:渠道超时、网络闪断、回调丢失。
- 补偿机制:系统需启动定时轮询或重试任务,防止订单卡在“支付中”。
- 用户感知:前端应展示“支付处理中,请稍候…”并禁用重复提交。
3.4.3 支付成功 (SUCCESS)
- 确认方式:渠道异步通知优先,轮询结果作为兜底。
- 后续动作:触发商户通知、发货、积分赠送、对账记录生成。
- 退款能力:支持全额或部分退款,退款后进入“已退款”。
3.4.4 支付失败 (FAILED)
- 失败原因:余额不足、风控拦截、渠道系统异常、卡信息错误。
- 用户提示:需明确展示失败原因,引导用户重新支付。
- 重试策略:允许用户从“支付失败”重新发起,此时新建一笔支付订单。
3.4.5 已退款 (REFUNDED)
- 触发条件:用户申请退款或商户主动退款。
- 退款类型:全额退款、部分退款(需记录退款金额和剩余金额)。
- 对账要求:退款记录必须与渠道退款流水一一对应。
3.4.6 已关闭 (CLOSED)
- 触发条件:用户主动取消、超时未支付、风控拒绝。
- 不可逆:关闭后不可再发起支付,需重新下单。
- 资源释放:释放预占的库存、优惠券、积分等资源。
3.5 状态定义常见误区
避坑指南:
- 误区一:将“支付中”视为临时状态,不记录日志。→ 正确做法:支付中状态必须记录完整的请求和响应日志,用于对账和问题排查。
- 误区二:允许“支付中”直接跳转到“已关闭”。→ 正确做法:必须先等待渠道结果,再决定最终状态。
- 误区三:“支付成功”后不允许任何状态变更。→ 正确做法:保留“支付成功→已退款”的合法路径。
- 误区四:状态码使用数字而非枚举。→ 正确做法:使用有语义的字符串枚举,便于扩展和排查。
3.6 状态定义检查清单
在实际项目中,建议使用以下清单验证状态定义是否完整:
- 每个状态是否有明确的进入条件和退出条件?
- 是否存在无法到达的“孤儿状态”?
- 所有终态是否都有对应的业务处理逻辑?
- 状态转换是否覆盖了所有异常场景(超时、重试、取消)?
- 状态变更是否都有审计日志记录?
- 状态机是否支持未来扩展(如部分退款、部分关闭)?
最佳实践:在项目初期,将状态定义以状态机图的形式固化到技术文档中,并作为代码评审的必查项。每次新增状态或转换路径,都需要更新状态机图并通知相关团队。