文档目录
支付集成系统

简介

本文件面向电商开发者,系统化说明 DouPHP 支付集成系统的实现与使用。内容覆盖已集成的支付方式(支付宝、微信支付、PayPal等),重点阐述支付流程设计、回调处理、状态同步、退款分账、安全机制(签名验证、防重放)、配置管理、多币种支持、渠道切换与扩展新支付方式的步骤。最新更新:PaymentStatus枚举已迁移至核心领域层,并提供全新的PaymentSnGenerator支付流水号生成器,为第三方支付网关集成提供可靠的唯一标识符生成能力。重要变更:独立的余额支付插件(balancepay)已从代码库中移除,但核心余额支付功能通过WalletService保留,支持混合支付模式(余额+第三方支付)。文档以代码级分析为基础,配合流程图与时序图帮助理解数据流与控制流。

项目结构

支付能力由"插件 Provider + Service + 核心 PaymentService"三层构成:

  • 插件层:每个支付方式一个独立插件目录,包含 manifest.php、Provider、Service、SDK 与资源。
  • 服务层:各支付 Service 负责对接第三方 SDK、组装参数、验签与结果归一化。
  • 核心层:PaymentService 统一维护支付台账 order_payment、订单联动与退款分账,保证幂等与一致性。
  • 领域层:PaymentStatus 枚举定义在 core/domain/payment/,提供标准化的支付状态管理。
  • 钱包层:WalletService 提供余额管理和混合支付支持。
  • 新增:PaymentSnGenerator 提供统一的支付流水号生成服务,确保全局唯一性。
graph TB
subgraph "前端/后台"
UI["收银台/订单页"]
Admin["后台管理"]
end
subgraph "支付核心"
PS["PaymentService<br/>支付台账/状态机/退款分账"]
PSG["PaymentSnGenerator<br/>23位唯一流水号生成"]
OST["OrderStatusTransition<br/>订单状态机"]
PSD["PaymentStatus<br/>支付状态枚举"]
WS["WalletService<br/>余额管理/混合支付"]
end
subgraph "支付插件"
ALI_P["AlipayProvider"]
ALI_S["AlipayService"]
WX_P["WxpayProvider"]
WX_S["WxpayService"]
PP_P["PaypalProvider"]
end
UI --> ALI_P
UI --> WX_P
UI --> PP_P
ALI_P --> ALI_S
WX_P --> WX_S
PP_P --> PP_S["PaypalService"]
ALI_S --> PS
WX_S --> PS
PP_S --> PS
PS --> PSN["PaymentSnGenerator"]
PS --> OST
PS --> PSD
PS --> WS

图表来源

  • PaymentService.php:154-296
  • PaymentSnGenerator.php:32-53
  • PaymentStatus.php:37-107
  • AlipayProvider.php:18-110
  • AlipayService.php:44-172
  • WxpayProvider.php:19-126
  • WxpayService.php:49-187
  • PaypalProvider.php:16-100
  • WalletService.php:127-172

章节来源

  • PaymentService.php:154-296
  • PaymentSnGenerator.php:32-53
  • PaymentStatus.php:37-107
  • AlipayProvider.php:18-110
  • WxpayProvider.php:19-126
  • PaypalProvider.php:16-100
  • WalletService.php:127-172

