简介
本文件面向电商开发者,系统化说明 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 行
- 新增功能:提供23位唯一支付流水号生成,格式为
-
支付状态枚举(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