# 订单支付系统功能总结 ## 概述 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 3(add-card-device-series-binding)- 卡/设备套餐系列关联 - Wallet 模型 - 钱包余额管理 **被依赖**: - Phase 5(add-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)