文档目录
支付网关表

简介

本文件面向开发者,系统化梳理 DouPHP 系统的支付网关集成数据模型与流程,重点围绕以下目标展开:

  • 支付记录表 dou_order_payment 的字段设计、约束与用途
  • 支付配置管理如何通过插件机制支持多种支付网关(支付宝、微信支付、PayPal 等)
  • 支付状态同步/异步通知处理、对账查询的数据流与幂等性保障
  • 安全验证、防重复提交与幂等性的工程实践建议

项目结构与范围

  • 支付相关数据表定义位于系统表结构与订单模块备份 SQL 中,核心为 dou_order_payment。
  • 支付能力通过插件 Provider 暴露统一接口,不同支付渠道各自实现 start/notify/finish/query 等方法。
  • 前台收银台服务负责发起支付、混合支付(余额+网关)、以及后续状态推进。
  • 对账服务用于扫描待确认的支付记录并主动查询第三方状态,提升最终一致性。
graph TB
A["前台收银台<br/>CashierService"] --> B["支付服务编排<br/>PaymentService"]
B --> C["支付插件提供者<br/>AlipayProvider / WxpayProvider / PaypalService"]
C --> D["第三方支付网关"]
D --> |异步回调| B
B --> E["支付台账表<br/>dou_order_payment"]
F["对账任务<br/>OrderReconciliation"] --> C
F --> E

核心数据模型

本节聚焦支付台账表 dou_order_payment 的设计要点与字段语义。该表用于记录每一笔支付流水,支撑多支付方式、多渠道交易号、原始报文留存、过期与完成时间等关键信息。

  • 主键与唯一约束

    • id:自增主键
    • payment_sn:支付流水号,全局唯一,作为业务幂等键
    • gateway + transaction_id:联合唯一,防止同一渠道同一第三方交易号重复入账
  • 关键字段

    • order_id/order_sn:关联订单,便于按订单维度聚合支付明细
    • gateway:支付网关标识(如 alipay/wxpay/paypal),由插件 manifest/provider 决定
    • amount:支付金额(货币单位)
    • status:支付状态(如 pending/success/closed 等)
    • transaction_id:第三方交易流水号
    • pay_evidence:支付凭证(线下或特殊场景)
    • raw_request/raw_callback:请求与回调原始报文,用于审计与问题定位
    • paid_at/expired_at/add_time:完成时间、过期时间与创建时间
  • 索引策略

    • order_id:订单维度查询
    • status + expired_at:过期清理与超时处理
    • status + gateway + add_time:按渠道与时间维度的对账/统计查询
erDiagram
DOU_ORDER_PAYMENT {
int id PK
varchar payment_sn UK
int order_id
varchar order_sn
varchar gateway
decimal amount
varchar status
varchar transaction_id
varchar pay_evidence
text raw_request
text raw_callback
datetime paid_at
datetime expired_at
datetime created_at
}

架构总览

支付流程采用“前台收银台 + 支付服务编排 + 插件化网关”的分层架构:

  • 前台收银台负责参数校验、余额拆分、调起网关
  • 支付服务编排负责创建支付台账、调用插件、处理回调与状态推进
  • 插件 Provider 封装各支付渠道差异,对外暴露统一接口
  • 对账任务定期扫描待确认记录,主动查询第三方以达成最终一致
sequenceDiagram
participant U as "用户"
participant C as "前台收银台<br/>CashierService"
participant P as "支付服务编排"
participant V as "支付插件提供者"
participant G as "第三方支付网关"
participant DB as "数据库<br/>dou_order_payment"
U->>C : 选择支付方式并提交
C->>P : 创建支付台账(生成payment_sn, 写入amount/gateway/status)
P->>V : start(PaymentRequest)
V->>G : 发起支付(签名/加密/跳转或二维码)
G-->>V : 返回支付结果/跳转URL
V-->>P : 返回前端所需内容
P-->>C : 返回页面/跳转链接
Note over C,G : 用户完成支付
G-->>P : 异步回调(携带transaction_id/amount/signature)
P->>DB : 更新status/paid_at/transaction_id(幂等)
P-->>C : 同步回跳finish(可选)

