支付集成.md 19 KB

支付集成

本文引用的文件

  • 支付集成指南.md
  • payment.service.ts
  • payment.controller.ts
  • subscription.service.ts
  • subscription.controller.ts
  • index.vue(会员中心)
  • index.vue(支付确认)
  • index.vue(支付结果)
  • 订单列表页
  • 20260422105352_add_content_status/migration.sql

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本技术文档面向“支付集成系统”,围绕支付宝与微信支付两大第三方支付网关,系统化阐述从 SDK 配置、API 调用流程、订单创建、参数设置、回调通知处理到支付状态同步机制的完整实现;同时覆盖支付安全策略(签名验证、防重放)、数据加密传输、支付金额计算、Token 扣减、退款处理、支付监控与对账、风控与合规要点。文档以仓库现有代码与文档为依据,提供可操作的集成指引与可视化流程图。

项目结构

支付相关能力由后端 Koa 路由与服务层、前端 UniApp 页面以及 Prisma 数据模型共同构成,形成“前端交互—后端支付—第三方网关—状态回推”的闭环。

graph TB
subgraph "前端UniApp"
FE_Member["会员中心<br/>选择套餐"]
FE_Confirm["支付确认<br/>选择支付方式"]
FE_Result["支付结果<br/>展示状态"]
FE_Orders["订单列表<br/>查询与轮询"]
end
subgraph "后端Koa"
C_Payment["payment.controller.ts<br/>路由与鉴权"]
S_Payment["payment.service.ts<br/>订单/回调/激活订阅"]
C_Sub["subscription.controller.ts<br/>Token/配额API"]
S_Sub["subscription.service.ts<br/>Token/音频时长计费"]
end
subgraph "数据库Prisma"
M_Order["Order<br/>支付订单"]
M_SubPlan["SubscriptionPlan<br/>套餐计划"]
M_Sub["Subscription<br/>订阅记录"]
M_TB["TokenBalance<br/>Token余额"]
M_TU["TokenUsage<br/>Token使用记录"]
end
subgraph "第三方支付"
Ali["支付宝"]
Wx["微信支付"]
end
FE_Member --> FE_Confirm --> FE_Result
FE_Confirm --> C_Payment --> S_Payment
C_Payment --> S_Payment
S_Payment --> Ali
S_Payment --> Wx
S_Payment --> M_Order
S_Payment --> M_Sub
S_Payment --> M_TB
S_Payment --> M_TU
C_Sub --> S_Sub
S_Sub --> M_SubPlan
S_Sub --> M_Sub
S_Sub --> M_TB
S_Sub --> M_TU
FE_Orders --> C_Payment

图表来源

  • payment.controller.ts:1-258
  • payment.service.ts:1-578
  • subscription.controller.ts:1-191
  • subscription.service.ts:1-938
  • 20260422105352_add_content_status/migration.sql:270-301

章节来源

  • payment.controller.ts:1-258
  • payment.service.ts:1-578
  • subscription.controller.ts:1-191
  • subscription.service.ts:1-938
  • 20260422105352_add_content_status/migration.sql:270-301

核心组件

  • 支付控制器(payment.controller.ts):负责接收前端请求、鉴权、路由分发至支付服务,并处理支付宝/微信回调。
  • 支付服务(payment.service.ts):封装订单创建、支付参数生成、回调签名验证、支付状态处理与订阅激活。
  • 订阅控制器(subscription.controller.ts):提供套餐查询、用户订阅、Token 余额与使用记录等 API。
  • 订阅服务(subscription.service.ts):实现 Token 与音频时长的计费模型、配额检查与扣减。
  • 前端页面:会员中心选择套餐、支付确认页选择支付方式并跳转、支付结果页展示状态、订单列表页查询与轮询。
  • 数据模型:Order、SubscriptionPlan、Subscription、TokenBalance、TokenUsage。

章节来源

  • payment.controller.ts:1-258
  • payment.service.ts:1-578
  • subscription.controller.ts:1-191
  • subscription.service.ts:1-938

架构总览

