# 支付集成
**本文引用的文件**
- [支付集成指南.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)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本技术文档面向“支付集成系统”,围绕支付宝与微信支付两大第三方支付网关,系统化阐述从 SDK 配置、API 调用流程、订单创建、参数设置、回调通知处理到支付状态同步机制的完整实现;同时覆盖支付安全策略(签名验证、防重放)、数据加密传输、支付金额计算、Token 扣减、退款处理、支付监控与对账、风控与合规要点。文档以仓库现有代码与文档为依据,提供可操作的集成指引与可视化流程图。
## 项目结构
支付相关能力由后端 Koa 路由与服务层、前端 UniApp 页面以及 Prisma 数据模型共同构成,形成“前端交互—后端支付—第三方网关—状态回推”的闭环。
```mermaid
graph TB
subgraph "前端UniApp"
FE_Member["会员中心
选择套餐"]
FE_Confirm["支付确认
选择支付方式"]
FE_Result["支付结果
展示状态"]
FE_Orders["订单列表
查询与轮询"]
end
subgraph "后端Koa"
C_Payment["payment.controller.ts
路由与鉴权"]
S_Payment["payment.service.ts
订单/回调/激活订阅"]
C_Sub["subscription.controller.ts
Token/配额API"]
S_Sub["subscription.service.ts
Token/音频时长计费"]
end
subgraph "数据库Prisma"
M_Order["Order
支付订单"]
M_SubPlan["SubscriptionPlan
套餐计划"]
M_Sub["Subscription
订阅记录"]
M_TB["TokenBalance
Token余额"]
M_TU["TokenUsage
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["写入订单记录
状态=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)