Files
junhong_cmp_fiber/openspec/changes/fix-order-activation-idempotency/design.md
huang b02175271a
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m39s
feat: 实现企业设备授权功能并归档 OpenSpec 变更
- 新增企业设备授权模块(Model、DTO、Service、Handler、Store)
- 实现设备授权的创建、查询、更新、删除等完整业务逻辑
- 添加企业卡授权与设备授权的关联关系
- 新增 2 个数据库迁移脚本
- 同步 OpenSpec delta specs 到 main specs
- 归档 add-enterprise-device-authorization 变更
- 更新 API 文档和路由配置
- 新增完整的集成测试和单元测试覆盖
2026-01-29 13:18:49 +08:00

41 lines
1.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 订单激活幂等性修复 - 设计
## 目标
1. 同一订单被重复支付/重复回调/重复请求时,只会激活一次套餐使用记录。
2. 重复请求返回“幂等成功”(不报错,不重复激活)。
3. 避免因并发导致的重复插入。
## 方案
### 1) 以状态机作为幂等门闸
将订单支付状态从 `pending` 变更为 `paid` 时使用条件更新:
- `UPDATE tb_order SET payment_status=paid,... WHERE id=? AND payment_status=pending`
-`RowsAffected == 0`
- 视为订单已被处理(可能已支付/已取消/已退款)
- 对“已支付”场景直接返回成功(幂等成功)
- 对“非待支付且非已支付”场景返回对应业务错误(例如已取消不允许支付)
这样可以确保并发下只有一个请求能“拿到激活资格”。
### 2) 激活逻辑只在首次成功支付后执行
`activatePackage` 只在上述条件更新成功后执行;并确保激活过程内的数据读取使用同一个事务 `tx`(避免出现读取不一致或部分写入)。
### 3) 防御性约束(可选但推荐)
`tb_package_usage` 增加唯一约束(示例):
- 同一订单下,同一 `package_id` 只能有一条 usage
-`order_id + package_id` 为主(按当前业务:一个订单对应一个资源,且一次购买不应重复同套餐)
如果未来允许同订单同套餐多份购买,则需要同时引入 `quantity` 或 usage 的明细拆分策略,再调整唯一约束。
## 验收标准
- 重复调用钱包支付/支付回调接口,不会重复生成 `tb_package_usage` 记录。
- 幂等重复请求返回成功。
- 新增测试通过。