支付系统采用“前端发起—后端统一下单—第三方支付—异步回调—后端状态同步—订阅激活”的模式,确保支付安全与幂等处理。

sequenceDiagram
participant U as "用户"
participant FE as "前端页面"
participant PC as "支付控制器"
participant PS as "支付服务"
participant GW as "第三方支付网关"
participant DB as "数据库"
U->>FE : 选择套餐/支付方式
FE->>PC : POST /payment/create
PC->>PS : 创建订单并生成支付参数
PS->>GW : 调用支付接口支付宝/微信
GW-->>PS : 返回支付链接/二维码
PS-->>PC : 返回支付信息
PC-->>FE : 返回订单号/支付URL/二维码
FE->>GW : 跳转/扫码支付
GW-->>PC : 异步回调notify
PC->>PS : 验证签名/处理回调
PS->>DB : 更新订单状态/激活订阅/更新Token
PS-->>PC : 处理结果
PC-->>GW : 返回成功/失败

图表来源

  • payment.controller.ts:9-33
  • payment.service.ts:121-191
  • payment.service.ts:358-406

详细组件分析

支付服务(订单创建与支付参数生成)

  • 订单创建:根据套餐 ID 与支付方式生成唯一订单号,写入 Order 表,状态 pending。
  • 支付参数生成:
    • 支付宝:根据是否生产环境决定沙箱/正式网关,返回支付 URL。
    • 微信:调用 Native 支付接口,返回二维码链接;若未配置则返回模拟链接。
  • 支付宝扫码:提供当面付预下单接口生成二维码链接。
  • 订单轮询:前端轮询 /payment/orders/:orderNo 获取支付状态。

    flowchart TD
    Start(["创建支付订单"]) --> LoadPlan["查询套餐信息"]
    LoadPlan --> GenOrderNo["生成订单号"]
    GenOrderNo --> CreateOrder["写入订单记录<br/>状态=pending"]
    CreateOrder --> ChoosePay{"支付方式?"}
    ChoosePay --> |支付宝| Alipay["生成支付宝支付URL"]
    ChoosePay --> |微信| Wechat["生成微信支付二维码"]
    Alipay --> Return["返回支付URL/二维码"]
    Wechat --> Return
    Return --> End(["前端跳转/扫码"])
    

图表来源

  • payment.service.ts:121-191
  • payment.service.ts:193-243
  • payment.service.ts:245-295

章节来源

  • payment.service.ts:121-191
  • payment.service.ts:193-243
  • payment.service.ts:245-295

支付回调与状态同步

  • 支付宝回调:
    • 异步通知:校验签名,根据 trade_status 判断成功/失败,调用回调处理器。
    • 同步返回:校验签名后重定向到结果页,携带状态参数。
  • 微信回调:
    • 异步通知:解析回调参数,根据 trade_state 判断成功/失败,调用回调处理器。
  • 回调处理器:

    • 校验订单存在与状态,防止重复处理;
    • 支付成功:更新订单状态为 paid,激活订阅,更新用户会员等级与 Token 余额;
    • 支付失败:更新订单状态为 failed。

      sequenceDiagram
      participant GW as "第三方网关"
      participant PC as "支付控制器"
      participant PS as "支付服务"
      participant DB as "数据库"
      GW->>PC : POST /payment/{alipay|wechat}/notify
      PC->>PS : verifyAlipaySign()/解析参数
      alt 支付宝
      PS->>PS : TRADE_SUCCESS/TRADE_FINISHED
      else 其他状态
      PS->>PS : 标记失败
      end
      PS->>DB : 更新订单/订阅/Token
      PS-->>PC : 处理结果
      PC-->>GW : SUCCESS/FAIL
      

图表来源

  • payment.controller.ts:57-95
  • payment.controller.ts:127-149
  • payment.service.ts:340-356
  • payment.service.ts:358-406

章节来源

  • payment.controller.ts:57-95
  • payment.controller.ts:97-125
  • payment.controller.ts:127-149
  • payment.service.ts:340-356
  • payment.service.ts:358-406

