简介
本文件面向DouPHP支付插件系统的开发者,系统性阐述支付插件的架构设计、统一接口、回调处理机制、状态管理、订单同步、退款与对账等关键能力。文档基于仓库中已实现的支付宝、微信支付、PayPal、Stripe等支付插件代码进行提炼,帮助读者快速理解并扩展新的支付方式。
项目结构
支付插件采用“Provider + Service”的分层模式:
- Provider:对外暴露统一的支付生命周期方法(start/notify/finish/query/status),实现具体网关接入契约。
- Service:封装各支付渠道的业务逻辑,负责参数组装、SDK调用、验签、状态推进与异常处理。
- manifest.php:声明插件分组与Provider类名,供系统加载。
graph TB
subgraph "支付插件"
A["支付宝<br/>AlipayProvider / AlipayService"]
B["微信支付<br/>WxpayProvider / WxpayService"]
C["PayPal<br/>PaypalProvider"]
D["Stripe<br/>StripeProvider"]
end
subgraph "系统核心"
E["PaymentService<br/>统一状态机与订单联动"]
F["路由/中间件<br/>入口与鉴权"]
end
A --> E
B --> E
C --> E
D --> E
F --> A
F --> B
F --> C
F --> D
核心组件
- 统一支付接口
- start(PaymentRequest): 发起支付,返回跳转URL或前端交互内容。
- notify(PaymentCallbackPayload): 异步通知处理,完成验签与幂等处理,调用PaymentService推进状态。
- finish(PaymentCallbackPayload): 同步回跳处理,用于页面跳转与提示。
- query(PaymentQueryRequest): 主动对账查询,返回统一结果对象。
- status(PaymentCallbackPayload): 部分渠道支持轮询查询(如微信Native扫码)。
- 业务服务
- 各渠道Service负责构建请求、调用官方SDK、解析响应、签名校验、错误码映射、原始报文落盘等。
- 配置元数据
- Provider.meta()定义插件名称、描述、版本、适用客户端、配置项表单字段等,便于后台动态渲染配置页。
架构总览
支付流程遵循“发起支付 -> 第三方支付 -> 异步通知/同步回跳 -> 统一状态机 -> 订单状态联动”的模式。不同渠道在start阶段差异较大(网页跳转、JSAPI唤起、扫码生成、托管支付页),但在notify/finish/query上通过统一接口收敛。
sequenceDiagram
participant U as "用户浏览器"
participant P as "Provider(渠道)"
participant S as "Service(渠道业务)"
participant PS as "PaymentService(统一状态机)"
participant G as "第三方网关"
U->>P : 调用 start(request)
P->>S : start(request)
S->>G : 创建订单/获取支付参数
G-->>S : 返回支付链接/二维码/JS参数
S-->>P : 返回跳转或前端脚本
P-->>U : 展示支付界面
Note over U,G : 用户在第三方完成支付
G-->>S : 异步通知 notify(payload)
S->>S : 验签/幂等检查
S->>PS : markSucceeded(paymentSn, transactionId, raw)
PS-->>S : 成功/失败
S-->>G : 返回确认(如 success/FAIL)
U->>P : 同步回跳 finish(payload)
P->>S : finish(payload)
S-->>P : 返回订单页路由
P-->>U : 重定向到订单页
详细组件分析
支付宝插件(alipay)
- 特点
- 电脑网站支付,使用AOP SDK进行页面支付。
- 支持主动对账(query),以paymentSn作为out_trade_no查询交易状态。
- notify/finish均先验签再调用PaymentService推进状态。
- 关键流程
- start:构造支付内容并调用SDK pagePay,返回跳转URL。
- notify:验签通过后,提取paymentSn与trade_no,调用markSucceeded。
- finish:验签通过后,再次尝试标记成功并发送邮件通知。
- query:根据trade_status映射为succeeded/closed/pending/notFound。
- 配置项
- app_id、merchant_private_key、alipay_public_key、return_url、notify_url等由Service自动拼接。
flowchart TD
Start(["开始"]) --> BuildCfg["读取插件配置"]
BuildCfg --> CheckCfg{"配置完整?"}
CheckCfg -- 否 --> Err["抛出配置不完整异常"]
CheckCfg -- 是 --> PagePay["调用SDK pagePay"]
PagePay --> ReturnUrl["返回支付跳转URL"]
ReturnUrl --> End(["结束"])
微信支付插件(wxpay)
- 特点
- 按UA智能选择JSAPI(微信内)、H5(移动端)、Native(PC扫码)。
- Native扫码支持轮询status接口,命中SUCCESS后推进状态。
- 支持主动对账query,将trade_state映射为统一结果。
- 统一notify入口,内部委托NotifyCallback处理验签与业务。
- 关键流程
- start:根据设备类型分发至startJsapi/startH5/startNative。
- notify:初始化SDK与日志,委托NotifyCallback处理。
- status:按paymentSn查询订单,若SUCCESS则调用markSucceeded。
- query:将微信返回码映射为succeeded/closed/pending/notFound。
- 配置项
- appid、appsecret、mchid、key、证书路径等。
sequenceDiagram
participant U as "用户"
participant WX as "微信支付"
participant WS as "WxpayService"
participant PS as "PaymentService"
U->>WS : start(request)
WS->>WX : 统一下单(JSAPI/H5/Native)
WX-->>WS : 返回支付参数/二维码
WS-->>U : 展示支付界面
WX-->>WS : 异步通知 notify
WS->>WS : 验签/日志
WS->>PS : markSucceeded(paymentSn, tid, raw)
PS-->>WS : 成功
WS-->>WX : 返回空串(成功)
U->>WS : 同步回跳 finish
WS-->>U : 跳转订单页
PayPal插件(paypal)
- 特点
- 基础Provider实现,提供meta配置与start/notify/finish转发。
- 适用于简单跳转型支付场景。
- 关键流程
- start:交由Service生成支付表单或跳转链接。
- notify/finish:由Service处理IPN或回跳逻辑。
Stripe插件(stripe)
- 特点
- 基于Stripe Checkout(Hosted Sessions)模式,start创建Session并跳转至Stripe托管页。
- notify接收Webhook并验签;finish处理success_url回跳;query通过PaymentIntents API主动对账。
- 关键流程
- start:创建Checkout Session并返回跳转URL。
- notify:验证Webhook签名,解析事件,更新本地支付记录。
- finish:根据session信息跳转订单页。
- query:根据paymentIntent状态映射为succeeded/closed/pending。
依赖关系分析
- 插件与核心
- 所有Provider均依赖PaymentService进行状态推进与订单联动。
- Service依赖各自渠道SDK与平台配置。
- 耦合与内聚
- Provider仅做路由与DTO转换,内聚于Service;Service集中处理渠道差异,降低上层耦合。
- 外部依赖
- 支付宝AOP SDK、微信支付SDK、Stripe API、PayPal IPN/REST等。
classDiagram
class PaymentPluginProviderInterface
class ReconcilablePaymentProviderInterface
class PollablePaymentProviderInterface
class PaymentRequest
class PaymentCallbackPayload
class PaymentQueryRequest
class PaymentQueryResult
class PaymentService
class AlipayProvider
class AlipayService
class WxpayProvider
class WxpayService
class PaypalProvider
class StripeProvider
AlipayProvider ..|> ReconcilablePaymentProviderInterface
WxpayProvider ..|> ReconcilablePaymentProviderInterface
WxpayProvider ..|> PollablePaymentProviderInterface
StripeProvider ..|> ReconcilablePaymentProviderInterface
PaypalProvider ..|> PaymentPluginProviderInterface
AlipayProvider --> AlipayService : "委托"
WxpayProvider --> WxpayService : "委托"
StripeProvider --> StripeService : "委托"
AlipayService --> PaymentService : "调用"
WxpayService --> PaymentService : "调用"
StripeService --> PaymentService : "调用"
性能与可靠性
- 幂等性
- 通过paymentSn唯一标识支付尝试,notify/finish需保证幂等,避免重复入账。
- 重试与补偿
- 异步通知可能丢失或乱序,建议结合query主动对账进行补偿。
- 超时与限流
- 对第三方API调用设置合理超时;对高频轮询(如Native扫码)控制频率与上限。
- 日志与可观测性
- 记录原始报文与关键状态变化,便于问题定位与审计。
故障排查指南
- 常见错误
- 配置缺失:如APPID、私钥、公钥未配置导致start失败。
- 验签失败:notify/finish验签不通过,检查密钥与时间戳、随机数。
- 状态不一致:异步通知延迟或丢失,使用query主动对账补齐。
- 轮询失败:Native扫码status接口返回FAIL,检查paymentSn与网络。
- 定位步骤
- 查看Service日志与原始报文;核对第三方返回码与本地映射。
- 检查PaymentService状态机是否被正确推进。
- 复现时开启调试日志,逐步缩小范围。
结论
DouPHP支付插件体系通过Provider+Service分层与统一接口抽象,有效屏蔽了多渠道差异,提供了稳定的支付生命周期管理与状态推进机制。结合主动对账、轮询查询与完善的日志记录,能够保障支付流程的可靠性与可维护性。新增支付方式只需实现对应Provider与Service,即可快速接入系统。
附录:开发示例与最佳实践
新增支付插件步骤
- 创建Provider
- 实现PaymentPluginProviderInterface或其增强接口(如ReconcilablePaymentProviderInterface)。
- 实现pluginId、meta、start、notify、finish、可选query/status。
- 创建Service
- 封装渠道SDK调用、参数构建、验签、错误码映射、原始报文保存。
- 通过PaymentService.markSucceeded推进状态,确保幂等。
- 注册插件
- 在manifest.php声明plugin_group与provider类名。
- 配置项
- 在meta.config中定义字段、类型、默认值与说明,便于后台配置。
安全与合规要点
- 签名与验签
- 所有notify/finish必须严格验签,防止伪造请求。
- 敏感信息保护
- 私钥、密钥、证书等不得硬编码,使用配置中心或环境变量管理。
- 防重放攻击
- 使用nonce、timestamp、order_sn等组合校验,限制时间窗口。
- 最小权限原则
- Webhook仅暴露必要端点,限制来源IP与Content-Type。
测试与部署
- 测试环境
- 使用沙箱账号与测试密钥;模拟异步通知与回跳。
- 覆盖成功、失败、超时、重复通知等场景。
- 生产环境
- 启用正式密钥与证书;配置HTTPS与访问白名单。
- 开启详细日志与监控告警;定期演练对账与退款流程。