详细组件分析

支付记录表 dou_order_payment 设计要点

  • 幂等键与去重
    • payment_sn 唯一:保证同一支付流水号仅能成功入账一次
    • gateway + transaction_id 唯一:避免同一渠道同一第三方交易号重复入账
  • 可追溯性
    • raw_request/raw_callback 保留原始报文,便于审计与排障
  • 时效性与清理
    • expired_at 配合索引 status+expired_at 支持定时清理与重试
  • 查询优化
    • order_id 索引支持订单维度查看
    • status+gateway+created_at 支持对账与报表

支付配置表与多网关管理

  • 插件清单表 dou_plugin 存储插件元信息与配置 JSON,按 plugin_group=payment 组织支付类插件
  • 各支付插件通过 manifest.php 声明 provider 类名与配置项,例如:
    • 支付宝:APPID、应用私钥、支付宝公钥
    • 微信支付:AppID、AppSecret、商户号、API 密钥
    • PayPal:seller_email(老版 IPN)
  • 后台展示与编辑基于 meta() 中的 config schema 动态渲染表单
classDiagram
class PaymentPluginProviderInterface {
+pluginId() string
+meta() array
+start(request) string
+notify(payload) string
+finish(payload) string
}
class AlipayProvider {
+pluginId() string
+meta() array
+start(request) string
+notify(payload) string
+finish(payload) string
+query(request) PaymentQueryResult
}
class WxpayProvider {
+pluginId() string
+meta() array
+start(request) string
+notify(payload) string
+finish(payload) string
+status(payload) string
+query(request) PaymentQueryResult
}
class PaypalService {
+start(request) string
+notify(payload) string
+finish(payload) string
}
PaymentPluginProviderInterface <|.. AlipayProvider
PaymentPluginProviderInterface <|.. WxpayProvider
PaypalService ..> PaymentPluginProviderInterface : "遵循统一契约"

支付状态同步与异步通知处理

  • 异步回调
    • 第三方支付通过 notify_url 回调系统,系统解析 payload,校验签名后更新 dou_order_payment 的状态与第三方交易号
    • 使用 payment_sn 与 gateway+transaction_id 双重唯一约束保证幂等
  • 同步回跳
    • finish 方法用于浏览器回跳后的页面引导,不直接作为入账依据
  • 对账补偿
    • OrderReconciliation 定时扫描 pending 且超时的记录,调用 provider.query 主动查询第三方状态并回填
flowchart TD
Start(["收到回调"]) --> Verify["验签与参数校验"]
Verify --> Valid{"校验通过?"}
Valid -- 否 --> Reject["拒绝并记录日志"]
Valid -- 是 --> CheckDup{"是否已入账?"}
CheckDup -- 是 --> Idempotent["幂等返回success"]
CheckDup -- 否 --> Update["更新dou_order_payment状态/交易号/时间"]
Update --> Notify["触发订单状态机/业务动作"]
Notify --> End(["结束"])
Reject --> End
Idempotent --> End

支付验证与安全方案

  • 签名与加密
    • 各渠道 SDK 提供签名与验签能力(如支付宝 RSA2、微信 API 密钥)
    • 回调必须严格验签,失败则拒绝并记录
  • 金额一致性校验
    • 回调金额需与 dou_order_payment.amount 比对,不一致则拒绝
  • 来源白名单与限流
    • 限制回调来源 IP 白名单;对回调接口实施限流与重试退避
  • 敏感信息保护
    • 私钥、密钥等敏感配置应加密存储,不在日志中输出明文

