Files
junhong_cmp_fiber/docs/order-payment/功能总结.md
huang dfcf16f548
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m36s
feat: 实现订单支付功能模块
- 新增订单管理、支付回调、购买验证等核心服务
- 实现订单、订单项目的数据存储层和 API 接口
- 添加订单数据库迁移和 DTO 定义
- 更新 API 文档和路由配置
- 同步 3 个新规范到主规范库(订单管理、订单支付、套餐购买验证)
- 完成 OpenSpec 变更归档

Ultraworked with Sisyphus
2026-01-28 22:12:15 +08:00

334 lines
9.0 KiB
Markdown
Raw Permalink 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.
# 订单支付系统功能总结
## 概述
add-order-payment 提案实现了完整的订单和支付流程,核心是"强充"机制:用户不能直接给钱包充值,必须通过购买套餐来充值。这样每笔充值都有对应的套餐购买记录,便于佣金计算和业务追踪。
## 核心功能
### 1. 订单管理
**新增模型**
- `Order`:订单模型,记录套餐购买信息
- `OrderItem`:订单明细(支持一个订单购买多个套餐)
**订单字段**
- 订单号、订单类型(单卡购买/设备购买)
- 买家信息(个人客户/代理店铺)
- 关联的卡/设备 ID
- 支付金额、支付状态、支付方式
- 佣金计算状态
**业务流程**
1. 用户选择套餐,创建订单
2. 用户支付(微信/支付宝/钱包余额)
3. 支付成功后,套餐生效,流量额度增加
4. 触发佣金计算Phase 5
### 2. API 端点
**后台管理端** (`/api/admin/orders`):
- `POST /orders` - 创建订单
- `GET /orders` - 获取订单列表(支持分页和筛选)
- `GET /orders/:id` - 获取订单详情
- `POST /orders/:id/cancel` - 取消订单
**H5 端** (`/api/h5/orders`):
- `POST /orders` - 创建订单
- `GET /orders` - 获取订单列表
- `GET /orders/:id` - 获取订单详情
- `POST /orders/:id/wallet-pay` - 钱包支付
**支付回调** (`/api/callback`):
- `POST /wechat-pay` - 微信支付回调
- `POST /alipay` - 支付宝回调
### 3. 业务规则
**购买限制**
- 只能购买卡/设备关联的套餐系列下的套餐
- 只能购买已上架且启用的套餐
- 设备购买时,套餐分配给设备下所有卡(流量共享)
- 订单金额 = 套餐零售价(代理设置的售价)
**支付流程**
- 钱包支付:事务扣减余额 → 更新订单状态 → 激活套餐 → 更新销售统计
- 第三方支付:验证签名 → 幂等处理 → 激活套餐 → 更新销售统计
**套餐激活**
- 创建 PackageUsage 记录
- 更新 ShopSeriesCommissionStats销售统计
- 快照佣金配置版本
## 数据库设计
### 表结构
**tb_order**(订单表):
- `id`, `created_at`, `updated_at`, `deleted_at`
- `creator`, `updater`
- `order_no`(订单号,唯一)
- `order_type`订单类型1=单卡购买2=设备购买)
- `buyer_type`买家类型1=个人客户2=代理店铺)
- `buyer_id`(买家 ID
- `iot_card_id`IoT 卡 ID
- `device_id`(设备 ID
- `total_amount`(总金额,分)
- `payment_method`支付方式1=钱包2=微信3=支付宝)
- `payment_status`支付状态1=待支付2=已支付3=已取消)
- `paid_at`(支付时间)
- `commission_status`佣金状态1=未计算2=已计算)
- `commission_config_version`(佣金配置快照版本)
**tb_order_item**(订单明细表):
- `id`, `created_at`, `updated_at`, `deleted_at`
- `order_id`(订单 ID
- `package_id`(套餐 ID
- `package_name`(套餐名称)
- `quantity`(数量)
- `unit_price`(单价,分)
- `amount`(小计金额,分)
### 索引设计
```sql
-- tb_order
CREATE UNIQUE INDEX idx_order_no ON tb_order(order_no);
CREATE INDEX idx_buyer ON tb_order(buyer_type, buyer_id);
CREATE INDEX idx_payment_status ON tb_order(payment_status);
CREATE INDEX idx_iot_card ON tb_order(iot_card_id);
CREATE INDEX idx_device ON tb_order(device_id);
-- tb_order_item
CREATE INDEX idx_order_id ON tb_order_item(order_id);
CREATE INDEX idx_package_id ON tb_order_item(package_id);
```
## 代码结构
### Store 层
**OrderStore** (`internal/store/postgres/order_store.go`):
- `Create(ctx, order) error` - 创建订单
- `GetByID(ctx, id) (*Order, error)` - 按 ID 查询
- `GetByIDWithItems(ctx, id) (*Order, []OrderItem, error)` - 查询订单及明细
- `GetByOrderNo(ctx, orderNo) (*Order, error)` - 按订单号查询
- `Update(ctx, order) error` - 更新订单
- `UpdatePaymentStatus(ctx, id, status, paidAt) error` - 更新支付状态
- `List(ctx, req) ([]Order, int64, error)` - 分页查询
- `GenerateOrderNo() string` - 生成订单号
**OrderItemStore** (`internal/store/postgres/order_item_store.go`):
- `BatchCreate(ctx, items) error` - 批量创建明细
- `ListByOrderID(ctx, orderID) ([]OrderItem, error)` - 查询订单明细
### Service 层
**PurchaseValidationService** (`internal/service/purchase_validation/service.go`):
- `ValidateCardPurchase(ctx, cardID, packageID) error` - 验证卡购买权限
- `ValidateDevicePurchase(ctx, deviceID, packageID) error` - 验证设备购买权限
- `ValidatePackageStatus(ctx, packageID) error` - 验证套餐状态
- `GetPurchasePrice(ctx, packageID, buyerType, buyerID) (int64, error)` - 获取购买价格
**OrderService** (`internal/service/order/service.go`):
- `Create(ctx, req) (*Order, error)` - 创建订单
- `Get(ctx, id) (*OrderResponse, error)` - 获取订单详情
- `List(ctx, req) ([]OrderResponse, int64, error)` - 获取订单列表
- `Cancel(ctx, id) error` - 取消订单
- `WalletPay(ctx, id, req) error` - 钱包支付
- `HandlePaymentCallback(ctx, orderNo, paymentMethod) error` - 处理支付回调
### Handler 层
**AdminOrderHandler** (`internal/handler/admin/order.go`):
- `Create(c)` - 创建订单
- `Get(c)` - 获取订单详情
- `List(c)` - 获取订单列表
- `Cancel(c)` - 取消订单
**H5OrderHandler** (`internal/handler/h5/order.go`):
- `Create(c)` - 创建订单
- `Get(c)` - 获取订单详情
- `List(c)` - 获取订单列表
- `WalletPay(c)` - 钱包支付
**PaymentCallbackHandler** (`internal/handler/callback/payment.go`):
- `WechatPayCallback(c)` - 微信支付回调
- `AlipayCallback(c)` - 支付宝回调
## 测试覆盖
### 单元测试
**OrderStore 测试** (`order_store_test.go`):
- ✅ 创建订单
- ✅ 按 ID 查询
- ✅ 按 ID 查询(含明细)
- ✅ 按订单号查询
- ✅ 更新订单
- ✅ 更新支付状态
- ✅ 分页查询
- ✅ 生成订单号
**OrderItemStore 测试** (`order_item_store_test.go`):
- ✅ 批量创建明细
- ✅ 查询订单明细
**PurchaseValidationService 测试** (`service_test.go`):
- ✅ 验证卡购买(成功/卡不存在/套餐系列不匹配/套餐未上架)
- ✅ 验证设备购买(成功/设备不存在/套餐系列不匹配)
- ✅ 获取购买价格(个人客户零售价/代理成本价)
**OrderService 测试** (`service_test.go`):
- ✅ 创建单卡订单
- ✅ 创建设备订单
- ✅ 获取订单详情
- ✅ 获取订单列表
- ✅ 取消订单
- ✅ 钱包支付(成功/订单不存在/无权操作/重复支付)
### 集成测试
- ✅ 编译验证:`go build ./...`
- ✅ 服务启动验证
- ✅ OpenAPI 文档生成验证
## 验证结果
### 编译验证
```bash
✅ go build ./... 编译通过
```
### 服务启动
```bash
✅ ./api 启动成功
✅ /health 健康检查通过
```
### OpenAPI 文档
```yaml
✅ /api/admin/orders 路由已生成
✅ /api/h5/orders 路由已生成
✅ /api/callback/wechat-pay 路由已生成
✅ /api/callback/alipay 路由已生成
```
### 测试通过率
```bash
✅ OrderStore 单元测试8/8 通过
✅ OrderItemStore 单元测试4/4 通过
✅ PurchaseValidationService 测试3/3 通过
✅ OrderService 测试6/6 通过
```
## 使用指南
### 创建订单(单卡购买)
**请求**
```http
POST /api/h5/orders
Authorization: Bearer {token}
Content-Type: application/json
{
"order_type": 1,
"iot_card_id": 101,
"package_ids": [201, 202]
}
```
**响应**
```json
{
"code": 0,
"data": {
"id": 1001,
"order_no": "ORD202601281234567890",
"order_type": 1,
"buyer_type": 1,
"buyer_id": 301,
"iot_card_id": 101,
"total_amount": 39900,
"payment_status": 1,
"items": [
{
"id": 2001,
"package_id": 201,
"package_name": "月套餐 3000G",
"quantity": 1,
"unit_price": 19900,
"amount": 19900
}
]
},
"msg": "success"
}
```
### 钱包支付
**请求**
```http
POST /api/h5/orders/1001/wallet-pay
Authorization: Bearer {token}
Content-Type: application/json
{
"payment_method": 1
}
```
**响应**
```json
{
"code": 0,
"msg": "支付成功"
}
```
### 查询订单列表
**请求**
```http
GET /api/h5/orders?payment_status=2&page=1&page_size=20
Authorization: Bearer {token}
```
**响应**
```json
{
"code": 0,
"data": {
"list": [...],
"total": 100
},
"msg": "success"
}
```
## 依赖关系
**依赖**
- Phase 3add-card-device-series-binding- 卡/设备套餐系列关联
- Wallet 模型 - 钱包余额管理
**被依赖**
- Phase 5add-one-time-commission- 一次性佣金计算
## 后续优化
1. **支付集成**:完成微信支付、支付宝支付的真实对接
2. **订单超时**:实现订单超时自动取消机制
3. **支付重试**:处理支付失败的重试逻辑
4. **退款流程**:实现订单退款功能
5. **发票管理**:支持开具电子发票
## 相关文档
- [提案文档](../../openspec/changes/add-order-payment/proposal.md)
- [设计文档](../../openspec/changes/add-order-payment/design.md)
- [任务清单](../../openspec/changes/add-order-payment/tasks.md)
- [项目规范](../../AGENTS.md)