06 — 审批后子流程
来源:
api/order.ts saveStep(sign/pay/deliver)+views/application/Sign.tsx/Pay.tsx/Deliver.tsx
涉及页面:Sign PRD / Pay PRD / Deliver PRD
共 6 个接口(Sign 3 子阶段 + Pay + Deliver + 锁机激活轮询)
订单状态机完整定义见 手机分期订单状态机(SoT)。本文涉及 Approved / Signed / Paid / Completed / Closed 等状态的推进、异常码(ORDER_NOT_APPROVED 等)、时限规则,均以 SoT 为准。
业务上下文
风控审批通过(status = Approved)后,订单进入审批后子流程:
Reviewing → Approved → Signed → Paid → Completed
| | |
Sign 流程 SA 收首付 SA 交设备 + 锁机激活
(含合影)
| 步骤 | 谁主导 | 关键动作 |
|---|---|---|
| Sign(签约,3 子阶段) | SA 带客户走 | ① Confirm Plan:客户看方案接受 → ② Group Photo:SA + 客户现场合影留证 → ③ Sign Agreement:客户手写签字提交合同 |
| Pay(收款) | SA 收首付 | 现金 / 在线支付,留凭证 |
| Deliver(交付) | SA 把手机交给客户 | 扫 IMEI 二次核验 + 锁机服务激活 |
关键设计:
- Sign 流程内的 3 子阶段订单状态保持 Approved,子状态由前端按
order.group_photo_url/order.signed_at推断当前应在哪一子阶段 - 签约 / 收款 / 交付 涉及资金和合同,事务性强;建议拆独立接口(不复用 saveStep)便于鉴权 / 审计 / 防误调用
- 交付时 IMEI 必须与试算时 IMEI 一致(如有)— 防中途换机欺诈
1. 签约信息查询(Sign 子阶段 1:Confirm Plan)
业务描述:拉取签约页所需的合同摘要 + 客户确认信息。
触发场景:Sign 页 mount。
入参
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| order_id | string | ✓ | 订单 ID(status 必须是 Approved) |
出参
| 字段 | 类型 | 说明 |
|---|---|---|
| order_id | string | |
| customer_name | string | 客户姓名(用于合同抬头展示) |
| approved_amount | number(NGN) | 审批通过的分期金额 |
| down_payment | number(NGN) | 首付金额 |
| term | int | 分期期数 |
| frequency | enum | weekly / monthly |
| per_period_payment | number(NGN) | 单期还款(含利息) |
| total_repayment | number(NGN) | 总还款(loan + 利息) |
| interest_rate | string | 利率(百分比展示,如 4.5% per month) |
| first_due_date | string(ISO 8601) | 首期还款日 |
| contract_terms_md | string | 合同条款(markdown 富文本;前端 render) |
| contract_version | string | 合同版本号(审计字段) |
关键异常
| 异常码 | 含义 | 前端处理 |
|---|---|---|
| ORDER_NOT_APPROVED | 当前不是 Approved 状态 | toast + 跳详情 |
| CONTRACT_NOT_READY | 合同生成中(风控审批通过到合同生成有短暂延迟) | 显示”Preparing contract…” 5s 后重试 |
2. 合影上传(Sign 子阶段 2:Group Photo)
业务描述:SA 在 Confirm Plan 与 Sign Agreement 之间,与客户现场合影并提交。
触发场景:Sign 页 Group Photo 子阶段,SA 拍完合影后点击 Next。
入参
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| order_id | string | ✓ | 订单 ID(status 必须是 Approved) |
| group_photo_url | string | ✓ | 合影图 URL(前端先调图片上传接口拿 URL) |
出参 — 返回更新后的 OrderData;order.group_photo_url 字段已写入;status 不变(保持 Approved)
关键异常
| 异常码 | 含义 | 前端处理 |
|---|---|---|
| ORDER_NOT_APPROVED | 当前不是 Approved 状态 | toast + 跳详情 |
| PHOTO_URL_INVALID | URL 不可达 / 格式错 | toast + 让 SA 重传 |
注:图片上传接口(multipart/form-data)独立,URL 协议由架构师定(CDN / S3 / 内部路径)。
3. 客户签字提交(Sign 子阶段 3:Sign Agreement)
业务描述:客户在 SA 手机上画签名(canvas)后提交;触发 Approved → Signed 状态推进。
触发场景:Sign 页客户签字完毕 + 滚动到合同底部 + 点 Confirm Signature 按钮。
入参
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| order_id | string | ✓ | 订单 ID |
| signature_image_url | string | ✓ | 签名图 URL(前端先调图片上传接口拿 URL) |
| contract_version | string | ✓ | 客户签字时看到的合同版本(与查询接口出参一致;审计字段防版本错位) |
| signed_at_client_ts | string(ISO 8601) | ✓ | 客户签字时间(前端 ts,与服务端 ts 对比审计) |
| scrolled_to_bottom | boolean | ✓ | 客户是否完整看完合同(前端检测;审计字段) |
出参 — 返回更新后的 OrderData(status 应推到 Signed)
关键异常
| 异常码 | 含义 | 前端处理 |
|---|---|---|
| SIGNATURE_INVALID | 签名图为空 / 不合法 | toast + 让客户重签 |
| CONTRACT_VERSION_MISMATCH | 合同已更新版本(客户签字期间被运营/合规改了) | toast + 重新拉签约信息 |
| ORDER_NOT_APPROVED | 同 §1 异常 | 同上 |
4. 首付收款提交
业务描述:SA 引导客户向 PocketBuy 虚拟收款账户转账完成首付后,SA 确认到账提交。触发 Signed → Paid 状态推进。
通道:仅虚拟子账户银行转账(NIBSS / NIP)。
触发场景:Pay 页 SA 看到客户转账完成后点 Confirm Payment Received 按钮。
入参
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| order_id | string | ✓ | 订单 ID |
| amount | number(NGN) | ✓ | 应收金额(必须等于 down_payment) |
| confirmed_at_client_ts | string(ISO 8601) | ✓ | SA 确认时间(前端时间戳,与服务端到账时间对比审计) |
出参 — 返回更新后的 OrderData(status 应推到 Paid)
关键异常
| 异常码 | 含义 | 前端处理 |
|---|---|---|
| PAY_AMOUNT_MISMATCH | 实到账金额 ≠ 首付 | toast 提示金额对不上 |
| PAY_NOT_RECEIVED | 后端未检测到到账(客户尚未转账或转账失败) | toast Payment not received yet, please verify with customer + 不推进状态 |
| ORDER_NOT_SIGNED | 当前不是 Signed 状态 | toast + 跳详情 |
注:
- 客户转账通过 NIBSS / 各银行 NIP 通道到账;后端实时监听到账事件(webhook / 推送)。
- SA 端”Confirm Payment Received”按钮的语义:SA 看到客户银行 App 转账成功提示,请求后端校验到账;后端若已收到到账事件则推进 Paid,否则返回 PAY_NOT_RECEIVED 让 SA 让客户再核对。
- 客户的虚拟收款账户编号由后端按订单分配(订单创建时下发,前端 Pay 页展示该账户);架构师定具体编号生成 / 路由策略。
5. 交付确认(含 IMEI 二次校验)
业务描述:SA 把设备交给客户前,扫描设备 IMEI 二次校验 — 必须与试算时 IMEI(如有)或审批时绑定的 IMEI 一致,防欺诈换机。校验通过后触发 Paid → Completed + 后端启动锁机服务激活。
触发场景:Deliver 页 SA 扫设备 IMEI 后点 Confirm Delivery 按钮。
入参
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| order_id | string | ✓ | 订单 ID |
| imei | string | ✓ | SA 现场扫到的 IMEI(15 位) |
| delivered_at_client_ts | string(ISO 8601) | ✓ | 交付时间 |
出参
| 字段 | 类型 | 说明 |
|---|---|---|
| order | OrderData | 更新后的订单(status 应推到 Completed) |
| lock_activation_status | enum | pending / succeeded / failed — 锁机服务激活状态(首次返回多为 pending 异步处理) |
| lock_activation_message | string? | 激活失败时的说明 |
前端处理:
lock_activation_status = pending→ 前端进入”Activating…”等待态,每 3s 轮询 5 次succeeded→ 显示”Delivered + Activated” 跳详情failed→ 显示故障提示 + 联系运维流程
关键异常
| 异常码 | 含义 | 前端处理 |
|---|---|---|
| DELIVER_IMEI_MISMATCH | 现场 IMEI 与订单绑定 IMEI 不一致 | inline 错误 IMEI mismatch — same device required + SA 重扫 |
| DELIVER_IMEI_INVALID | IMEI 格式不对(应该前端拦下,兜底) | inline 错误 |
| DELIVER_DEVICE_ALREADY_LOCKED | 该 IMEI 已绑其它订单 | 严重 — toast + 走人工调查 |
| ORDER_NOT_PAID | 当前不是 Paid 状态 | toast + 跳详情 |
| LOCK_SERVICE_UNAVAILABLE | 锁机服务上游不可达 | 允许 SA 完成交付但 lock_activation_status=pending,后端异步重试 |
6. 锁机激活状态轮询
业务描述:交付接口若返回 lock_activation_status = pending,前端轮询此接口查激活进度。
触发场景:Deliver 页 phase = ‘activating’ 时每 3s 调用。
入参
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| order_id | string | ✓ | 订单 ID |
出参
| 字段 | 类型 | 说明 |
|---|---|---|
| lock_activation_status | enum | pending / succeeded / failed |
| lock_activation_message | string? |
注:可与 §4 出参结构对齐;如果架构师用 WebSocket / SSE 推送替代轮询,本接口可省略。
待业务方确认事项
| # | 议题 | 待确认 |
|---|---|---|
| 1 | IMEI 二次校验失败的业务处理 | 单次失败 inline + 重扫已确定;若同单连续 N 次失败是否触发风控警报 / 暂停订单 — 业务规则待定 |
| 2 | 客户合同副本派送 | 签约完成后客户是否拿合同副本、通过哪种渠道(SMS / 邮件 / SA 微信)— 合规 + UX 决策 |