简介
本指南面向希望在 DouPHP 框架中开发插件的开发者,覆盖插件目录结构规范、配置文件格式、服务类编写方法;并给出支付插件、物流插件、社交登录插件等类型的具体实现步骤。文档同时提供插件 API 参考、钩子与事件使用方式、测试与调试技巧以及常见问题解决方案。
项目结构
DouPHP 的插件体系位于 plugin 目录下,每个插件是一个独立目录,包含 manifest.php 声明文件、Provider 类、Service 类及可选 SDK/资源。核心通过 ManifestValidator 校验 manifest 返回值,并通过 Registry 自动发现 Provider。
graph TB
A["plugin 目录"] --> B["alipay 插件"]
A --> C["wxpay 插件"]
A --> D["cod 插件"]
A --> E["paypal 插件"]
A --> F["ems 插件"]
A --> G["qq 插件"]
A --> H["google 插件"]
B --> B1["manifest.php"]
B --> B2["AlipayProvider.php"]
B --> B3["AlipayService.php"]
C --> C1["manifest.php"]
C --> C2["WxpayProvider.php"]
D --> D1["CodProvider.php"]
E --> E1["PaypalProvider.php"]
F --> F1["EmsProvider.php"]
G --> G1["QqProvider.php"]
H --> H1["manifest.php"]
图表来源
- plugin/alipay/manifest.php:7-10
- plugin/wxpay/manifest.php:7-10
- plugin/cod/CodProvider.php:1-57
- plugin/paypal/PaypalProvider.php:1-81
- plugin/ems/EmsProvider.php:1-71
- plugin/qq/QqProvider.php:1-83
- plugin/google/manifest.php:7-10
章节来源
- plugin/alipay/manifest.php:7-10
- plugin/wxpay/manifest.php:7-10
- core/infra/plugin/ManifestValidator.php:35-63
核心组件
- 插件清单校验器:对 manifest.php 返回数组进行白名单校验,限制 plugin_group 为 payment/connect/shipping,provider 必须为 Dou\Plugin\ 命名空间下的合法 FQCN。
- 插件注册中心:扫描 plugin 目录,加载 manifest.php,解析 provider 并实例化对应类,按分组暴露能力(支付、登录、物流)。
- Provider 接口族:定义不同插件类型的统一契约,如支付、可轮询支付、可对账支付、物流、社交登录。
- DTO 数据对象:封装请求与回调载荷,如 PaymentRequest、PaymentCallbackPayload、PaymentQueryRequest、PaymentQueryResult、ConnectStartRequest、ConnectCallbackPayload。
- 业务服务基类与支付服务:BaseService 提供通用能力;PaymentService 负责订单支付状态机推进、通知处理与结果落库。
章节来源
- core/infra/plugin/ManifestValidator.php:21-32
- core/infra/plugin/ManifestValidator.php:35-63
- core/infra/plugin/registry/ConnectPluginRegistry.php:121-147
- core/infra/plugin/contract/PaymentPluginProviderInterface.php
- core/infra/plugin/contract/ReconcilablePaymentProviderInterface.php
- core/infra/plugin/contract/PollablePaymentProviderInterface.php
- core/infra/plugin/contract/ShippingPluginProviderInterface.php
- core/infra/plugin/contract/ConnectPluginProviderInterface.php
- core/infra/plugin/dto/PaymentRequest.php
- core/infra/plugin/dto/PaymentCallbackPayload.php
- core/infra/plugin/dto/PaymentQueryRequest.php
- core/infra/plugin/dto/PaymentQueryResult.php
- core/infra/plugin/dto/ConnectStartRequest.php
- core/infra/plugin/dto/ConnectCallbackPayload.php
- core/service/BaseService.php
- core/service/Payment/PaymentService.php
架构总览
插件系统采用“声明式清单 + 接口契约 + 自动发现”的模式:
- 每个插件在 plugin/<slug>/manifest.php 声明分组与 Provider 类名。
- 核心通过 ManifestValidator 校验清单合法性,防止恶意或错误配置。
- Registry 扫描并实例化 Provider,按分组对外暴露能力。
- Provider 仅做薄封装,具体业务逻辑下沉到 Service。
- 支付流程通过 PaymentService 统一推进状态机,保证一致性。
sequenceDiagram
participant 前端 as "前端/后台"
participant 路由 as "Admin/Route"
participant 注册表 as "ConnectPluginRegistry"
participant 校验器 as "ManifestValidator"
participant 提供者 as "Provider(各插件)"
participant 服务 as "Service(各插件)"
participant 支付服务 as "PaymentService"
前端->>路由 : 访问插件管理或调用支付/登录
路由->>注册表 : 根据分组查找 Provider
注册表->>校验器 : 校验 manifest.php
校验器-->>注册表 : 返回合法 provider 类名
注册表->>提供者 : 实例化 Provider
前端->>提供者 : 调用 start/finish/notify/query/methods
提供者->>服务 : 委托具体业务
服务->>支付服务 : 标记成功/查询/回调处理
支付服务-->>服务 : 返回状态
服务-->>提供者 : 返回结果
提供者-->>前端 : 返回响应
图表来源
- core/infra/plugin/registry/ConnectPluginRegistry.php:121-147
- core/infra/plugin/ManifestValidator.php:73-106
- plugin/alipay/AlipayProvider.php:75-109
- plugin/alipay/AlipayService.php:44-87
- core/service/Payment/PaymentService.php
详细组件分析
支付插件(以支付宝为例)
- 清单 manifest.php 声明 plugin_group=payment 与 provider 类名。
- Provider 实现 ReconcilablePaymentProviderInterface,提供 pluginId、meta、start、notify、finish、query。
- Service 负责与第三方 SDK 交互、验签、构建请求、调用 PaymentService 推进状态机。
classDiagram
class AlipayProvider {
+pluginId() string
+meta() array
+start(request) string
+notify(payload) string
+finish(payload) string
+query(request) PaymentQueryResult
}
class AlipayService {
+start(request) string
+notify(payload) string
+finish(payload) string
+query(request) PaymentQueryResult
-buildConfig() array
-encodeRaw(data) string
-responseToArray(response) array|null
}
class PaymentService {
+markSucceeded(paymentSn, transactionId, raw) bool
+findBySn(paymentSn) array
}
AlipayProvider --> AlipayService : "委托业务"
AlipayService --> PaymentService : "推进状态机"
图表来源
- plugin/alipay/AlipayProvider.php:15-110
- plugin/alipay/AlipayService.php:20-229
- core/service/Payment/PaymentService.php
章节来源
- plugin/alipay/manifest.php:7-10
- plugin/alipay/AlipayProvider.php:15-110
- plugin/alipay/AlipayService.php:20-229
微信支付(支持轮询与对账)
- Provider 实现 ReconcilablePaymentProviderInterface 与 PollablePaymentProviderInterface,额外提供 status 用于扫码轮询。
- meta 中定义 AppID、AppSecret、商户号、API 密钥等配置项。
sequenceDiagram
participant 客户端 as "客户端"
participant WxProvider as "WxpayProvider"
participant WxService as "WxpayService"
participant PaySvc as "PaymentService"
客户端->>WxProvider : start(PaymentRequest)
WxProvider->>WxService : start(request)
WxService-->>客户端 : 支付参数/二维码
客户端->>WxProvider : status(PaymentCallbackPayload)
WxProvider->>WxService : status(payload)
WxService-->>客户端 : trade_state | FAIL
客户端->>WxProvider : notify(PaymentCallbackPayload)
WxProvider->>WxService : notify(payload)
WxService->>PaySvc : markSucceeded(...)
PaySvc-->>WxService : 成功
WxService-->>客户端 : success
图表来源
- plugin/wxpay/WxpayProvider.php:16-126
- core/infra/plugin/contract/PollablePaymentProviderInterface.php
- core/infra/plugin/contract/ReconcilablePaymentProviderInterface.php
- core/service/Payment/PaymentService.php
章节来源
- plugin/wxpay/manifest.php:7-10
- plugin/wxpay/WxpayProvider.php:16-126
货到付款与 PayPal
- 货到付款 Provider 实现 PaymentPluginProviderInterface,提供基础支付能力。
- PayPal Provider 同样实现 PaymentPluginProviderInterface,并在 meta 中定义货币选择等配置。
章节来源
- plugin/cod/CodProvider.php:13-57
- plugin/paypal/PaypalProvider.php:13-81
物流插件(以 EMS 为例)
- Provider 实现 ShippingPluginProviderInterface,提供 methods 返回配送方式与费用规则。
- meta 中定义费用、包邮门槛等配置项。
章节来源
- plugin/ems/EmsProvider.php:11-71
- core/infra/plugin/contract/ShippingPluginProviderInterface.php
社交登录插件(QQ、Google)
- QQ Provider 实现 ConnectPluginProviderInterface,提供 start 与 finish。
- Google 通过 manifest.php 声明 connect 分组与 provider 类名。
章节来源
- plugin/qq/QqProvider.php:13-83
- plugin/google/manifest.php:7-10
- core/infra/plugin/contract/ConnectPluginProviderInterface.php
插件清单校验与安全
- ManifestValidator 严格校验 manifest.php 返回数组键名、plugin_group 取值范围、provider 命名空间前缀,避免任意类加载风险。
章节来源
- core/infra/plugin/ManifestValidator.php:21-32
- core/infra/plugin/ManifestValidator.php:35-63
- core/infra/plugin/ManifestValidator.php:73-106
依赖关系分析
- 插件 Provider 依赖各自 Service,Service 依赖核心 BaseService 与 PaymentService。
- 支付回调与完成流程通过 PaymentService 统一处理,确保订单状态一致。
- 管理员端通过 admin/route/plugin.php 暴露插件安装/禁用等管理操作。
graph LR
P1["AlipayProvider"] --> S1["AlipayService"]
P2["WxpayProvider"] --> S2["WxpayService"]
P3["CodProvider"] --> S3["CodService"]
P4["PaypalProvider"] --> S4["PaypalService"]
P5["EmsProvider"] --> S5["EmsService"]
P6["QqProvider"] --> S6["QqService"]
S1 --> PS["PaymentService"]
S2 --> PS
S3 --> PS
S4 --> PS
PS --> DB["数据库"]
图表来源
- plugin/alipay/AlipayProvider.php:15-110
- plugin/wxpay/WxpayProvider.php:16-126
- plugin/cod/CodProvider.php:13-57
- plugin/paypal/PaypalProvider.php:13-81
- plugin/ems/EmsProvider.php:11-71
- plugin/qq/QqProvider.php:13-83
- core/service/Payment/PaymentService.php
章节来源
- admin/route/plugin.php:15-34
- core/service/Payment/PaymentService.php
性能与可靠性
- 支付回调与完成路径应尽快验签并调用 PaymentService 推进状态,减少阻塞时间。
- 主动对账(query)需捕获异常并返回失败结果,避免影响主流程。
- 轮询支付(如微信 Native)应在服务端合理设置轮询间隔与最大次数,避免高频请求。
- 配置校验应在 start 阶段尽早失败,避免无效请求进入第三方 SDK。
故障排查指南
- 清单校验失败:检查 manifest.php 是否只包含允许键(plugin_group、provider),plugin_group 是否为 payment/connect/shipping,provider 是否为 Dou\Plugin\ 命名空间下的合法类名。
- 支付回调失败:确认 notify_url 与 return_url 配置正确,验签通过后调用 PaymentService::markSucceeded。
- 轮询无结果:检查 status 接口返回 trade_state,必要时调整轮询策略。
- 管理端无法安装/禁用:确认 admin/route/plugin.php 路由可用,插件模块已启用且数据库表存在。
章节来源
- core/infra/plugin/ManifestValidator.php:73-106
- plugin/alipay/AlipayService.php:69-87
- plugin/wxpay/WxpayProvider.php:107-126
- admin/route/plugin.php:15-34
结论
DouPHP 插件体系通过严格的清单校验、统一的接口契约与自动发现机制,提供了安全、可扩展的扩展点。开发者只需遵循 manifest 规范与 Provider 接口,即可快速实现支付、物流、社交登录等功能。借助 PaymentService 的状态机与 DTO 模型,可确保业务流程的一致性与可维护性。
附录:API参考与模板
插件清单 manifest.php 字段
- plugin_group:必填,值为 payment、connect、shipping 之一。
- provider:必填,FQCN 必须以 Dou\Plugin\ 开头,后接至少两段命名空间段。
章节来源
- core/infra/plugin/ManifestValidator.php:35-63
- core/infra/plugin/ManifestValidator.php:73-106
- plugin/alipay/manifest.php:7-10
- plugin/wxpay/manifest.php:7-10
- plugin/google/manifest.php:7-10
支付插件 Provider 接口方法
- pluginId:返回插件唯一标识。
- meta:返回名称、描述、版本、分组、客户端限制与配置项定义。
- start:发起支付,返回跳转地址或支付参数。
- notify:异步通知处理,验签后调用 PaymentService 推进状态。
- finish:同步完成处理,常用于用户页面重定向。
- query:主动对账,返回 PaymentQueryResult。
章节来源
- core/infra/plugin/contract/PaymentPluginProviderInterface.php
- core/infra/plugin/contract/ReconcilablePaymentProviderInterface.php
- plugin/alipay/AlipayProvider.php:31-109
- plugin/wxpay/WxpayProvider.php:32-125
物流插件 Provider 接口方法
- pluginId:返回插件唯一标识。
- meta:返回名称、描述、版本、分组、客户端限制与配置项定义。
- methods:返回可用的配送方法与费用规则。
章节来源
- core/infra/plugin/contract/ShippingPluginProviderInterface.php
- plugin/ems/EmsProvider.php:27-69
社交登录插件 Provider 接口方法
- pluginId:返回插件唯一标识。
- meta:返回名称、描述、版本、分组、客户端限制与配置项定义。
- start:发起授权跳转。
- finish:处理回调并完成登录绑定。
章节来源
- core/infra/plugin/contract/ConnectPluginProviderInterface.php
- plugin/qq/QqProvider.php:29-81
支付流程时序(支付宝)
sequenceDiagram
participant 用户 as "用户"
participant 前端 as "前台页面"
participant 提供者 as "AlipayProvider"
participant 服务 as "AlipayService"
participant 支付服务 as "PaymentService"
用户->>前端 : 提交订单
前端->>提供者 : start(PaymentRequest)
提供者->>服务 : start(request)
服务-->>前端 : 返回支付跳转地址
用户->>服务 : notify(PaymentCallbackPayload)
服务->>支付服务 : markSucceeded(paymentSn, tradeNo, raw)
支付服务-->>服务 : 成功
服务-->>前端 : success
图表来源
- plugin/alipay/AlipayProvider.php:75-109
- plugin/alipay/AlipayService.php:44-87
- core/service/Payment/PaymentService.php
支付流程流程图(通用)
flowchart TD
Start(["开始"]) --> BuildReq["构建支付请求"]
BuildReq --> ValidateCfg{"配置完整?"}
ValidateCfg -- 否 --> FailCfg["返回配置不完整错误"]
ValidateCfg -- 是 --> CallThird["调用第三方支付SDK"]
CallThird --> Notify["接收异步通知"]
Notify --> Verify["验签与参数校验"]
Verify -- 失败 --> FailNotify["返回失败"]
Verify -- 成功 --> MarkSuccess["调用 PaymentService 标记成功"]
MarkSuccess --> Finish["同步完成处理"]
Finish --> End(["结束"])
FailCfg --> End
FailNotify --> End
图表来源
- plugin/alipay/AlipayService.php:44-87
- core/service/Payment/PaymentService.php
插件管理与路由
- 后台通过 admin/route/plugin.php 暴露插件安装与禁用等操作。
- 插件表由 admin/model/plugin/Plugin.php 映射,字段包括 slug、name、config、plugin_group、allow_client、description。
章节来源
- admin/route/plugin.php:15-34
- admin/model/plugin/Plugin.php:24-71
最佳实践
- 将第三方 SDK 引入放在 Service 层,保持 Provider 轻量。
- 所有外部调用需捕获异常并返回明确的失败结果。
- 配置项在 meta 中集中声明,便于后台可视化编辑。
- 使用 PaymentService 统一推进状态,避免重复造轮子。
- 对敏感配置(私钥、密钥)进行加密存储与最小权限访问。