核心组件

  • 支付流水号生成器(PaymentSnGenerator)

    • 新增功能:提供23位唯一支付流水号生成,格式为 P + YmdHis(14位)+ 8位随机数
    • 内置冲突检测:通过数据库查询确保 payment_sn 的唯一性
    • 自动重试机制:发生冲突时自动休眠并重试生成,避免无限递归
    • 用于第三方支付网关的 out_trade_no 字段,确保"一个订单多次支付尝试"能精准对应到本地 payment 行
  • 支付状态枚举(PaymentStatus)

    • 位于 core/domain/payment/PaymentStatus.php,定义了完整的支付状态机
    • 支持状态:PENDING、SUCCEEDED、FAILED、CLOSED、REFUNDED、PARTIAL_REFUNDED
    • 提供表驱动的迁移验证,确保状态转换的合法性
    • 支持部分退款场景:从 SUCCEEDED → PARTIAL_REFUNDED → REFUNDED
  • 支付台账与状态机(PaymentService)

    • 为每次支付尝试创建 order_payment 记录,统一管理状态迁移
    • 使用 PaymentSnGenerator 生成唯一的 payment_sn
    • 提供 markSucceeded、tryFinalizeOrder、refundOrder、markRefundSucceeded 等原子方法
    • 混合支付:网关腿与钱包腿可任意先后到达,累计金额达到订单金额后推进订单到 PAID
    • 使用 PaymentStatus::canTransit() 进行状态迁移验证
  • 钱包服务(WalletService)

    • 提供会员余额和积分管理功能
    • 支持混合支付模式:余额+第三方支付组合
    • 事务安全的余额扣款和充值操作
    • 与PaymentService集成,实现无缝的混合支付流程
  • 订单状态联动(OrderStatusTransition)

    • 在 PaymentService 中调用 changeStatus,将订单从 PENDING/AWAITING_CONFIRMATION 推进到 PAID/COMPLETED
    • 触发库存、积分、分销等副作用
  • 支付插件 Provider/Service

    • Provider 暴露标准接口 start/notify/finish/query/status
    • Service 封装第三方 SDK 调用与参数归一化
    • 支持主动对账(query)与轮询(status,如微信 Native)

章节来源

  • PaymentSnGenerator.php:32-53
  • PaymentStatus.php:37-107
  • PaymentService.php:154-296
  • PaymentService.php:471-642
  • WalletService.php:127-172
  • OrderStatusTransition.php:89-122

架构总览

支付主流程(以支付宝为例):

  • 收银台创建 pending 的 payment 记录,调用 AlipayService.start 生成跳转链接
  • 新增:PaymentService.createForOrder 使用 PaymentSnGenerator.generate() 生成23位唯一 payment_sn
  • 用户完成支付后,支付宝异步通知 notify,AlipayService 验签后调用 PaymentService.markSucceeded
  • PaymentService 使用 PaymentStatus::canTransit() 验证状态迁移,更新 payment 为 SUCCEEDED
  • 累计 gateway_paid,并尝试 tryFinalizeOrder 推进订单到 PAID
  • 若存在未完成的钱包腿或后续回调,最终自愈收尾
sequenceDiagram
participant U as "用户"
participant F as "前台收银台"
participant A as "AlipayService"
participant PS as "PaymentService"
participant PSG as "PaymentSnGenerator"
participant PS_ENUM as "PaymentStatus"
participant O as "OrderStatusTransition"
participant G as "支付宝网关"
U->>F : 提交订单并选择支付宝
F->>PS : createForOrder(orderId, orderSn, gateway, amount)
PS->>PSG : generate()
PSG-->>PS : 23位唯一payment_sn (P+时间戳+随机数)
PS->>A : start(PaymentRequest with payment_sn)
A->>G : 构造页面支付请求(out_trade_no=payment_sn)
G-->>U : 跳转至支付宝收银台
U->>G : 完成支付
G-->>A : 异步通知(notify)
A->>A : 验签与参数校验
A->>PS : markSucceeded(paymentSn, tradeNo)
PS->>PS_ENUM : canTransit(pending -> succeeded)
PS_ENUM-->>PS : true
PS->>PS : 更新order_payment为SUCCEEDED
PS->>O : changeStatus(orderSn, PAID)
O-->>PS : 订单状态推进成功
PS-->>A : 返回true
A-->>F : 返回success

图表来源

  • PaymentService.php:84-102
  • PaymentSnGenerator.php:39-53
  • AlipayService.php:44-88
  • PaymentService.php:154-296
  • PaymentStatus.php:69-77
  • OrderStatusTransition.php:89-122

章节来源

  • PaymentService.php:84-102
  • PaymentSnGenerator.php:39-53
  • AlipayService.php:44-172
  • PaymentService.php:154-296

详细组件分析

支付流水号生成器(PaymentSnGenerator)

