手机分期订单状态机

单一事实源(SoT):跨 SA App / 客户 App(PocketBuy)/ 运营后台 / 风控 / 信贷核心的状态机契约。
任何涉及订单状态的设计、接口、PRD、代码注释,应引用本文档,不得自行定义新的状态名 / 枚举值 / 流转规则。
如需新增状态或调整流转,先改本文档再同步下游。

适用业务线:手机分期(PocketBuy)。现金贷(RocketCash)等其它业务线的订单状态机应独立分册(避免直接套用)。


1. 文档定位与适用范围

说明
适用业务手机分期(PocketBuy)— SA 代客办单的完整生命周期
适用端SA App(PocketBuy SA)/ 客户 App(PocketBuy Client)/ 运营后台 / 风控决策 / 信贷核心
状态语义一级状态全部用完成式命名(描述当前所处状态而非”待做什么”)
子状态语义二级标签不进一级状态机,作为附加字段描述当前一级状态的细分原因或属性
工程命名规范一级状态:PascalCase(如 DraftingFixRequired);二级枚举值:snake_case(如 identity_mismatchdeclined

2. 一级状态(8 个)

状态业务含义SA 下一动作UI 标签(i18n value)UI Tab 归属二级字段(如有)
Drafting进件中:客户资料填写未完成;订单已创建有 order_id,可中途暂停后续录继续录单 → Review 提交DraftingPending(pending tab)
Reviewing客户已提交,风控审批中等审批结果ReviewingReviewing(in_approval tab)
FixRequired风控要求补正资料跳回标红 step 补齐后重提Fix RequiredPending(pending tab)fix_reason + fix_notes
Approved已审批通过,待签约跳 Sign 流程ApprovedPending(pending tab)offer_type
Signed已签约,待 SA 收首付跳 PaySignedPending(pending tab)offer_type
Paid已收首付,待 SA 交付设备 + 锁机激活跳 DeliverPaidPending(pending tab)offer_type
Completed已交付 + 锁机激活完成;订单生效CompletedCompletedoffer_type
Closed已关闭(拒贷 / 用户放弃 / 过期)ClosedClosedclose_reason

UI Tab 与一级状态的映射(4 Tab):

UI Tab 标签tab_id(技术字段)包含状态
PendingpendingDrafting / FixRequired / Approved / Signed / Paid
Reviewingin_approvalReviewing
CompletedcompletedCompleted
ClosedclosedClosed

tab_id in_approval 是历史技术命名(早期叫 In Approval),UI 显示 Reviewing;改名风险高(破坏 URL section param / 后端枚举),保留不动。


3. 状态流转图

stateDiagram-v2
    [*] --> Drafting: OTP 通过 + 创建订单
    Drafting --> Reviewing: Review 页 SA 帮客户提交
    Reviewing --> Approved: 风控审批通过(含 offer_type=original 或 revised)
    Reviewing --> FixRequired: 风控要求补资料(带 fix_reason)
    Reviewing --> Closed: 风控拒贷 → close_reason=declined
    FixRequired --> Reviewing: SA 原单补齐后重提
    FixRequired --> Closed: SLA 超时 → close_reason=returned
    Approved --> Signed: Sign 流程子阶段 3 客户签字提交
    Approved --> Closed: 24h 未推进 → close_reason=expired
    Signed --> Paid: Pay 页 SA 确认收到首付
    Signed --> Closed: 24h 未推进 → close_reason=expired
    Paid --> Completed: Deliver 页 IMEI 校验通过 + 锁机激活成功
    Paid --> Closed: 24h 未闭环 → close_reason=expired
    Completed --> [*]
    Closed --> [*]

关键说明

  • Drafting 不会自动 Closed:客户已落库但未提交,运营可手动归档但状态机不自动转。
  • Reviewing 没有 24h 超时:风控审批时长由风控侧 SLA 控制,不在状态机层超时。
  • Approved / Signed / Paid 均 24h 超时自动 Closed(expired):给”SA 推进窗口”加上限,避免库存锁定 / 客户决策窗口拖长。
  • 没有 Drafting → Approved 等跳步 — 必须经过 Reviewing
  • 没有 Closed → 任何 — 关闭后不可重开(如要重新办单需新建订单)。

4. 二级状态字段(不进一级状态机)

二级字段是附加在一级状态上的细分原因或属性标签,作为 OrderData 的可选字段返回。不改变状态机流转

4.1 fix_reason(仅 status = FixRequired 时有意义)

取值含义触发场景
identity_mismatchBVN / NIN 核验信息与 SA 录入不符风控核身阶段发现不一致
income_insufficient收入不足 / 流水异常风控收入评估不通过
guarantor_invalid担保人信息核验失败担保人手机号无效 / BVN 不可达等
address_unverified居住地址无法核实地址核验失败
other其它原因(须配合 fix_notes 自由文本说明)不在上述枚举内的补正方向

配套字段:

  • fix_notes: string(可选,≤ 500 字符):自由文本,用于补充说明(特别是 other 取值时)

4.2 offer_type(仅 status ∈ {Approved, Signed, Paid, Completed} 时有意义)

取值含义业务影响
original按 SA 试算方案审批通过合同方案 = 试算方案
revised风控调价通过(如降额 / 改期数)合同方案 ≠ 试算方案;详情见 approval_result 字段;UI 端订单卡显示 “Offer Revised” 黄标

:早期 prototype 用过 revised_offer: boolean 字段表达同一语义;v2.0 起统一改为 offer_type 枚举。

4.3 close_reason(仅 status = Closed 时有意义)

取值含义触发场景
declined风控拒贷Reviewing → Closed(风控审批不通过)
returned客户主动放弃 / 三次联系不上FixRequired SLA 超时;或运营三次联系不上
expired长时间未推进过期Approved / Signed / Paid 24h 未推进;自动转 Closed

5. Sign 流程子阶段(非二级状态,前端推断)

Sign 流程内部 3 子阶段(订单 status 整个 Sign 流程保持 Approved):

子阶段客户端 signStep触发条件完成时写入字段
Confirm Plan1进入 Sign 页时默认
Group Photo2SA 点 Confirm Plan & Continueorder.group_photo_url(合影 URL)
Sign Agreement3SA 拍完合影点 Nextorder.signed_at(提交时同时推进 status 到 Signed)

Continue 路径恢复逻辑(前端按字段推断当前子阶段):

if (!order.group_photo_url)  → signStep = 1(Confirm Plan)
else if (!order.signed_at)   → signStep = 3(Sign Agreement)
else                          → 已经是 Signed 状态,跳 Pay

重要约定

  • OrderDatasign_substage: enum 字段
  • 进入订单状态机
  • ✅ 前端按已有字段(group_photo_url / signed_at)推断
  • ✅ 后端只需要正确接收 saveStep('group_photo', ...)saveStep('review', { signed_at })(或 saveStep('sign', ...))两个事件

为什么这样设计

  1. Sign 子阶段是流程内部步骤,不是状态机层面的”状态”
  2. 信息已经在 group_photo_url 字段里隐含(有 = 进过 Step 2;没有 = 还在 Step 1)
  3. 业务上 Sign 流程是 SA 连续操作,不像 Drafting 那种”长时间挂起”需要监控进度
  4. 如未来需要追踪”SA 在合影环节的流失率”等运营数据,用埋点分析,不动状态机

6. 状态推进触发条件

谁触发 → 状态变化 → 调用什么接口 → 关键字段

From → To触发方接口写入字段
(初始)DraftingSA(Verify OTP 通过)校验 OTP + 创建订单([[接口需求/SA App/03-客户身份验证与订单创建#203 §2]])status='Drafting'
DraftingReviewingSA(Review 提交)进件正式提交([[接口需求/SA App/04-进件资料采集#504 §5]])status='Reviewing'customer_authorized=truesubmitted_at
ReviewingApproved风控风控决策事件status='Approved'offer_type ∈ {original, revised}approval_result
ReviewingFixRequired风控风控决策事件status='FixRequired'fix_reasonfix_notes?
ReviewingClosed(declined)风控风控决策事件status='Closed'close_reason='declined'
FixRequiredReviewingSA(补齐后再提)同 Drafting → Reviewing
FixRequiredClosed(returned)后台(SLA 超时)定时任务status='Closed'close_reason='returned'
ApprovedSignedSA(客户签字提交)客户签字提交([[接口需求/SA App/06-审批后子流程#206 §2]])status='Signed'signed_atsignature_image_url
ApprovedClosed(expired)后台(24h 未推进)定时任务status='Closed'close_reason='expired'
SignedPaidSA(确认首付到账)首付收款提交([[接口需求/SA App/06-审批后子流程#306 §3]])status='Paid'confirmed_at
SignedClosed(expired)后台定时任务同上
PaidCompletedSA(IMEI 二次校验通过 + 锁机激活成功)交付确认([[接口需求/SA App/06-审批后子流程#406 §4]])status='Completed'delivered_atlock_activation_status='succeeded'
PaidClosed(expired)后台定时任务同上

Sign 流程子阶段(Confirm Plan → Group Photo → Sign Agreement)不在本表,因 status 全程保持 Approved


7. 时限规则(推进窗口期)

状态推进窗口默认值红字阈值(前端 SA 端订单卡)超时后状态业务含义运营可配置
Drafting无超时SA 可中途暂停后续录
Reviewing由风控 SLA 控制不在订单状态机超时层
FixRequired由运营 SLA 配置Closed(returned)客户补资料窗口
Approved24h< 12hClosed(expired)客户决策签约窗口✅ 独立配置
Signed24h< 12hClosed(expired)等待首付到账窗口✅ 独立配置
Paid24h< 12hClosed(expired) + 首付退款SA 交付设备 + 激活窗口✅ 独立配置
Completed终态
Closed终态

SA App 订单卡 expires_at 字段呈现倒计时;< 红字阈值时改用 text-stateDanger 颜色。


8. 状态相关的异常码

接口层面与状态机相关的异常码命名规则:ORDER_NOT_<状态> — 表示当前订单状态不允许该操作。

异常码含义使用场景
ORDER_NOT_FOUND订单不存在任何拉单 / 改单接口
ORDER_NOT_AUTHORIZED订单不属于当前 SA同上(多租户隔离)
ORDER_STATUS_INVALID当前订单状态不允许该操作(通用兜底)进件资料采集 / saveStep
ORDER_NOT_APPROVED当前不是 Approved 状态Sign 子流程相关接口
ORDER_NOT_SIGNED当前不是 Signed 状态首付收款接口
ORDER_NOT_PAID当前不是 Paid 状态交付确认接口

9. 其它文档引用关系

本文档为 SoT,下列文档应引用本文(不应自行定义状态名 / 枚举):

文档引用方式
04-进件资料采集 §2 OrderData 出参引用本文 §2 一级状态 + §4 二级字段
06-审批后子流程引用本文 §6 推进规则 + §7 时限规则 + §8 异常码
07-列表与汇总查询引用本文 §2 UI Tab 映射 + §4.3 close_reason 取值
kangaroo_prototype/.../docs/application/overview_prd.md §3.2.2 状态机引用本文(替代原 prototype 自行维护的状态机图)
kangaroo_prototype/.../api/order.ts 类型注释引用本文 §2 / §4

如未来加入 客户 App(PocketBuy Client)/ 运营后台 / 风控 / 信贷核心 相关文档涉及订单状态,应直接引用本文,避免分叉。


10. 修改记录

  • [2026-06-01] v2.0:首版(从 prototype overview_prd.md §3.2.2 + 接口需求 04/06/07 整合);一级状态全完成式命名;新增 3 个二级字段(fix_reason / offer_type / close_reason);Sign 流程子阶段不入状态机的设计决策落档。