订阅激活与 Token 余额更新

  • 若存在有效订阅,则续期 30 天;否则新建订阅,有效期 30 天。
  • 更新用户会员等级与到期时间。
  • 根据套餐配置更新 Token 余额:有配额则按月重置,无配额则标记无限额。

    flowchart TD
    A["收到支付成功回调"] --> B["查询订单与套餐"]
    B --> C{"是否存在有效订阅?"}
    C --> |是| D["续期30天"]
    C --> |否| E["创建新订阅30天"]
    D --> F["更新用户会员等级/到期时间"]
    E --> F
    F --> G{"套餐是否有月Token配额?"}
    G --> |是| H["更新/创建Token余额并设置重置日期"]
    G --> |否| I["设置无限额"]
    H --> J["结束"]
    I --> J
    

图表来源

  • payment.service.ts:408-509

章节来源

  • payment.service.ts:408-509

前端支付流程

  • 会员中心:展示套餐与 Token 余额,选择套餐。
  • 支付确认:选择支付方式(支付宝/微信),创建订单并跳转或显示二维码。
  • 支付结果:展示支付成功/失败/待支付状态。
  • 订单列表:查询历史订单与使用记录。

    sequenceDiagram
    participant U as "用户"
    participant FE_M as "会员中心"
    participant FE_C as "支付确认"
    participant FE_R as "支付结果"
    participant PC as "支付控制器"
    participant PS as "支付服务"
    U->>FE_M : 选择套餐
    U->>FE_C : 确认支付选择方式
    FE_C->>PC : POST /payment/create
    PC->>PS : 创建订单/生成支付参数
    PS-->>PC : 返回支付URL/二维码
    PC-->>FE_C : 返回结果
    FE_C->>U : 跳转/显示二维码
    U->>FE_R : 查看支付结果
    

图表来源

  • index.vue(会员中心):1-36
  • index.vue(支付确认):113-181
  • index.vue(支付结果):74-119
  • payment.controller.ts:9-33

章节来源

  • index.vue(会员中心):1-36
  • index.vue(支付确认):113-181
  • index.vue(支付结果):74-119
  • payment.controller.ts:9-33

数据模型与对账

  • 订单与订阅:Order、Subscription、SubscriptionPlan。
  • Token 体系:TokenBalance、TokenUsage。
  • 对账思路:以第三方回调为准,核对订单状态与金额一致性;若失败则人工介入重试或退款。

    erDiagram
    SUBSCRIPTION_PLAN {
    int id PK
    string name
    int level
    decimal priceMonthly
    decimal priceYearly
    int monthlyTokens
    int yearlyTokens
    string features
    }
    ORDER {
    int id PK
    int userId
    string orderNo UK
    int planId
    string productType
    decimal amount
    string status
    string paymentMethod
    datetime createdAt
    datetime updatedAt
    }
    SUBSCRIPTION {
    int id PK
    int userId
    int planId
    datetime startDate
    datetime endDate
    string status
    boolean autoRenew
    }
    TOKEN_BALANCE {
    int id PK
    int userId UK
    int totalTokens
    int usedTokens
    datetime resetDate
    }
    TOKEN_USAGE {
    int id PK
    int userId
    string type
    int amount
    int contentLength
    int orderId
    string description
    datetime createdAt
    }
    ORDER }o--|| SUBSCRIPTION_PLAN : "planId"
    ORDER }o--o| SUBSCRIPTION : "planId"
    TOKEN_USAGE }o--|| ORDER : "orderId"
    

图表来源

  • 20260422105352_add_content_status/migration.sql:270-301

章节来源

  • 20260422105352_add_content_status/migration.sql:270-301