新增功能:PaymentSnGenerator 提供统一的23位唯一支付流水号生成服务

  • 生成规则:

    • 格式:P + YmdHis(14位时间戳)+ 8位随机数 = 23位
    • 前缀 P 便于日志排查时一眼区分支付流水号与订单号
    • 时间戳确保按时间顺序生成,随机数确保同一秒内的唯一性
  • 冲突检测与重试机制:

    • 生成后立即查询数据库检查是否存在重复
    • 发现冲突时休眠1毫秒后递归重试
    • 避免无上限递归,通过微秒级延迟降低冲突概率
  • 应用场景:

    • 支付流水号:作为第三方网关的 out_trade_no
    • 退款流水号:用于退款申请和退款确认的唯一标识
    • 确保"一个订单多次支付尝试"在第三方侧也能精准对应到本地的 payment 行
flowchart TD
Start(["调用generate()"]) --> Generate["生成23位流水号<br/>P + YmdHis + 8位随机数"]
Generate --> CheckDB["查询数据库检查重复"]
CheckDB --> |存在重复| Sleep["休眠1毫秒"]
Sleep --> Retry["递归调用generate()"]
Retry --> CheckDB
CheckDB --> |无重复| Return["返回唯一流水号"]
Return --> End(["结束"])

图表来源

  • PaymentSnGenerator.php:39-53

章节来源

  • PaymentSnGenerator.php:32-53

支付状态枚举(PaymentStatus)

更新:PaymentStatus 现已迁移至核心领域层,提供更强大的支付生命周期管理

  • 状态定义:

    • PENDING:已发起,等待结果
    • SUCCEEDED:成功(第三方异步回调验签通过 / 后台审核通过 / 主动对账确认成功)
    • FAILED:失败(第三方明确返回失败 / 后台审核驳回 / 验签失败)
    • CLOSED:关闭(超时未付款 / 第三方明确说已关闭)
    • REFUNDED:已全额退款(成功的支付被全额退回,终态)
    • PARTIAL_REFUNDED:已部分退款(成功的支付被部分退回,可继续退至全额 → REFUNDED)
  • 状态迁移规则:

    • PENDING → {SUCCEEDED, FAILED, CLOSED}
    • SUCCEEDED → {REFUNDED, PARTIAL_REFUNDED}
    • PARTIAL_REFUNDED → {REFUNDED}
    • FAILED/CLOSED/REFUNDED → {}(终态)
stateDiagram-v2
[*] --> PENDING
PENDING --> SUCCEEDED
PENDING --> FAILED
PENDING --> CLOSED
SUCCEEDED --> REFUNDED
SUCCEEDED --> PARTIAL_REFUNDED
PARTIAL_REFUNDED --> REFUNDED
FAILED --> [*]
CLOSED --> [*]
REFUNDED --> [*]

图表来源

  • PaymentStatus.php:53-60

章节来源

  • PaymentStatus.php:37-107

钱包服务(WalletService)

重要更新:虽然独立的balancepay插件已被移除,但核心钱包功能通过WalletService保留,支持混合支付模式

  • 余额管理:

    • 提供createMoney方法写入余额流水,带行锁防止并发问题
    • 支持负数金额(扣款)和正数金额(充值)
    • 自动更新用户钱包余额快照
  • 混合支付支持:

    • 与PaymentService集成,支持余额+第三方支付组合
    • 事务安全的余额扣款操作
    • 支持订单取消时的余额退回
  • 配置开关:

    • 通过Config::get('features.money', false)控制钱包功能启用
    • 未启用时所有钱包操作直接返回false
flowchart TD
Start(["余额操作"]) --> CheckConfig{"features.money启用?"}
CheckConfig --> |否| ReturnFalse["返回false"]
CheckConfig --> |是| Lock["获取行锁FOR UPDATE"]
Lock --> Calculate["计算新余额"]
Calculate --> CheckBalance{"余额>=0?"}
CheckBalance --> |否| Rollback["回滚操作"]
CheckBalance --> |是| Insert["插入余额流水"]
Insert --> UpdateWallet["更新钱包快照"]
UpdateWallet --> Success["返回true"]

图表来源

  • WalletService.php:127-172

章节来源

  • WalletService.php:127-172

支付宝插件(电脑网站支付)

  • Provider 职责
    • 暴露 pluginId、meta(APPID、私钥、公钥)、start/notify/finish/query
  • Service 职责
    • start:构建 pagePay 请求,设置 out_trade_no=payment_sn(来自 PaymentSnGenerator)
    • notify/finish:验签通过后调用 PaymentService.markSucceeded,finish 成功后发送邮件通知
    • query:主动对账,根据 trade_status 返回 succeeded/pending/closed
  • 安全与幂等
    • 验签失败直接拒绝;重复回调通过 PaymentService 幂等处理
