文档目录
订单支付相关表

简介

本设计文档围绕 DouPHP 电商系统的订单支付相关表展开,重点覆盖以下主题:

  • 支付流水表(order_payment)与退款记录表(order_refund)的数据结构设计
  • 支付配置与渠道接入(支付宝、微信支付、银行转账、货到付款等)
  • 支付流程状态管理、回调处理、对账兜底
  • 退款分账策略(网关退款与余额退款)
  • 安全与异常处理(幂等、加密存储、传输安全、重试与补偿)
  • 面向开发者的集成参考实现建议

项目结构

支付能力由“核心服务 + 插件化渠道”构成:

  • 核心层:PaymentService 负责创建支付流水、状态迁移、混合支付收尾、退款分账、回调落库等;PaymentSnGenerator 生成唯一支付流水号。
  • 渠道层:各支付插件(微信、支付宝、银行转账、货到付款等)通过 Provider/Service 对接第三方网关,统一调用 PaymentService 完成状态推进。
  • 售后层:AftersaleService 触发退款申请,结合 PaymentService 的退款分账逻辑完成余额与网关退款的拆分与收尾。
  • 后台展示:order.htm 展示支付记录列表;order_report.htm 提供支付方式统计与退款趋势报表。
graph TB
Client["前端/商户系统"] --> Order["订单模块"]
Order --> PaySvc["支付服务<br/>PaymentService"]
PaySvc --> Gen["支付流水号生成器<br/>PaymentSnGenerator"]
PaySvc --> DB1["数据库<br/>order_payment / order_refund / order"]
PaySvc --> Wallet["钱包服务<br/>WalletService"]
PaySvc --> Status["订单状态机<br/>OrderStatusTransition"]
ChannelWX["微信支付插件"] --> PaySvc
ChannelAli["支付宝插件"] --> PaySvc
ChannelBank["银行转账插件"] --> PaySvc
ChannelCOD["货到付款插件"] --> PaySvc
Aftersale["售后退款服务"] --> PaySvc

核心组件

  • 支付流水服务(PaymentService)
    • 创建支付流水行(pending),支持过期时间控制
    • 按 payment_sn/gateway+transaction_id 查询,保障 Webhook 幂等
    • 标记成功并联动订单推进到已支付(考虑混合支付凑满才收尾)
    • 钱包支付腿扣款、回滚与退款退回
    • 售后退款分账(网关 pending 申请,余额同步退回)
    • 标记失败/关闭、记录回调原文、离线凭证附件
  • 支付流水号生成器(PaymentSnGenerator)
    • 生成唯一 payment_sn,作为第三方 out_trade_no
    • 冲突时重试生成,避免重复
  • 退款记录模型(OrderRefund)
    • 每笔退款一行,关联原始支付 leg(order_payment_id)
    • 支持按订单、状态筛选
  • 订单状态日志模型(OrderStatusLog)
    • 记录订单状态变更时间线,供详情页展示

架构总览

支付主流程(以第三方支付为例):

  • 订单下单后,创建 pending 支付流水
  • 渠道插件发起支付请求,返回支付链接/二维码
  • 用户完成支付,第三方回调通知
  • 平台校验签名与金额,幂等写入 raw_callback,推进 payment 为 succeeded
  • 累计网关已付金额,尝试将订单推进到 PAID(混合支付需凑满)
  • 若未凑满,保持部分支付,等待其他支付腿(如余额)补齐
sequenceDiagram
participant U as "用户"
participant O as "订单模块"
participant P as "支付服务"
participant G as "支付网关(微信/支付宝/银行)"
participant D as "数据库"
U->>O : "提交订单"
O->>P : "createForOrder(orderSn, gateway, amount)"
P->>D : "插入 order_payment(pending)"
P-->>O : "返回 payment_sn"
O->>G : "发起支付(携带 out_trade_no=payment_sn)"
G-->>U : "展示支付页面/二维码"
U->>G : "完成支付"
G-->>P : "回调通知(transaction_id, amount)"
P->>D : "记录 raw_callback"
P->>D : "更新 order_payment(succeeded)"
P->>D : "累计 order.gateway_paid"
P->>P : "tryFinalizeOrder(检查是否凑满)"
P-->>O : "订单推进到PAID(若满足)"

详细组件分析

