# Split Order

> 拆单

- Skill: `1398281322-a11y/split-order` (Agent Skill)
- Install (CLI): `npx skillmds@latest add 1398281322-a11y/split-order`
- Raw SKILL.md: https://api.skillmd.com/api/skills/1398281322-a11y/split-order/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: 1398281322-a11y (https://skillmd.com/u/1398281322-a11y)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/1398281322-a11y/split-order

---


# 拆单

## When to Invoke

购物车跨店、多仓发货、文旅一单里多个景区/门店要分别履约和结算。面试：「怎么拆单、支付怎么付」。

## When NOT

分库分表 → `sharding`。普通单店单仓不要拆。

## 风险（面试考点）

父单支付成功、子单创一半：钱与货不一致。拆完每子单独立扣自己仓库存，取消要按子单释放。客服只拿父单号找不到子单。

支付两种：父单一次支付再分账；子单分别支付。C 端默认 **父单一次支付**，内部拆子单履约。

## 方案选型（轻量优先）

```text
t_order_parent  支付、用户、应付总额
t_order_split   parent_no + merchant_id/warehouse_id, 自己的状态、金额、运费
```

拆分键：`merchant_id`（电商多店）或 `warehouse_id` 或 `poi_id`（文旅门店）。同一键一行子单。

下单本地事务：写父单 + 所有子单 + 各子单预占。失败全滚。支付回调只改父单 PAID，再消息通知子单 PAID（子单幂等）。

履约、发货、售后挂在 **子单**。退款金额不能超过该子单实付。

## 默认方案

```sql
UNIQUE KEY uk_parent_merchant (parent_no, merchant_id)
```

父单号对外展示；子单号内部履约。查询始终能用父单号查出全部子单。

部分子单售后：父单状态 `PARTIAL_REFUND`，不要整单关。

## 反例

错误：一个订单表 `merchant_ids` 逗号存多家，发货无法拆。
正确：子单行。

错误：子单各自调支付，用户付 N 次。
正确：C 端一次支付（除非业务就是到店分付）。

错误：取消父单只改父状态，子单库存不释放。
正确：遍历子单走释放流水。

## 验证

- 两店结算，生成 1 父 2 子，支付一次，两店都能看到待发货。
- 一店售后，另一店不受影响。
- 关父单，两店预占都释放且只一次。

## 评审清单

- [ ] 有父单号和子单号
- [ ] 库存按子单预占
- [ ] 支付次数与产品设计一致
---

