diff --git "a/docs/02-\350\256\276\350\256\241\346\226\207\346\241\243/process/wqq/C03-\350\256\242\345\215\225\350\266\205\346\227\266\346\265\201\347\250\213.md" "b/docs/02-\350\256\276\350\256\241\346\226\207\346\241\243/process/wqq/C03-\350\256\242\345\215\225\350\266\205\346\227\266\346\265\201\347\250\213.md"
new file mode 100644
index 0000000000000000000000000000000000000000..572be1465852090b034ba6c888b1aeb13f0adedc
--- /dev/null
+++ "b/docs/02-\350\256\276\350\256\241\346\226\207\346\241\243/process/wqq/C03-\350\256\242\345\215\225\350\266\205\346\227\266\346\265\201\347\250\213.md"
@@ -0,0 +1,187 @@
+# C03 订单超时自动取消流程
+
+> 负责人:韦乾强
+> 覆盖:C03 订单超时自动取消
+> 基础核心流程:M04 订单状态机(F08/F09)、M05 支付(F10)
+> 直接协作:罗皓晨(M00 Worker 基础设施)、张海洋(M05 支付)、朱惠惠(M03 购物车)
+> 文档状态:修订中
+> 需求事实源:[需求规格说明书 C03 订单超时自动取消](../../../01-需求文档/需求规格说明书.md) 的"C03 订单超时自动取消"完整章节
+
+## 一、范围与事实来源
+
+本挑战模块负责在买家未按时支付时,由系统自动取消订单并回补库存。核心目标是"超时即取消、取消即回补、并发安全"。Worker 定时扫描 PendingPayment 订单,对超时订单执行与买家主动取消相同的状态变更和库存回补逻辑。
+
+本文先确认超时触发条件、超时时间配置、扫描策略、与支付模块的状态竞争处理,再登记对 M04 订单状态机的复用边界和对 M09 站内消息的输出接口。
+
+| 设计对象 | 当前成熟度 | 本文处理 |
+|---|---|---|
+| C03 需求 | 完整定义 | 作为超时取消业务语义事实源 |
+| 超时时间配置 | 正式环境 30 分钟,演示环境可配置 | 由部署配置注入,不硬编码 |
+| 超时扫描与取消事务 | 修订中 | 修正重试语义矛盾、库存通道区分、锁策略 |
+| 与支付的状态竞争 | 完整定义 | 条件更新保证幂等 |
+| 站内消息通知 | M09 承载 | 登记输出事件类型和消息内容要求 |
+
+## 二、基础核心流程依赖
+
+```mermaid
+flowchart LR
+ ORDER["M04 Ordering
PendingPayment 订单创建"] --> TIMEOUT["C03 超时 Worker
定时扫描 PendingPayment 订单"]
+ ORDER --> PAY["M05 Payment
买家主动支付"]
+ TIMEOUT -->|"超时取消事务|回补库存"| STOCK["M02 Catalog
库存回补"]
+ TIMEOUT -->|"OrderCancelledIntegrationEvent
超时取消通知"| MSG["M09 站内消息"]
+ PAY -->|"OrderPaidIntegrationEvent
支付成功通知"| MSG
+ MSG -->|"超时取消通知
买家站内消息"| BUYER["买家消息中心"]
+```
+
+关键约束:
+
+- C03 复用 M04 的订单状态变更和库存回补逻辑,不独立发明新事务。
+- C03 由 Worker 后台任务触发,不提供买家主动接口。
+- 超时时间从订单 `created_at` 计算,不从其他时间点计算。
+
+## 三、超时时间配置
+
+```mermaid
+flowchart TD
+ A["Worker 启动"] --> B["读取配置 OrderTimeoutMinutes"]
+ B --> C{"配置存在?"}
+ C -- "否" --> D["使用默认值 30 分钟"]
+ C -- "是" --> E["使用配置值"]
+ D --> F["订单超时时间已确认"]
+ E --> F
+```
+
+关键约束:
+
+- 超时时间通过配置项 `OrderTimeoutMinutes` 管理。
+- 正式环境默认 30 分钟。
+- 演示环境可通过配置调整为更短时间(如 5 分钟),但需说明与正式参数的对应关系。
+- 配置不得硬编码。
+
+## 四、Worker 超时扫描流程
+
+```mermaid
+flowchart TD
+ A["Worker 定时触发(建议间隔 ≤ 超时时间/2)"] --> B["查询超时订单(FOR UPDATE SKIP LOCKED):status = PendingPayment AND created_at + timeout < NOW()"]
+ B --> C{"有待处理订单?"}
+ C -- "否" --> Z["本次扫描结束"]
+ C -- "是" --> D["按批次处理(建议每批 ≤ 100 条)"]
+ D --> E["对每条超时订单开启独立事务"]
+ E --> F["条件更新状态为 Cancelled:WHERE status = PendingPayment"]
+ F --> G{"影响行数 = 1?"}
+ G -- "否" --> H["订单已被其他操作处理(如已支付/已取消),跳过"]
+ G -- "是" --> I{"订单类型?"}
+ I -- "普通订单" --> J1["回补普通库存:stock = stock + quantity"]
+ I -- "秒杀订单" --> J2["回补秒杀活动库存 + 释放买家限购额度"]
+ J1 --> J3["记录 cancelled_at = NOW() 和 cancel_reason = TIMEOUT"]
+ J2 --> J3
+ J3 --> K["写入 Outbox:OrderCancelledIntegrationEvent(cancel_reason = TIMEOUT)"]
+ K --> L["提交事务"]
+ L --> M{"提交成功?"}
+ M -- "否" --> N["记录错误日志"]
+ N --> O{"当前重试次数 < 3?"}
+ O -- "是" --> P["重试次数 +1,继续处理该订单"]
+ P --> E
+ O -- "否" --> Q["重试次数已达上限,标记失败并告警"]
+ M -- "是" --> R["重试次数归零,继续处理下一条"]
+ Q --> R
+ R --> S{"批次处理完成?"}
+ S -- "否" --> D
+ S -- "是" --> Z
+```
+
+关键约束:
+
+- 扫描间隔建议 ≤ 超时时间/2(如超时 30 分钟,扫描间隔 ≤ 15 分钟)。
+- 每批次处理上限 100 条,避免长时间锁表。
+- 使用条件更新 `WHERE status = 'PendingPayment'` 保证幂等。
+- 库存回补与订单状态变更、Outbox 写入处于同一事务;任一失败则整体回滚,不允许出现"订单已取消但库存未回补"的部分成功状态。
+- 单笔订单最多重试 3 次;3 次均失败后标记该订单为永久失败、发送告警,由人工介入处理,不再自动重试。
+- 重试次数记录在订单或独立调度记录中,不依赖 Worker 进程内存。
+
+## 五、与支付的状态竞争处理
+
+```mermaid
+flowchart TD
+ subgraph 并发竞争
+ A["C03 Worker:超时扫描并尝试取消"] --> B["条件更新状态为 Cancelled"]
+ C["买家:主动点击支付"] --> D["M05 支付事务:条件更新状态为 Paid"]
+ end
+
+ B --> E{"乐观锁结果"}
+ D --> F{"乐观锁结果"}
+
+ E -- "取消成功,行数=1" --> G["库存已回补,订单已取消"]
+ F -- "支付成功,行数=1" --> H["余额已扣减,订单已支付"]
+ E -- "行数=0:已被支付" --> I["取消跳过,返回幂等成功"]
+ F -- "行数=0:已被取消" --> J["支付跳过,返回余额未扣减"]
+```
+
+关键约束:
+
+- 取消与支付使用相同的条件更新 `WHERE status = 'PendingPayment'`。
+- 最终只有一个操作成功,避免"又支付又取消"的矛盾状态。
+- 两者竞争时数据库事务隔离保证最终一致性。
+
+## 六、事件输出
+
+```mermaid
+flowchart TD
+ A["超时取消事务提交成功"] --> B["发布 OrderCancelledIntegrationEvent(cancel_reason = TIMEOUT)"]
+ B --> C["Outbox 投递到 MQ"]
+ C --> D["Messaging 事件总线路由"]
+ D --> E["M09 消费事件,生成站内消息:订单超时取消通知"]
+ E --> F["买家查看消息中心"]
+```
+
+事件内容要求:
+
+- 消息标题:订单超时取消
+- 消息内容:您的订单 {订单号} 因超时未支付已自动取消,库存已回补,如有需要可重新下单。
+- cancel_reason = 'TIMEOUT' 用于 M09 生成差异化文案。
+
+## 七、异常与边界场景
+
+| 场景 | C03 处理 | 最终状态/责任 |
+|---|---|---|
+| Worker 停止 | 重启后继续扫描 | 不漏扫,不重复取消 |
+| 数据库连接短暂中断 | 记录错误日志,本次扫描重试 | 最多延迟一个扫描周期 |
+| 扫描时订单已被支付 | 条件更新影响行数=0,跳过 | 订单保持 Paid |
+| 扫描时订单已被买家取消 | 条件更新影响行数=0,跳过 | 订单保持 Cancelled |
+| 库存回补时商品已删除或秒杀活动已结束 | 事务整体回滚,记录错误日志;若该订单重试次数 < 3,下次扫描继续重试;若已达 3 次,标记永久失败并告警 | 订单保留 PendingPayment,等待人工处理 |
+| 多实例 Worker 并发扫描 | 扫描查询使用 SELECT FOR UPDATE SKIP LOCKED;领取与处理在同一事务内完成 | 同一订单只被一个 Worker 处理 |
+| 单笔订单重试 3 次均失败 | 标记永久失败,发送告警,人工介入 | 订单保留 PendingPayment |
+
+## 八、与 M04 订单模块的复用关系
+
+C03 复用的 M04 逻辑:
+
+| M04 逻辑 | C03 复用方式 |
+|---|---|
+| 取消条件校验 | 直接复用订单归属和状态判断 |
+| 库存回补事务 | 直接复用库存回补 SQL |
+| 订单状态变更 | 直接复用条件更新 SQL |
+| cancelled_at 和 cancel_reason | 直接复用字段写入 |
+| OrderCancelledIntegrationEvent | 复用事件结构,cancel_reason = TIMEOUT |
+
+C03 不改变的 M04 逻辑:
+
+- 订单创建逻辑
+- 订单查询逻辑
+- 买家主动取消的具体接口契约
+
+## 九、验收证据清单
+
+- [ ] 超时订单被自动取消,状态变为 Cancelled
+- [ ] 库存正确回补,回补量 = 订单项数量
+- [ ] 普通订单回补普通库存,秒杀订单回补秒杀活动库存并释放限购
+- [ ] cancelled_at 和 cancel_reason = TIMEOUT 已写入
+- [ ] OrderCancelledIntegrationEvent(TIMEOUT)已发布到 Outbox
+- [ ] 买家收到站内消息通知
+- [ ] 买家在超时前支付成功,取消被跳过
+- [ ] 并发取消与支付只有一个成功,不出现矛盾状态
+- [ ] 重复取消返回幂等成功,库存只回补一次
+- [ ] Worker 重启后继续扫描,不漏扫
+- [ ] 多实例 Worker 不重复处理同一订单
+- [ ] 单笔订单重试 3 次均失败后告警,不无限重试
+- [ ] 演示环境超时时间可配置(如 30 秒、5 分钟)
diff --git "a/docs/02-\350\256\276\350\256\241\346\226\207\346\241\243/process/wqq/M04-\350\256\242\345\215\225\346\265\201\347\250\213.md" "b/docs/02-\350\256\276\350\256\241\346\226\207\346\241\243/process/wqq/M04-\350\256\242\345\215\225\346\265\201\347\250\213.md"
new file mode 100644
index 0000000000000000000000000000000000000000..1b6809d0538ec7e8cf560e68933a1f9515c01482
--- /dev/null
+++ "b/docs/02-\350\256\276\350\256\241\346\226\207\346\241\243/process/wqq/M04-\350\256\242\345\215\225\346\265\201\347\250\213.md"
@@ -0,0 +1,278 @@
+# M04 订单流程
+
+> 负责人:韦乾强
+> 覆盖:M04-01 提交订单(F08)、M04-02 订单列表与详情(F09)、M04-03 取消订单(F09)
+> 基础核心流程:M01 身份与鉴权、M02 分类与商品、M03 购物车、M05 支付、M06-02 后台订单管理
+> 直接协作:朱惠惠(M03 购物车)、张海洋(M05 支付)、顾欣月(M02 商品)、罗皓晨(M09 站内消息)
+> 文档状态:修订中
+> 需求事实源:[需求规格说明书 M04 订单模块](../../../01-需求文档/需求规格说明书.md) 的"M04-01、M04-02、M04-03"完整七节
+
+## 一、范围与事实来源
+
+本模块负责买家在已登录态下完成订单创建、订单查询、订单取消,以及商家在后台完成订单发货。订单模块承担"交易确认与履约的核心状态机",连接买家购物车结算、支付模拟、商家履约和管理员监督。
+
+本文先依据需求确定业务参与者、上游输入、状态派生口径、原子结果和模块出入口,再由这些动作派生接口契约。A301~A308 只用于流程完成后的契约映射与缺口检查,不能反向拼接流程,也不能用现有 Axxx 反向覆盖业务语义。
+
+| 设计对象 | 当前成熟度 | 本文处理 |
+|---|---|---|
+| M04-01/F08、M04-02/F09、M04-03/F09 需求 | 完整定义 | 作为订单业务语义事实源 |
+| 本文业务流程 | 修订中 | 修正库存条件语义、Mermaid 围栏、事件消费路径 |
+| A301~A308 接口 | 部分定义、未冻结 | 由流程派生并做映射;冲突记为接口待评审项 |
+| DBxxx(orders、order_items) | 模板/占位 | 本文不发明字段、约束和索引 |
+| C03 订单超时取消 | 独立扩展 | 登记边界,不混入 F08/F09 主流程 |
+| M06-02 后台订单管理 | F12 基础履约 | 仅登记与 M04 共享的订单状态机边界 |
+
+## 二、模块直接出入口
+
+```mermaid
+flowchart LR
+ ID["M01 Identity
已认证买家、角色、账号状态"] -->|"BuyerOnly 通过"| ORD["M04 Ordering
订单状态机:PendingPayment → Paid → Shipped → Completed"]
+ CART["M03 Cart
已选中条目、服务端金额"] -->|"提交结算:商品+数量+地址+幂等键"| ORD
+ CAT["M02 Catalog
实时价格、实时库存、上架状态"] -->|"价格快照、库存扣减/回补"| ORD
+ PAY["M05 Payment
模拟支付状态、余额"] -->|"支付成功/失败、余额变化"| ORD
+ ORD -->|"订单列表、详情、取消/确认动作"| BUYER["买家订单页"]
+ ORD -->|"发货操作、物流信息"| MERCHANT["商家后台订单页"]
+ ORD -->|"站内消息通知"| MSG["M09 站内消息"]
+ MSG -->|"订单状态变更通知"| BUYER
+ MSG -->|"待发货通知"| MERCHANT
+
+ ID -. "买家取消 / 超时取消".-> ORD
+ CAT -. "商品下架/改价".-> ORD
+```
+
+边界约束:
+
+- M04 不接受前端传入最终金额,订单总额由服务端按快照计算。
+- M04 库存扣减/回补在事务内完成,使用条件更新防止超卖。
+- M04 不承担购物车、支付、站内消息的内部状态,只消费外部输入并输出确定性结果。
+- C03 超时取消复用 M04 的状态机与库存回补逻辑,但由 Worker 触发,不走买家主动接口。
+
+## 三、提交订单(M04-01 / F08)
+
+```mermaid
+flowchart TD
+ ID["M01:已认证且状态正常的买家"] --> A["买家从购物车提交订单:商品 ID 列表 + 地址 ID + 幂等键"]
+ CART["M03 Cart:读取选中条目"] --> B
+ CAT["M02 Catalog:读取实时价格、实时库存、上架状态"] --> B
+ A --> B{"全部商品可售且库存充足?"}
+ B -- "否" --> X["整单拒绝,返回问题商品和当前可购数量"]
+ B -- "是" --> C{"地址归属当前买家?"}
+ C -- "否" --> Y["拒绝:地址无效"]
+ C -- "是" --> D["服务端计算订单总额 = Σ(实时单价 × 数量)"]
+ D --> E["开启订单创建事务"]
+ E --> F["条件扣减库存:商品可售 AND 库存充足"]
+ F --> G["创建订单主记录(PendingPayment)+ 订单项快照"]
+ G --> H["解析并保存 assignedMerchantUserId"]
+ H --> I["删除已下单的购物车条目"]
+ I --> J["写入 Outbox:OrderCreatedIntegrationEvent"]
+ J --> K{"事务提交成功?"}
+ K -- "否" --> R["库存回滚、订单不创建"]
+ K -- "是" --> L["返回订单号、应付金额、PendingPayment 状态"]
+```
+
+关键约束:
+
+- 同一幂等键 `(buyer_id, idempotency_key)` 只创建一张订单,重复请求返回首次成功结果。
+- 库存扣减在事务内使用商品可售且库存充足的条件更新,避免并发超卖和商品下架后仍被下单。
+- 订单项保存商品名称、图片、成交单价快照,后续改价不影响已有订单。
+- 地址保存快照,后续修改不影响已有订单。
+- 订单金额由服务端计算,不接受客户端传入。
+- 购物车清理在同事务内完成;清理失败时事务整体回滚,库存不扣减,订单不创建。
+
+## 四、订单列表与详情(M04-02 / F09)
+
+### 4.1 订单列表
+
+```mermaid
+flowchart TD
+ ID["M01:已认证买家"] --> A["买家请求订单列表:分页 + 可选状态筛选"]
+ A --> B["按 buyer_id = 当前用户过滤"]
+ B --> C["按状态筛选(PendingPayment/Paid/Shipped/Completed/Cancelled)"]
+ C --> D["按创建时间倒序返回列表"]
+ D --> E["返回订单号、状态、总额、创建时间、商品摘要"]
+```
+
+关键约束:
+
+- 买家只能查看本人订单,按 buyer_id 过滤。
+- 订单号可脱敏展示,商品摘要最多 3 个。
+- 分页参数 page ≥ 1,pageSize 默认 10,上限 50。
+
+### 4.2 订单详情
+
+```mermaid
+flowchart TD
+ ID["M01:已认证买家"] --> A["买家请求订单详情:orderId"]
+ A --> B{"订单存在且归属当前买家?"}
+ B -- "否" --> X["返回 404 或 403,不泄露归属"]
+ B -- "是" --> C["返回完整订单信息"]
+ C --> D["地址快照:收件人、手机号(脱敏)、省市区、详细地址"]
+ D --> E["订单项快照:商品名称/图片/单价/数量/小计"]
+ E --> F["状态时间线:创建/支付/发货/完成/取消时间"]
+ F --> G["可用操作入口:根据状态展示 cancel/confirm/pay"]
+```
+
+关键约束:
+
+- 订单项为快照,不读取商品实时价格。
+- 地址为快照,不读取地址实时状态。
+- 状态时间线展示所有状态变更节点。
+
+## 五、取消订单(M04-03 / F09)
+
+```mermaid
+flowchart TD
+ ID["M01:已认证买家"] --> A["买家请求取消订单:orderId"]
+ A --> B{"订单存在且归属当前买家?"}
+ B -- "否" --> X["返回 404 或 403"]
+ B -- "是" --> C{"订单状态为 PendingPayment?"}
+ C -- "否" --> Y["返回 409:状态不允许取消"]
+ C -- "是" --> D["开启取消事务"]
+ D --> E["条件更新状态为 Cancelled:WHERE status = PendingPayment"]
+ E --> F{"订单类型?"}
+ F -- "普通订单" --> G1["回补普通库存:stock = stock + quantity"]
+ F -- "秒杀订单" --> G2["回补秒杀活动库存 + 释放买家限购额度"]
+ G1 --> H["记录 cancelled_at 和 cancel_reason = BUYER_CANCELLED"]
+ G2 --> H
+ H --> I["写入 Outbox:OrderCancelledIntegrationEvent"]
+ I --> J{"事务提交成功?"}
+ J -- "否" --> R["返回错误,不回补库存"]
+ J -- "是" --> K["返回取消成功"]
+```
+
+关键约束:
+
+- 只有 PendingPayment 状态可取消。
+- 使用条件更新 `WHERE status = 'PendingPayment'` 保证幂等。
+- 重复取消返回成功,不重复回补库存。
+- 取消事务回滚时库存不变化。
+
+## 六、与支付模块的协作(M05)
+
+```mermaid
+flowchart TD
+ PENDING["PendingPayment 订单"] --> PAY["M05 Payment:买家确认支付"]
+ PAY --> A{"余额充足?"}
+ A -- "否" --> X["提示余额不足,引导充值"]
+ A -- "是" --> B["开启支付事务"]
+ B --> C["扣减钱包余额"]
+ C --> D["写入 payment 记录"]
+ D --> E["更新订单状态为 Paid"]
+ E --> F["写入 Outbox:OrderPaidIntegrationEvent"]
+ F --> G{"事务提交成功?"}
+ G -- "否" --> R["余额回滚,订单保持 PendingPayment"]
+ G -- "是" --> H["返回支付成功"]
+ H --> I["Messaging 消费 OrderPaidIntegrationEvent,触发 M09 站内消息"]
+```
+
+关键约束:
+
+- 支付使用条件更新 `WHERE status = 'PendingPayment'` 保证幂等。
+- M05 与 M04 的状态更新共享同一 PendingPayment 条件,避免"又支付又取消"。
+- 支付成功后订单状态流转为 Paid,进入待发货阶段。
+- 订单状态由 M05 在支付事务内直接更新;事件只用于异步消息通知,不再次触发状态变更。
+
+## 七、与商家发货的协作(M06-02 / F12)
+
+```mermaid
+flowchart TD
+ PAID["Paid 订单"] --> SHIP["商家请求发货:orderId + 物流信息"]
+ SHIP --> A{"订单存在且 assignedMerchantUserId == currentUserId?"}
+ A -- "否" --> X["返回 404 或 403"]
+ A -- "是" --> B{"存在未完结售后申请锁定该订单行?"}
+ B -- "是" --> Y["返回 409:存在进行中售后,暂不允许发货"]
+ B -- "否" --> C{"订单状态为 Paid?"}
+ C -- "否" --> Z["返回 409:状态不允许发货"]
+ C -- "是" --> D["更新状态为 Shipped,记录 shipped_at、物流信息"]
+ D --> E["写入 Outbox:OrderShippedIntegrationEvent"]
+ E --> F{"事务提交成功?"}
+ F -- "否" --> R["返回错误"]
+ F -- "是" --> G["返回发货成功"]
+ G --> H["Messaging 消费 OrderShippedIntegrationEvent,触发 M09 站内消息"]
+```
+
+关键约束:
+
+- 商家只能操作 `assignedMerchantUserId == currentUserId` 的订单(单店 B2C 严格校验)。
+- 发货前须检查是否存在未完结的售后申请(AfterSales 锁定同一订单行)。
+- 发货使用条件更新 `WHERE status = 'Paid'` 保证幂等。
+- 重复发货返回成功,不重复变更状态。
+
+## 八、买家确认收货
+
+```mermaid
+flowchart TD
+ SHIPPED["Shipped 订单"] --> CONFIRM["买家请求确认收货:orderId"]
+ CONFIRM --> A{"订单存在且归属当前买家?"}
+ A -- "否" --> X["返回 404 或 403"]
+ A -- "是" --> B{"订单状态为 Shipped?"}
+ B -- "否" --> Y["返回 409:状态不允许确认"]
+ B -- "是" --> C["更新状态为 Completed,记录 completed_at 和 completed_by = BUYER_CONFIRMED"]
+ C --> D["写入 Outbox:OrderCompletedIntegrationEvent"]
+ D --> E{"事务提交成功?"}
+ E -- "否" --> R["返回错误"]
+ E -- "是" --> F["返回确认成功"]
+ F --> G["Messaging 消费 OrderCompletedIntegrationEvent,触发 M09 站内消息"]
+ G --> H["X01 开放评价入口(若已实现)"]
+```
+
+关键约束:
+
+- 只有 Shipped 状态可确认收货。
+- 确认收货后买家可对订单项进行评价(X01)。
+- 使用条件更新 `WHERE status = 'Shipped'` 保证幂等。
+
+## 九、异常、状态竞争与责任
+
+| 场景 | M04 处理 | 最终状态/责任 |
+|---|---|---|
+| 游客、商家、管理员访问买家订单接口 | 拒绝 | 401/403,不返回数据 |
+| 订单不存在或不属于买家 | 404/403 | 不泄露归属 |
+| 库存不足 | 整单拒绝 | 事务回滚,库存不扣减 |
+| 商品下架 | 整单拒绝 | 事务回滚 |
+| 地址无效或不归属 | 整单拒绝 | 事务回滚 |
+| 幂等键重复提交 | 返回首次成功结果 | 不重复扣库存,不重复创建订单 |
+| 支付时余额不足 | 支付失败 | 订单保持 PendingPayment |
+| 取消时订单已为 Cancelled | 条件更新影响行数=0,返回幂等成功 | 不重复取消,不重复回补库存 |
+| 取消时订单为 Paid/Shipped/Completed | 条件更新影响行数=0,返回 409 状态冲突 | 订单保持不变 |
+| 并发取消与支付 | 条件更新竞争,最终只有一个成功 | 不会出现"又支付又取消" |
+| 商家发货时状态已变更 | 条件更新影响行数=0,返回幂等成功 | 不重复变更 |
+| C03 超时取消与支付竞争 | 条件更新竞争,最终只有一个成功 | 不会出现矛盾状态 |
+
+## 十、由流程派生的接口映射
+
+| 已确认流程能力 | 当前派生接口 | 接口必须承载的业务结果 | 当前状态 |
+|---|---|---|---|
+| 提交订单(可选幂等) | A301 | 校验库存/地址/商品状态,原子扣减,创建订单快照,返回订单号和 PendingPayment | 待评审 |
+| 查询订单列表(分页+筛选) | A302 | 仅返回当前买家订单,按创建时间倒序 | 待评审 |
+| 查询订单详情 | A303 | 返回地址快照、订单项快照、状态时间线 | 待评审 |
+| 买家取消订单 | A304 | 条件更新状态为 Cancelled,回补库存,写入 cancelled_at | 待评审 |
+| 商家查询订单列表 | A305 | 仅返回与商家商品相关的订单 | 待评审 |
+| 商家查询订单详情 | A306 | 返回商家可见的订单信息 | 待评审 |
+| 商家发货 | A307 | 条件更新状态为 Shipped,记录物流信息 | 待评审 |
+| 买家确认收货 | A308 | 条件更新状态为 Completed,记录 completed_at | 待评审 |
+
+## 十一、扩展接入边界
+
+- C03 订单超时自动取消:复用取消事务逻辑,Worker 触发,不走买家主动接口;C03 复用 M04 的库存回补和状态变更逻辑。
+- X01 商品评价:Completed 状态后开放评价入口,评价模块消费 OrderCompletedIntegrationEvent。
+- M09 站内消息:消费 OrderCreatedIntegrationEvent、OrderCancelledIntegrationEvent、OrderShippedIntegrationEvent、OrderCompletedIntegrationEvent(由 Messaging 事件总线路由,不由 M05/M04 直接调用)。
+- M05 支付:在支付事务内更新订单状态为 Paid 并发布 OrderPaidIntegrationEvent;Messaging 事件总线消费事件后触发 M09 站内消息。
+
+## 十二、验收证据清单
+
+- [ ] 正常下单:返回订单号、PendingPayment 状态、订单总额
+- [ ] 库存不足:整单拒绝,库存不扣减
+- [ ] 商品下架:整单拒绝,库存不扣减
+- [ ] 地址无效:整单拒绝
+- [ ] 幂等键重复:返回首次成功结果,不重复扣库存
+- [ ] 订单列表:仅返回当前买家订单,分页正确
+- [ ] 订单详情:地址快照、订单项快照、状态时间线正确
+- [ ] 买家取消:状态变为 Cancelled,库存回补,站内消息通知
+- [ ] 重复取消:幂等成功,库存只回补一次
+- [ ] 已支付/已发货/已完成订单取消被拒绝(返回 409)
+- [ ] 商家发货:状态变为 Shipped
+- [ ] 重复发货:幂等成功
+- [ ] 买家确认收货:状态变为 Completed,站内消息通知
+- [ ] 支付与取消/发货竞争:条件更新保证最终只有一个成功
+- [ ] C03 超时取消:状态变为 Cancelled,库存回补,站内消息通知