支付流水表(order_payment)设计

  • 作用:记录每次支付尝试(一个订单可多次尝试),作为第三方 out_trade_no 的唯一标识
  • 关键字段
    • id:自增主键
    • payment_sn:支付流水号(唯一,用于幂等与对账)
    • order_id / order_sn:关联订单
    • gateway:支付渠道标识(如 wxpay、alipay、bankpay、wallet 等)
    • amount:本次支付金额
    • status:状态(pending/succeeded/failed/closed/refunded/partial_refunded)
    • transaction_id:第三方交易号(用于幂等查找)
    • paid_at:支付成功时间
    • expired_at:过期时间(用于超时关闭)
    • raw_callback:回调原文(用于审计与对账)
    • pay_evidence:离线付款凭证路径(如银行转账截图)
    • created_at:创建时间
  • 索引与约束
    • UNIQUE(gateway, transaction_id):保证同一第三方交易号不重复落库
    • INDEX(payment_sn)、INDEX(order_id)、INDEX(status):提升查询性能

退款记录表(order_refund)设计

  • 作用:记录每笔退款申请与结果,支持按支付腿拆分退款(混合支付场景)
  • 关键字段
    • id:自增主键
    • refund_sn:退款单号(唯一)
    • order_id:关联订单
    • aftersale_id:关联售后单(可为空)
    • order_payment_id:关联原始支付腿(order_payment.id)
    • channel:退款渠道(wallet 或具体网关)
    • amount:退款金额
    • status:状态(pending/succeeded)
    • refunded_at:退款完成时间
    • raw_callback:退款回调原文(可选)
    • created_at:创建时间
  • 业务规则
    • 网关退款:先登记 pending,待管理员在网关后台完成退款后,调用 markRefundSucceeded 收尾
    • 余额退款:直接同步退回会员余额,并标记 succeeded
    • 幂等:按 leg 维度计算可退额 = 腿金额 − 该腿已 succeeded 的退款合计

订单状态与日志(order、order_status_log)

  • order 表扩展字段
    • pay_id:实际使用的支付方式(当全部为 wallet 时自动填充)
    • gateway_paid:网关累计已付金额
    • wallet_paid:余额累计已付金额
    • refund_status:退款状态(refunded/partial_refunded)
  • order_status_log:记录订单状态变更时间线,便于追踪协商、支付、发货、售后等关键节点

支付渠道集成与回调处理

  • 微信支付(wxpay)
    • 通过 WxpayService 发起支付,接收回调后调用 PaymentService::markSucceeded
    • 回调中携带 transaction_id,用于幂等匹配
  • 支付宝(alipay)
    • 通过 AlipayService 发起支付,回调验证签名与金额后推进状态
  • 银行转账(bankpay)
    • 支持线下转账凭证上传(pay_evidence),后台审核后手动推进
  • 货到付款(cod)
    • 收货确认后标记支付成功
sequenceDiagram
participant C as "渠道插件"
participant P as "支付服务"
participant D as "数据库"
C->>P : "回调通知(transaction_id, amount)"
P->>D : "findByGatewayTxn 幂等检查"
P->>D : "recordCallback(raw_callback)"
P->>D : "update order_payment(succeeded)"
P->>D : "累计 order.gateway_paid"
P->>P : "tryFinalizeOrder(凑满则推进订单)"

退款处理流程

  • 售后退款申请触发后,PaymentService::refundOrder 按支付腿拆分退款
    • 网关腿:登记 pending 退款申请
    • 余额腿:同步退回余额,标记 succeeded
  • 管理员在网关后台完成退款后,调用 markRefundSucceeded 收尾,更新退款状态与支付腿状态
flowchart TD
Start(["开始退款"]) --> LoadLegs["加载成功支付腿<br/>gateway优先,wallet在后"]
LoadLegs --> Split{"按剩余退款额分配"}
Split --> |网关腿| CreatePending["创建order_refund(pending)"]
Split --> |余额腿| RefundWallet["退回余额并标记succeeded"]
CreatePending --> WaitAdmin["等待管理员完成网关退款"]
RefundWallet --> UpdateLeg["更新支付腿状态(refunded/partial_refunded)"]
WaitAdmin --> MarkSucceeded["markRefundSucceeded收尾"]
MarkSucceeded --> UpdateLeg
UpdateLeg --> End(["结束"])

