# 支付集成 **本文引用的文件** - [支付集成指南.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)