flowchart TD
Start(["支付宝回调入口"]) --> Verify["验签与参数校验"]
Verify --> |失败| Fail["返回fail"]
Verify --> |成功| Extract["提取out_trade_no/trade_no"]
Extract --> CallPS["调用PaymentService.markSucceeded"]
CallPS --> CheckStatus["PaymentStatus::canTransit验证"]
CheckStatus --> Update["更新order_payment为SUCCEEDED"]
Update --> Finalize["tryFinalizeOrder推进订单"]
Finalize --> Done(["结束"])

图表来源

  • AlipayService.php:69-120
  • PaymentService.php:154-296
  • PaymentStatus.php:69-77

章节来源

  • AlipayProvider.php:18-110
  • AlipayService.php:44-172

微信支付插件(Native/JSAPI/H5)

  • Provider 职责
    • 暴露 pluginId、meta(AppID、MCHID、Key、AppSecret)、start/notify/finish/status/query
  • Service 职责
    • start:按 UA 自动派发 JSAPI/MWEB/NATIVE
    • notify:统一用 WxPayNotify 验签,内部回调处理成功后调用 PaymentService.markSucceeded
    • status:Native 扫码场景前端轮询,查询 trade_state 并推进状态
    • query:主动对账,映射 trade_state 为 succeeded/pending/closed
  • 日志与配置
    • 初始化 SDK 日志到 storage/log/payment/wxpay/;配置来自插件 meta 与 buildConfig
sequenceDiagram
participant U as "用户"
participant WX as "WxpayService"
participant PS as "PaymentService"
participant PS_ENUM as "PaymentStatus"
participant G as "微信支付网关"
U->>WX : start(按UA选择JSAPI/H5/Native)
WX->>G : 统一下单/获取支付参数
G-->>U : 唤起支付/展示二维码
G-->>WX : 异步通知(notify)
WX->>WX : 验签与解析
WX->>PS : markSucceeded(paymentSn, transaction_id)
PS->>PS_ENUM : canTransit(pending -> succeeded)
PS_ENUM-->>PS : true
PS->>PS : 更新order_payment为SUCCEEDED
PS->>PS : tryFinalizeOrder推进订单
PS-->>WX : true
WX-->>U : finish(回跳订单页)

图表来源

  • WxpayService.php:49-134
  • PaymentService.php:154-296
  • PaymentStatus.php:69-77

章节来源

  • WxpayProvider.php:19-126
  • WxpayService.php:49-187
  • WxPay.Config.Interface.php:1-36

PayPal 插件

  • Provider 职责
    • 暴露 pluginId、meta(收款邮箱、货币多选)、start/notify/finish
  • Service 职责
    • 对接 PayPal 流程,完成支付发起与回调处理(具体实现位于 PaypalService)
  • 多币种
    • meta 中 currency_code 支持 USD/EUR/GBP/AUD/CAD/JPY/HKD

章节来源

  • PaypalProvider.php:16-100

混合支付(余额+网关)

重要更新:虽然balancepay插件已移除,但混合支付功能通过WalletService和PaymentService集成实现

  • 钱包支付腿
    • PaymentService.markSucceededByWallet:在事务内扣款、落账、累计 wallet_paid,并尝试收尾订单
    • 使用 PaymentSnGenerator 生成钱包支付的唯一标识
    • 幂等:已有成功钱包腿不重复扣款
  • 取消时退回钱包
    • refundWalletPaymentOnCancel:逐腿原额退回会员余额,并将该腿标记 REFUNDED
  • 售后退款分账
    • refundOrder:按"网关优先、钱包在后"的顺序拆分退款,wallet 腿即时退回余额并标记 REFUNDED/PARTIAL_REFUNDED;网关腿登记 pending,待人工或回调收尾
    • 退款申请也使用 PaymentSnGenerator 生成唯一的 refund_sn
    • markRefundSucceeded:收尾网关退款,更新 order_refund 与 order_payment 状态
