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

9.0 KiB
Raw Blame History

订单支付系统功能总结

概述

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_idIoT 卡 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(小计金额,分)

索引设计

-- 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 文档生成验证

验证结果

编译验证

✅ go build ./... 编译通过

服务启动

✅ ./api 启动成功
✅ /health 健康检查通过

OpenAPI 文档

✅ /api/admin/orders 路由已生成
✅ /api/h5/orders 路由已生成
✅ /api/callback/wechat-pay 路由已生成
✅ /api/callback/alipay 路由已生成

测试通过率

✅ OrderStore 单元测试8/8 通过
✅ OrderItemStore 单元测试4/4 通过
✅ PurchaseValidationService 测试3/3 通过
✅ OrderService 测试6/6 通过

使用指南

创建订单(单卡购买)

请求

POST /api/h5/orders
Authorization: Bearer {token}
Content-Type: application/json

{
  "order_type": 1,
  "iot_card_id": 101,
  "package_ids": [201, 202]
}

响应

{
  "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"
}

钱包支付

请求

POST /api/h5/orders/1001/wallet-pay
Authorization: Bearer {token}
Content-Type: application/json

{
  "payment_method": 1
}

响应

{
  "code": 0,
  "msg": "支付成功"
}

查询订单列表

请求

GET /api/h5/orders?payment_status=2&page=1&page_size=20
Authorization: Bearer {token}

响应

{
  "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. 发票管理:支持开具电子发票

相关文档