订单状态怎么设计:别用一个字段装所有情况

订单状态越加越多,最后没人说得清某个值代表什么。本文说明状态机该怎么划分、支付与发货为什么要分开记,以及异常状态的处理。

要点速览
  • 一个字段装支付、履约、售后多个维度,会导致状态值组合式增长。
  • 拆成独立的支付、履约、售后状态,对外展示时再合成给用户看的说法。
  • 必须明确每个状态能转到哪些状态,非法流转直接拒绝而非静默执行。
  • 每个可能失败的环节都要有对应的异常状态并进入人工队列,否则订单会静默卡住。
  • 状态变更日志单独成表、只追加,它在客诉与对账时比当前状态更有价值。

订单状态字段的典型演化:一开始是待付款、已付款、已发货、已完成四个值。然后加了已取消、退款中、已退款、部分退款、待审核、已关闭 —— 两年后字段里有二十多个值,新人看代码时无法判断某两个状态能不能互相转换。

问题在于一个字段装了多个维度

「已付款」说的是支付状态,「已发货」说的是履约状态,「退款中」说的是售后状态。它们是可以同时存在的 —— 一笔订单可以同时是已付款、已发货、退款中。强行塞进一个字段,就必须为每种组合造一个新值,于是值的数量成组合式增长。

更清晰的做法是拆成几个独立字段:支付状态、履约状态、售后状态,各自有自己的取值和流转规则。对外展示时再按业务规则合成一个给用户看的说法。

流转要有约束

  • 明确每个状态能转到哪些状态,非法流转直接拒绝而不是静默执行;
  • 状态变更要带操作人与原因,系统自动变更也要记录是哪个任务触发的;
  • 并发变更要加锁或用乐观锁,两个客服同时操作同一订单是真实会发生的;
  • 终态要明确:已完成、已关闭之后不应再变化,需要变化说明状态划分有问题。

异常状态要显式存在

支付回调处理失败、发货接口超时、退款被拒 —— 这些情况如果没有对应的状态,订单就会停在某个中间值,看起来一切正常,实际上卡住了。应当有明确的异常状态并进入人工处理队列。

判断办法是:列出所有可能失败的环节,每一个都问「失败后订单是什么状态、谁会知道」。答不上来的就是会卡住的地方。

变更日志比当前状态更有价值

当前状态只有一个值,而客诉处理、对账、退款争议需要的是完整过程:什么时候付的款、什么时候发的货、谁在什么时候改成了已完成。这份日志应当单独成表、只追加不修改。

它的另一个作用是排查:订单状态异常时,日志能直接显示是哪一步出的问题,而不需要去翻应用日志。相关设计见电商网站 / 商城定制。状态机定义应当写进接口文档并随项目交付,安排见合作流程。

常见问题

订单状态为什么越加越多?

因为一个字段同时表达了支付、履约、售后多个维度,而这些维度可以并存——一笔订单可以同时是已付款、已发货、退款中。每出现一种组合就要新增一个值,数量于是组合式增长。拆成多个独立字段可以从根本上解决。

订单卡在中间状态怎么办?

根本办法是让每个可能失败的环节都有对应的异常状态,并自动进入人工处理队列。设计时逐一列出可能失败的步骤,对每一步追问失败后订单处于什么状态、谁会知道,答不上来的就是会静默卡住的地方。

需要记录订单状态变更历史吗?

需要,而且应当单独成表、只追加不修改,记录时间、操作人和原因。当前状态只有一个值,而客诉处理、对账和退款争议需要的是完整过程。这份日志同时也是排查状态异常最直接的依据。

参考资料

  1. 支付宝开放平台文档 · 支付宝开放平台
  2. WooCommerce Documentation · WooCommerce
# 订单# 状态机# 电商系统# 数据建模
免费咨询

聊聊你的项目

留下联系方式,我们一个工作日内联系你。先沟通需求和现状,再给方案;报价当面沟通。

  • 一个工作日内回复
  • 需求沟通免费,不强推方案
  • 交付管理后台与文档,可自行维护
仅用于本次咨询联系,不会用于其他用途。