flowchart TD
RStart(["发起退款"]) --> Legs["读取成功支付腿<br/>网关优先、钱包在后"]
Legs --> Alloc{"剩余可退金额>0?"}
Alloc --> |否| REnd(["结束"])
Alloc --> |是| Type{"leg.gateway==wallet?"}
Type --> |是| WalletRefund["余额退回+落账+标记REFUNDED/PARTIAL_REFUNDED<br/>使用PaymentSnGenerator生成refund_sn"]
Type --> |否| PendingRefund["登记pending退款申请<br/>使用PaymentSnGenerator生成refund_sn"]
WalletRefund --> Next["继续分配剩余金额"]
PendingRefund --> Next
Next --> Alloc

图表来源

  • PaymentService.php:471-642
  • PaymentSnGenerator.php:39-53

章节来源

  • PaymentService.php:298-469
  • PaymentService.php:471-642
  • WalletService.php:127-172

订单状态联动

  • PaymentService.tryFinalizeOrder:当所有成功支付腿金额累计覆盖订单金额时,调用 OrderStatusTransition.changeStatus 推进订单到 PAID/COMPLETED
  • OrderStatusTransition:在事务内更新订单与订单项状态,并根据是否有物流插件决定是否直接置为 COMPLETED

章节来源

  • PaymentService.php:227-296
  • OrderStatusTransition.php:89-122

依赖关系分析

  • 插件清单
    • 支付宝与微信支付通过 manifest.php 声明 provider,便于框架发现与路由
  • 契约与扩展点
    • ReconcilablePaymentProviderInterface:支持主动对账(query)
    • PollablePaymentProviderInterface:支持前端轮询(status,如微信 Native)
    • PaymentPluginProviderInterface:基础支付插件接口(start/notify/finish)
  • 外部依赖
    • 支付宝 SDK(AOP)、微信支付 SDK(WxPay.*)、PayPal SDK(PaypalService)
  • 领域模型依赖
    • 所有支付相关服务现在都依赖 Dou\Core\Service\Payment\PaymentSnGenerator
    • 所有支付相关服务现在都依赖 Dou\Core\Domain\Payment\PaymentStatus
    • 钱包服务依赖 Dou\Core\Service\Wallet\WalletService
    • 统一的支付流水号生成和状态管理确保了系统的一致性和可维护性
graph LR
M1["alipay/manifest.php"] --> P1["AlipayProvider"]
M2["wxpay/manifest.php"] --> P2["WxpayProvider"]
P1 --> S1["AlipayService"]
P2 --> S2["WxpayService"]
S1 --> Core["PaymentService"]
S2 --> Core
Core --> PSG["PaymentSnGenerator"]
Core --> PS["PaymentStatus<br/>核心领域层"]
Core --> WS["WalletService<br/>余额管理"]

图表来源

  • manifest.php(支付宝):7-10
  • manifest.php(微信支付):7-10
  • AlipayProvider.php:18-110
  • WxpayProvider.php:19-126
  • PaymentSnGenerator.php:32-53
  • PaymentStatus.php:37-107
  • WalletService.php:127-172

章节来源

  • manifest.php(支付宝):7-10
  • manifest.php(微信支付):7-10

性能与可靠性

  • 幂等性
    • PaymentService.markSucceeded 对已成功的 payment 直接返回 true,避免重复联动
    • DB 层 UNIQUE KEY(gateway, transaction_id) 防止重复落库
    • PaymentStatus::canTransit() 确保状态迁移的幂等性
    • 新增:PaymentSnGenerator 通过数据库冲突检测确保流水号全局唯一
  • 事务与锁
    • 钱包支付与退款在事务内执行,必要时使用 FOR UPDATE 行锁,防止并发超扣
    • PaymentSnGenerator 的重试机制避免了高并发下的冲突问题
  • 容差与精度
    • AMOUNT_EPSILON 用于浮点误差补偿,确保"已付满"判定准确
  • 对账与自愈
    • 主动对账(query)与轮询(status)兜底网络异常与回调丢失,确保最终一致
  • 日志与审计
    • raw_callback 留底,便于问题定位;关键路径均记录错误日志
    • 新增:PaymentSnGenerator 的冲突检测和重试过程便于追踪
  • 状态机验证
    • 所有状态迁移都经过 PaymentStatus::canTransit() 验证,防止非法状态转换

