# 支付集成

<cite>
**本文引用的文件**   
- [支付集成指南.md](file://docs/支付集成指南.md)
- [payment.service.ts](file://server/src/modules/payment/payment.service.ts)
- [payment.controller.ts](file://server/src/modules/payment/payment.controller.ts)
- [subscription.service.ts](file://server/src/modules/subscription/subscription.service.ts)
- [subscription.controller.ts](file://server/src/modules/subscription/subscription.controller.ts)
- [index.vue（会员中心）](file://my-uniapp-vue3/src/pages/member/index.vue)
- [index.vue（支付确认）](file://my-uniapp-vue3/src/pages/payment-confirm/index.vue)
- [index.vue（支付结果）](file://my-uniapp-vue3/src/pages/payment-result/index.vue)
- [订单列表页](file://my-uniapp-vue3/src/pages/orders/index.vue)
- [20260422105352_add_content_status/migration.sql](file://server/prisma/migrations/20260422105352_add_content_status/migration.sql)
</cite>

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

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

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

```mermaid
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](file://server/src/modules/payment/payment.controller.ts#L1-L258)
- [payment.service.ts:1-578](file://server/src/modules/payment/payment.service.ts#L1-L578)
- [subscription.controller.ts:1-191](file://server/src/modules/subscription/subscription.controller.ts#L1-L191)
- [subscription.service.ts:1-938](file://server/src/modules/subscription/subscription.service.ts#L1-L938)
- [20260422105352_add_content_status/migration.sql:270-301](file://server/prisma/migrations/20260422105352_add_content_status/migration.sql#L270-L301)

章节来源
- [payment.controller.ts:1-258](file://server/src/modules/payment/payment.controller.ts#L1-L258)
- [payment.service.ts:1-578](file://server/src/modules/payment/payment.service.ts#L1-L578)
- [subscription.controller.ts:1-191](file://server/src/modules/subscription/subscription.controller.ts#L1-L191)
- [subscription.service.ts:1-938](file://server/src/modules/subscription/subscription.service.ts#L1-L938)
- [20260422105352_add_content_status/migration.sql:270-301](file://server/prisma/migrations/20260422105352_add_content_status/migration.sql#L270-L301)

## 核心组件
- 支付控制器（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](file://server/src/modules/payment/payment.controller.ts#L1-L258)
- [payment.service.ts:1-578](file://server/src/modules/payment/payment.service.ts#L1-L578)
- [subscription.controller.ts:1-191](file://server/src/modules/subscription/subscription.controller.ts#L1-L191)
- [subscription.service.ts:1-938](file://server/src/modules/subscription/subscription.service.ts#L1-L938)

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

```mermaid
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](file://server/src/modules/payment/payment.controller.ts#L9-L33)
- [payment.service.ts:121-191](file://server/src/modules/payment/payment.service.ts#L121-L191)
- [payment.service.ts:358-406](file://server/src/modules/payment/payment.service.ts#L358-L406)

## 详细组件分析

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

```mermaid
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](file://server/src/modules/payment/payment.service.ts#L121-L191)
- [payment.service.ts:193-243](file://server/src/modules/payment/payment.service.ts#L193-L243)
- [payment.service.ts:245-295](file://server/src/modules/payment/payment.service.ts#L245-L295)

章节来源
- [payment.service.ts:121-191](file://server/src/modules/payment/payment.service.ts#L121-L191)
- [payment.service.ts:193-243](file://server/src/modules/payment/payment.service.ts#L193-L243)
- [payment.service.ts:245-295](file://server/src/modules/payment/payment.service.ts#L245-L295)

### 支付回调与状态同步
- 支付宝回调：
  - 异步通知：校验签名，根据 trade_status 判断成功/失败，调用回调处理器。
  - 同步返回：校验签名后重定向到结果页，携带状态参数。
- 微信回调：
  - 异步通知：解析回调参数，根据 trade_state 判断成功/失败，调用回调处理器。
- 回调处理器：
  - 校验订单存在与状态，防止重复处理；
  - 支付成功：更新订单状态为 paid，激活订阅，更新用户会员等级与 Token 余额；
  - 支付失败：更新订单状态为 failed。

```mermaid
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](file://server/src/modules/payment/payment.controller.ts#L57-L95)
- [payment.controller.ts:127-149](file://server/src/modules/payment/payment.controller.ts#L127-L149)
- [payment.service.ts:340-356](file://server/src/modules/payment/payment.service.ts#L340-L356)
- [payment.service.ts:358-406](file://server/src/modules/payment/payment.service.ts#L358-L406)

章节来源
- [payment.controller.ts:57-95](file://server/src/modules/payment/payment.controller.ts#L57-L95)
- [payment.controller.ts:97-125](file://server/src/modules/payment/payment.controller.ts#L97-L125)
- [payment.controller.ts:127-149](file://server/src/modules/payment/payment.controller.ts#L127-L149)
- [payment.service.ts:340-356](file://server/src/modules/payment/payment.service.ts#L340-L356)
- [payment.service.ts:358-406](file://server/src/modules/payment/payment.service.ts#L358-L406)

### 订阅激活与 Token 余额更新
- 若存在有效订阅，则续期 30 天；否则新建订阅，有效期 30 天。
- 更新用户会员等级与到期时间。
- 根据套餐配置更新 Token 余额：有配额则按月重置，无配额则标记无限额。

```mermaid
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](file://server/src/modules/payment/payment.service.ts#L408-L509)

章节来源
- [payment.service.ts:408-509](file://server/src/modules/payment/payment.service.ts#L408-L509)

### 前端支付流程
- 会员中心：展示套餐与 Token 余额，选择套餐。
- 支付确认：选择支付方式（支付宝/微信），创建订单并跳转或显示二维码。
- 支付结果：展示支付成功/失败/待支付状态。
- 订单列表：查询历史订单与使用记录。

```mermaid
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](file://my-uniapp-vue3/src/pages/member/index.vue#L1-L36)
- [index.vue（支付确认）:113-181](file://my-uniapp-vue3/src/pages/payment-confirm/index.vue#L113-L181)
- [index.vue（支付结果）:74-119](file://my-uniapp-vue3/src/pages/payment-result/index.vue#L74-L119)
- [payment.controller.ts:9-33](file://server/src/modules/payment/payment.controller.ts#L9-L33)

章节来源
- [index.vue（会员中心）:1-36](file://my-uniapp-vue3/src/pages/member/index.vue#L1-L36)
- [index.vue（支付确认）:113-181](file://my-uniapp-vue3/src/pages/payment-confirm/index.vue#L113-L181)
- [index.vue（支付结果）:74-119](file://my-uniapp-vue3/src/pages/payment-result/index.vue#L74-L119)
- [payment.controller.ts:9-33](file://server/src/modules/payment/payment.controller.ts#L9-L33)

### 数据模型与对账
- 订单与订阅：Order、Subscription、SubscriptionPlan。
- Token 体系：TokenBalance、TokenUsage。
- 对账思路：以第三方回调为准，核对订单状态与金额一致性；若失败则人工介入重试或退款。

```mermaid
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](file://server/prisma/migrations/20260422105352_add_content_status/migration.sql#L270-L301)

章节来源
- [20260422105352_add_content_status/migration.sql:270-301](file://server/prisma/migrations/20260422105352_add_content_status/migration.sql#L270-L301)

## 依赖分析
- 支付服务依赖：
  - 支付宝 SDK（按需懒加载）与微信支付 SDK（CommonJS require）。
  - 环境变量：ALIPAY_*、WECHAT_*、BASE_URL、ALIPAY_RETURN_URL 等。
  - 数据库：Prisma 访问 Order、Subscription、TokenBalance、TokenUsage。
- 控制器依赖：
  - 认证中间件（authMiddleware）保护敏感接口。
  - 错误处理中间件（BadRequestError）规范错误响应。
- 前端依赖：
  - 请求工具封装（post/get），统一处理加载态与错误提示。
  - 页面间参数传递（订单号、金额、套餐名、二维码）。

```mermaid
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](file://server/src/modules/payment/payment.service.ts#L1-L29)
- [payment.controller.ts:1-7](file://server/src/modules/payment/payment.controller.ts#L1-L7)
- [index.vue（支付确认）:80-140](file://my-uniapp-vue3/src/pages/payment-confirm/index.vue#L80-L140)
- [index.vue（支付结果）:74-119](file://my-uniapp-vue3/src/pages/payment-result/index.vue#L74-L119)
- [订单列表页:148-161](file://my-uniapp-vue3/src/pages/orders/index.vue#L148-L161)

章节来源
- [payment.service.ts:1-29](file://server/src/modules/payment/payment.service.ts#L1-L29)
- [payment.controller.ts:1-7](file://server/src/modules/payment/payment.controller.ts#L1-L7)
- [index.vue（支付确认）:80-140](file://my-uniapp-vue3/src/pages/payment-confirm/index.vue#L80-L140)
- [index.vue（支付结果）:74-119](file://my-uniapp-vue3/src/pages/payment-result/index.vue#L74-L119)
- [订单列表页:148-161](file://my-uniapp-vue3/src/pages/orders/index.vue#L148-L161)

## 性能考虑
- 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](file://server/src/modules/payment/payment.controller.ts#L57-L95)
- [payment.controller.ts:127-149](file://server/src/modules/payment/payment.controller.ts#L127-L149)
- [payment.service.ts:40-66](file://server/src/modules/payment/payment.service.ts#L40-L66)
- [payment.service.ts:68-119](file://server/src/modules/payment/payment.service.ts#L68-L119)

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

## 附录

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

章节来源
- [subscription.service.ts:517-600](file://server/src/modules/subscription/subscription.service.ts#L517-L600)
- [subscription.service.ts:410-450](file://server/src/modules/subscription/subscription.service.ts#L410-L450)

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

章节来源
- [支付集成指南.md:388-391](file://docs/支付集成指南.md#L388-L391)

### 安全策略与合规
- 回调签名验证：严格校验第三方回调签名。
- HTTPS 与白名单：回调地址使用 HTTPS；限制回调来源 IP。
- 防重放与幂等：订单状态与幂等键控制重复处理。
- 数据加密：敏感信息（证书、密钥）通过环境变量与只读文件管理。

章节来源
- [支付集成指南.md:376-383](file://docs/支付集成指南.md#L376-L383)