Skip to content

P61 项目场景:电商订单拆单与合单业务设计 ​

面试题:电商下单时为什么要拆单?拆单怎么设计?支付时为什么又要合单?

1. 什么是拆单/合单 ​

  • 拆单:一次下单(购物车多商品)拆成多个子订单;
  • 合单:多个子订单(或同一商家的多笔)合并成一次支付(支付单)。

2. 为什么拆单 ​

原因例子
不同商家淘宝/京东第三方店铺各自结算、各自发货
不同仓库/物流商品分属多地仓,拆成不同物流包裹
不同履约方式自营/海外购/虚拟商品(不发货)分开处理
不同结算规则不同商家优惠券、运费、税费独立计算
库存/锁定粒度部分商品缺货,其余先发货

3. 拆单设计 ​

数据模型 ​

text
订单单(主订单 order)1 : N 子订单(sub_order)
子订单 1 : N 订单明细(order_item)
支付单(payment)1 : N 子订单(合单支付)

拆单流程 ​

text
提交购物车 → 按商家/仓库/履约类型分组
→ 每组生成子订单(各自算商品金额、运费、优惠)
→ 生成主订单关联所有子订单
→ 生成支付单(金额 = 各子订单之和)

关键点:

  • 拆单规则可配置(按商家/仓库/发货时间等优先级);
  • 优惠分摊:平台优惠券按商品金额比例分摊到子订单;
  • 库存锁定按子订单粒度,部分失败只回滚对应子订单;
  • 主订单与子订单状态机联动(子订单都完成 → 主订单完成)。

4. 为什么合单支付 ​

  • 用户体验:一次下单一次支付,而不是拆成 N 笔分别支付;
  • 支付平台限制:微信/支付宝单笔金额、笔数限制;
  • 对账方便:支付单 ↔ 第三方流水一一对应。

合单要点 ​

  • 支付回调按支付单处理:回调成功 → 给关联的所有子订单同时标记已支付;
  • 幂等:支付结果多次回调只处理一次;
  • 部分支付/退款按子订单维度:退款单关联子订单,不能整单乱退;
  • 关单/超时:支付单超时未支付,子订单全部取消并释放库存。

5. 加分点 ​

  • 说清"订单、子订单、支付单、退款单"四类单据的关系;
  • 提到拆单后对账:支付单金额 = Σ子订单应付,异常要告警;
  • 追问"拆单后优惠怎么算":平台券按比例分摊、商家券留在本子订单;
  • 状态机:待支付 → 已支付 → 部分发货/全部发货 → 完成/退款。

一句话总结 ​

按商家/仓库/履约类型把一次下单拆成多个子订单(各自结算库存),再生成一个支付单合单支付;核心是"主订单-子订单-支付单"模型 + 优惠分摊 + 支付回调按支付单幂等处理 + 退款按子订单维度。

基于 VitePress 重建