故障排查指南

  • 常见错误
    • 非法状态迁移:PaymentService 会记录 illegal payment transition 日志,检查当前 payment 与目标状态是否允许
    • 订单不可收款:非 PENDING/AWAITING_CONFIRMATION/PAID/COMPLETED 的订单不会接受新的支付腿,保持 pending 留给对账或人工退款
    • 订单推进失败:changeStatus 后回查订单状态,若不成功则记录 order not advanced 日志
    • 新增:流水号冲突:PaymentSnGenerator 会自动重试,但频繁冲突可能表明系统负载过高
    • 钱包功能禁用:如果features.money配置为false,所有钱包操作将返回false
  • 排查步骤
    • 查看 order_payment.raw_callback 确认第三方回调原文
    • 核对插件配置(APPID、私钥、公钥、Key 等)是否完整
    • 检查对账结果(query/status)与订单状态是否一致
    • 关注 storage/log/payment/wxpay/*.log 中的微信 SDK 日志
    • 新增:检查 PaymentSnGenerator 的冲突日志,评估是否需要优化流水号生成策略
    • 检查 PaymentStatus::canTransit() 的返回值,确认状态迁移是否合法
    • 钱包相关:检查Config::get('features.money')配置是否正确

章节来源

  • PaymentService.php:172-225
  • PaymentService.php:744-784
  • WxpayService.php:447-455
  • PaymentSnGenerator.php:39-53
  • PaymentStatus.php:69-77
  • WalletService.php:127-172

结论

DouPHP 支付集成系统通过统一的 PaymentService 抽象出支付台账与状态机,结合各插件 Provider/Service 实现对多支付渠道的解耦接入。最新改进:新增的 PaymentSnGenerator 支付流水号生成器提供了可靠的23位唯一标识符生成能力,支持冲突检测和重试逻辑,为第三方支付网关集成提供了坚实的基础。同时,PaymentStatus 枚举迁移至核心领域层,提供了更强大的支付生命周期管理和部分退款支持。重要变更:虽然独立的余额支付插件(balancepay)已从代码库中移除,但核心余额支付功能通过WalletService保留,支持混合支付模式(余额+第三方支付),为商家提供了更灵活的支付方式组合。更新后的系统具备完善的幂等、事务、对账与退款分账能力,满足电商场景下的稳定性与一致性要求。开发者可按本文档快速扩展新支付方式,并在生产环境中获得可靠的支付处理能力。

附录:开发示例与最佳实践

添加新的支付方式(步骤)

  • 新建插件目录与 manifest.php,声明 plugin_group=payment 与 provider 类名
  • 实现 Provider:实现 start/notify/finish(可选 query/status),并在 meta 中定义配置项
  • 实现 Service:封装第三方 SDK,构造请求参数,设置 out_trade_no=payment_sn(来自 PaymentSnGenerator),回调中验签后调用 PaymentService.markSucceeded
  • 使用新的 PaymentSnGenerator:通过 PaymentService.createForOrder 自动生成唯一的 payment_sn
  • 使用新的 PaymentStatus:所有状态操作都应通过 PaymentStatus 常量,而不是硬编码字符串
  • 测试要点
    • 本地联调:模拟 notify/finish,验证幂等与订单联动
    • 对账与轮询:实现 query/status 以应对回调延迟或丢失
    • 退款:如需退款,遵循 refundOrder/markRefundSucceeded 的分账与收尾流程

章节来源

  • manifest.php(支付宝):7-10
  • manifest.php(微信支付):7-10
  • AlipayProvider.php:18-110
  • WxpayProvider.php:19-126
  • PaymentService.php:84-102
  • PaymentSnGenerator.php:39-53
  • PaymentStatus.php:37-107

处理支付异常

  • 验签失败:立即返回 fail,不更新任何状态
  • 网络异常:依靠对账与轮询兜底;记录错误日志并等待重试
  • 业务异常:如订单不可收款,保持 payment 为 pending,交由对账或人工处理
  • 状态迁移异常:PaymentStatus::canTransit() 返回 false 时,记录详细的非法状态迁移日志
  • 新增:流水号冲突异常:PaymentSnGenerator 会自动重试,但如果频繁冲突需要检查系统负载
  • 钱包功能异常:如果features.money配置为false,所有钱包操作将返回false

章节来源

  • AlipayService.php:69-88
  • PaymentService.php:172-225
  • PaymentSnGenerator.php:39-53
  • PaymentStatus.php:69-77
  • WalletService.php:127-172

实现支付日志记录

  • 统一记录 raw_callback 到 order_payment.raw_callback,便于回溯
  • 微信支付 SDK 日志输出到 storage/log/payment/wxapp/*.log
  • 关键路径记录错误日志(非法状态迁移、订单不可收款、推进失败等)
  • 新增:记录 PaymentSnGenerator 的冲突检测和重试过程,便于性能监控和问题诊断
  • 新增:记录 PaymentStatus::canTransit() 的验证结果,便于调试状态机问题

章节来源

  • PaymentService.php:670-687
  • WxpayService.php:447-455
  • PaymentSnGenerator.php:39-53
  • PaymentStatus.php:69-77

支付配置管理与多币种支持

  • 配置来源:插件 meta 中定义的字段(如 APPID、私钥、公钥、Key、货币等),通过 plugin()->getWithConfig 读取
  • 多币种:PayPal 插件 meta 中 currency_code 支持多种货币;其他插件可按需扩展
  • 渠道切换:前端收银台根据用户选择或规则动态调用不同 Provider.start
  • 钱包配置:通过Config::get('features.money', false)控制钱包功能启用

章节来源

  • PaypalProvider.php:40-72
  • AlipayService.php:177-192
  • WxpayService.php:398-414
  • WalletService.php:127-172

收银台与混合支付示例

重要更新:虽然balancepay插件已移除,但混合支付功能通过现有架构实现

  • 收银台获取订单信息并计算可用余额,支持混合支付(网关+钱包)
  • 先发起网关支付,再扣除钱包余额;每笔成功后调用 PaymentService.tryFinalizeOrder 进行收尾
  • 新增:所有支付流水号都通过 PaymentSnGenerator 生成,确保全局唯一性
  • 状态管理:所有支付状态操作都应使用 PaymentStatus 常量,确保类型安全

章节来源

  • CashierService.php:45-85
  • PaymentService.php:84-102
  • PaymentService.php:227-296
  • PaymentSnGenerator.php:39-53
  • PaymentStatus.php:37-107

使用新的 PaymentSnGenerator

最佳实践:

  • 通过 PaymentService.createForOrder 自动生成 payment_sn,不要手动生成
  • 退款时使用 PaymentService.refundOrder 自动生成 refund_sn
  • 利用 PaymentSnGenerator 的冲突检测机制,无需担心重复问题
  • 在高并发场景下,PaymentSnGenerator 的自动重试机制保证了流水号的唯一性

章节来源

  • PaymentSnGenerator.php:39-53
  • PaymentService.php:84-102
  • PaymentService.php:539-574

使用新的 PaymentStatus 枚举

最佳实践:

  • 始终使用 PaymentStatus::PENDING、PaymentStatus::SUCCEEDED 等常量,而不是硬编码字符串
  • 利用 PaymentStatus::canTransit() 进行状态迁移验证
  • 使用 PaymentStatus::isValid() 验证输入状态值
  • 利用 PaymentStatus::all() 获取所有可能的状态值

章节来源

  • PaymentStatus.php:37-107
  • PaymentService.php:172-225
  • OrderPayNameResolver.php:75-102
  • OrderReconciliation.php:105-193

钱包功能使用指南

重要更新:虽然balancepay插件已移除,但钱包功能通过WalletService继续使用

  • 启用钱包功能:确保Config::get('features.money', false)返回true
  • 余额扣款:使用WalletService.createMoney方法,传入负数金额进行扣款
  • 余额充值:使用WalletService.createMoney方法,传入正数金额进行充值
  • 混合支付:通过PaymentService.markSucceededByWallet方法实现余额支付
  • 事务安全:所有钱包操作都在事务内执行,确保数据一致性

章节来源

  • WalletService.php:127-172
  • PaymentService.php:311-391
添加日期:2026-10-05