支付配置表(概念性说明)

  • 支付配置通常以插件 manifest 或配置项形式存在,包含:
    • 渠道标识(gateway)
    • 渠道名称(用于前台展示)
    • 密钥与证书(敏感信息应加密存储)
    • 回调地址、签名算法、版本等
  • 在本系统中,渠道通过插件目录(如 plugin/wxpay、plugin/alipay)组织,manifest.php 描述插件元数据,Service/Provider 实现具体逻辑

依赖关系分析

  • PaymentService 依赖:
    • PaymentSnGenerator:生成唯一支付流水号
    • OrderStatusTransition:推进订单状态(PAID/COMPLETED)
    • WalletService:余额扣款与退款
    • DB:持久化 order_payment、order_refund、order 等
  • 渠道插件依赖:
    • 各自 SDK/Service 封装第三方 API
    • 回调统一调用 PaymentService 推进状态
  • 售后退款依赖:
    • AftersaleService 触发退款申请
    • PaymentService 执行分账与收尾
graph LR
PaySvc["PaymentService"] --> Gen["PaymentSnGenerator"]
PaySvc --> Status["OrderStatusTransition"]
PaySvc --> Wallet["WalletService"]
PaySvc --> DB["DB"]
WX["WxpayService"] --> PaySvc
ALI["AlipayService"] --> PaySvc
BANK["BankpayService"] --> PaySvc
COD["CodService"] --> PaySvc
AFT["AftersaleService"] --> PaySvc

性能与一致性

  • 幂等性
    • 通过 UNIQUE(gateway, transaction_id) 与 findByGatewayTxn 保证回调幂等
    • markSucceeded 对已成功的 payment 直接返回 true,避免重复联动
  • 事务与锁
    • 钱包支付使用 BEGIN/COMMIT/ROLLBACK 与 FOR UPDATE 锁,防止并发超扣
    • 退款分账逐腿事务处理,确保余额与状态一致
  • 金额精度
    • 使用 AMOUNT_EPSILON 容差避免 decimal 浮点误差导致判断偏差
  • 对账兜底
    • 订单未推进到 PAID 时,payment 保持 pending,交由对账任务扫描修复

故障排查指南

  • 常见问题定位
    • 支付未到账:检查 order_payment.status 是否为 succeeded,raw_callback 是否记录
    • 订单未推进:检查 tryFinalizeOrder 是否因未凑满而返回 false
    • 退款未生效:确认 order_refund.status 是否为 succeeded,网关退款是否已完成
  • 日志与审计
    • 使用 logError 记录非法状态迁移、异常信息与上下文
    • 后台 order.htm 展示支付记录列表,便于人工核对
  • 报表与分析
    • order_report.htm 提供支付方式统计与退款趋势,辅助发现异常

结论

DouPHP 的支付体系以 PaymentService 为核心,结合插件化渠道与售后退款服务,实现了:

  • 多支付方式支持与回调幂等处理
  • 混合支付的分账与凑满收尾
  • 退款分账与状态闭环
  • 完善的日志、审计与报表能力 建议在集成时遵循:
  • 严格使用 payment_sn 作为 out_trade_no
  • 回调中校验签名与金额,记录 raw_callback
  • 退款分账按 leg 维度处理,确保幂等与一致性
  • 利用后台工具与报表进行日常监控与问题定位

附录:数据模型与字段说明

支付流水表(order_payment)

  • 字段
    • id:主键
    • payment_sn:支付流水号(唯一)
    • order_id / order_sn:订单关联
    • gateway:支付渠道标识
    • amount:支付金额
    • status:状态(pending/succeeded/failed/closed/refunded/partial_refunded)
    • transaction_id:第三方交易号
    • paid_at:支付成功时间
    • expired_at:过期时间
    • raw_callback:回调原文
    • pay_evidence:离线凭证路径
    • created_at:创建时间
  • 索引
    • UNIQUE(gateway, transaction_id)
    • INDEX(payment_sn)、INDEX(order_id)、INDEX(status)

退款记录表(order_refund)

  • 字段
    • id:主键
    • refund_sn:退款单号(唯一)
    • order_id:订单关联
    • aftersale_id:售后单关联
    • order_payment_id:原始支付腿
    • channel:退款渠道
    • amount:退款金额
    • status:状态(pending/succeeded)
    • refunded_at:退款完成时间
    • raw_callback:退款回调原文
    • created_at:创建时间

订单状态日志表(order_status_log)

  • 字段
    • id:主键
    • order_id:订单关联
    • operator_id:操作人
    • created_at:创建时间
添加日期:2026-10-05