P61 项目场景:电商订单拆单与合单业务设计
面试题:电商下单时为什么要拆单?拆单怎么设计?支付时为什么又要合单?
1. 什么是拆单/合单
- 拆单:一次下单(购物车多商品)拆成多个子订单;
- 合单:多个子订单(或同一商家的多笔)合并成一次支付(支付单)。
2. 为什么拆单
| 原因 | 例子 |
|---|---|
| 不同商家 | 淘宝/京东第三方店铺各自结算、各自发货 |
| 不同仓库/物流 | 商品分属多地仓,拆成不同物流包裹 |
| 不同履约方式 | 自营/海外购/虚拟商品(不发货)分开处理 |
| 不同结算规则 | 不同商家优惠券、运费、税费独立计算 |
| 库存/锁定粒度 | 部分商品缺货,其余先发货 |
3. 拆单设计
数据模型
text
订单单(主订单 order)1 : N 子订单(sub_order)
子订单 1 : N 订单明细(order_item)
支付单(payment)1 : N 子订单(合单支付)拆单流程
text
提交购物车 → 按商家/仓库/履约类型分组
→ 每组生成子订单(各自算商品金额、运费、优惠)
→ 生成主订单关联所有子订单
→ 生成支付单(金额 = 各子订单之和)关键点:
- 拆单规则可配置(按商家/仓库/发货时间等优先级);
- 优惠分摊:平台优惠券按商品金额比例分摊到子订单;
- 库存锁定按子订单粒度,部分失败只回滚对应子订单;
- 主订单与子订单状态机联动(子订单都完成 → 主订单完成)。
4. 为什么合单支付
- 用户体验:一次下单一次支付,而不是拆成 N 笔分别支付;
- 支付平台限制:微信/支付宝单笔金额、笔数限制;
- 对账方便:支付单 ↔ 第三方流水一一对应。
合单要点
- 支付回调按支付单处理:回调成功 → 给关联的所有子订单同时标记已支付;
- 幂等:支付结果多次回调只处理一次;
- 部分支付/退款按子订单维度:退款单关联子订单,不能整单乱退;
- 关单/超时:支付单超时未支付,子订单全部取消并释放库存。
5. 加分点
- 说清"订单、子订单、支付单、退款单"四类单据的关系;
- 提到拆单后对账:支付单金额 = Σ子订单应付,异常要告警;
- 追问"拆单后优惠怎么算":平台券按比例分摊、商家券留在本子订单;
- 状态机:待支付 → 已支付 → 部分发货/全部发货 → 完成/退款。
一句话总结
按商家/仓库/履约类型把一次下单拆成多个子订单(各自结算库存),再生成一个支付单合单支付;核心是"主订单-子订单-支付单"模型 + 优惠分摊 + 支付回调按支付单幂等处理 + 退款按子订单维度。