防重复提交与幂等性保证

  • 客户端层面
    • 提交按钮禁用、前端防抖/节流,减少重复点击
  • 服务端层面
    • 基于 payment_sn 的唯一约束与分布式锁(Redis SETNX)在并发下保证单写
    • 回调处理先查再写,利用唯一索引天然幂等
  • 对账兜底
    • 对账任务拉取未确认记录,确保最终一致

前台收银台与混合支付

  • 混合支付流程
    • 优先扣减可用余额,剩余部分通过网关补齐
    • 若余额不足或失败,退回错误提示;若余额已覆盖全额,直接收尾订单
  • 数据流转
    • 收银台服务计算 split,调用支付服务创建 dou_order_payment 并调起对应 Provider
sequenceDiagram
participant U as "用户"
participant CS as "CashierService"
participant PS as "PaymentService"
participant PR as "Provider"
U->>CS : 提交支付
CS->>PS : 计算余额拆分/创建支付台账
PS->>PR : start(剩余金额)
PR-->>PS : 返回支付入口/二维码
PS-->>CS : 返回前端交互
U-->>PR : 完成支付
PR-->>PS : 回调/轮询/查询
PS-->>CS : 更新状态/跳转

依赖关系分析

  • 插件注册与发现
    • manifest.php 声明 group=payment 与 provider 类路径
    • 系统通过插件框架加载 Provider,统一对外暴露 start/notify/finish/query
  • 数据访问
    • 支付台账读写集中在支付服务编排层,控制器与服务仅传递 DTO
  • 对账与报表
    • 对账任务依赖 provider.query 能力;后台订单视图读取 dou_order_payment 列表展示
graph LR
M["manifest.php"] --> R["插件注册中心"]
R --> A["AlipayProvider"]
R --> W["WxpayProvider"]
R --> P["PaypalService"]
A --> DB["dou_order_payment"]
W --> DB
P --> DB
O["OrderReconciliation"] --> A
O --> W

性能与索引建议

  • 已有索引
    • payment_sn 唯一索引:幂等写入与查询
    • gateway+transaction_id 唯一索引:渠道级幂等
    • order_id:订单维度查询
    • status+expired_at:超时清理与对账扫描
    • status+gateway+created_at:渠道与时间维度的对账/统计
  • 建议
    • 对高频查询增加覆盖索引(如 order_id+status+created_at)
    • 大表归档:历史支付记录按季度归档至只读库
    • 回调接口限流与重试退避,避免雪崩

故障排查指南

  • 常见现象
    • 回调重复到达但状态未变:检查唯一约束与幂等逻辑
    • 支付成功但订单未更新:核对回调金额与签名校验
    • 长时间 pending:检查对账任务是否运行、provider.query 是否可用
  • 排查步骤
    • 查看 raw_callback 与 raw_request 定位报文问题
    • 核对 dou_order_payment.status 与 paid_at/expired_at
    • 检查 provider 的 query 返回值与异常日志
  • 工具与视图
    • 后台订单页展示支付记录列表,包含支付流水号、方式、金额、状态、第三方流水号、支付时间等

结论

DouPHP 的支付体系以 dou_order_payment 为核心台账,结合插件化的 Provider 抽象,实现了多支付渠道的统一接入与管理。通过唯一约束、回调验签、对账补偿等手段,构建了高可靠、可扩展、易维护的支付基础设施。建议在新增渠道时严格遵循统一契约,完善配置 schema、签名校验与对账能力,确保资金安全与数据一致。

附录:字段字典与状态说明

  • 字段字典(节选)
    • payment_sn:支付流水号(业务幂等键)
    • order_id/order_sn:关联订单
    • gateway:支付网关标识
    • amount:支付金额
    • status:支付状态(pending/success/closed 等)
    • transaction_id:第三方交易号
    • pay_evidence:支付凭证
    • raw_request/raw_callback:原始报文
    • paid_at/expired_at/created_at:时间戳
  • 状态说明
    • pending:待支付/处理中
    • success:支付成功
    • closed:关闭/失败
    • 其他状态可根据业务扩展
添加日期:2026-10-05