依赖分析

  • 支付服务依赖:
    • 支付宝 SDK(按需懒加载)与微信支付 SDK(CommonJS require)。
    • 环境变量:ALIPAY*、WECHAT*、BASE_URL、ALIPAY_RETURN_URL 等。
    • 数据库:Prisma 访问 Order、Subscription、TokenBalance、TokenUsage。
  • 控制器依赖:
    • 认证中间件(authMiddleware)保护敏感接口。
    • 错误处理中间件(BadRequestError)规范错误响应。
  • 前端依赖:

    • 请求工具封装(post/get),统一处理加载态与错误提示。
    • 页面间参数传递(订单号、金额、套餐名、二维码)。

      graph LR
      PS["payment.service.ts"] --> ENV["环境变量"]
      PS --> PRISMA["Prisma Models"]
      PS --> ALI["alipay-sdk"]
      PS --> WX["wechatpay-node-v3"]
      PC["payment.controller.ts"] --> PS
      PC --> AUTH["authMiddleware"]
      PC --> ERR["errorHandler"]
      FE_Confirm["payment-confirm/index.vue"] --> PC
      FE_Result["payment-result/index.vue"] --> PC
      FE_Orders["orders/index.vue"] --> PC
      

图表来源

  • payment.service.ts:1-29
  • payment.controller.ts:1-7
  • index.vue(支付确认):80-140
  • index.vue(支付结果):74-119
  • 订单列表页:148-161

章节来源

  • payment.service.ts:1-29
  • payment.controller.ts:1-7
  • index.vue(支付确认):80-140
  • index.vue(支付结果):74-119
  • 订单列表页:148-161

性能考虑

  • SDK 懒加载:避免 ESM/CJS 兼容性问题,仅在首次使用时加载。
  • 异步回调:回调处理应快速返回,业务逻辑异步落库,避免阻塞网关。
  • 轮询策略:前端轮询间隔与超时时间需平衡实时性与资源消耗。
  • 数据库索引:订单号、用户与状态组合索引有助于查询与对账。

故障排查指南

  • 签名验证失败:
    • 支付宝:检查回调参数与 SDK 签名验证方法;确认回调地址与公钥配置。
    • 微信:确认回调 XML 解析与签名流程。
  • 未配置支付参数:
    • 支付宝:检查 ALIPAY_APP_ID、ALIPAY_PRIVATE_KEY、ALIPAY_PUBLIC_KEY、ALIPAY_NOTIFY_URL。
    • 微信:检查 WECHAT_APP_ID、WECHAT_MCH_ID、WECHAT_SERIAL_NO、WECHAT_APIV3_KEY、证书文件。
  • 回调未触发:
    • 确认外网可访问的 HTTPS 回调地址;检查防火墙与域名解析。
  • 订单重复处理:
    • 回调处理器已判断订单状态,避免重复更新;必要时引入幂等键。
  • 微信证书问题:
    • 私钥/公钥 DER 编码导出与 SDK 初始化一致;证书路径与权限正确。

章节来源

  • payment.controller.ts:57-95
  • payment.controller.ts:127-149
  • payment.service.ts:40-66
  • payment.service.ts:68-119

结论

该支付集成系统以清晰的前后端职责划分与严谨的回调处理机制,实现了支付宝与微信支付的统一封装与订阅激活、Token 余额更新的自动化闭环。建议在生产环境中完善真实支付网关配置、强化安全校验与监控告警,并持续优化对账与风控策略。

附录

支付金额计算与扣减

  • 套餐价格:以套餐月付价格为基准,单位元。
  • Token 扣减:消费时检查余额,不足则拒绝;成功后记录使用明细。
  • 音频时长计费:按字数估算分钟数,结合套餐配额与超额单价计算费用。

章节来源

  • subscription.service.ts:517-600
  • subscription.service.ts:410-450

退款与状态同步

  • 退款流程:用户申请—后台审核—调用第三方退款 API—更新订单与订阅状态。
  • 状态同步:以第三方回调为准,本地仅做幂等与补偿处理。

章节来源

  • 支付集成指南.md:388-391

安全策略与合规

  • 回调签名验证:严格校验第三方回调签名。
  • HTTPS 与白名单:回调地址使用 HTTPS;限制回调来源 IP。
  • 防重放与幂等:订单状态与幂等键控制重复处理。
  • 数据加密:敏感信息(证书、密钥)通过环境变量与只读文件管理。

章节来源

  • 支付集成指南.md:376-383