简介
本指南面向在本项目中接入支付宝支付的开发者,覆盖网页支付(电脑网站)、手机网站支付、扫码支付(当面付)等场景的完整实现路径。文档基于仓库内现有插件代码,说明如何完成 SDK 集成、参数配置、签名校验、回调处理、订单状态同步与主动对账等关键环节,并提供流程图与调用时序图帮助理解。
注意:当前仓库未包含 APP 支付插件实现;如需 APP 支付,可参考现有插件模式扩展新的 Provider/Service。
项目结构
本项目采用“插件化”组织方式,每个支付渠道以独立插件目录呈现,包含:
- Provider:对外暴露统一接口(start/notify/finish/query/status),供系统调度
- Service:业务编排,负责组装请求、调用支付宝 SDK、处理回调与状态机推进
- manifest:声明插件元数据与配置项
- sdk:各场景对应的支付宝官方 SDK 封装
graph TB
subgraph "支付插件"
A["alipay(电脑网站)"]
B["alipaywap(手机网站)"]
C["alipayf2f(当面付/扫码)"]
end
subgraph "系统能力"
PS["PaymentService<br/>状态机推进"]
ORS["OrderReconciliation<br/>主动对账"]
end
A --> PS
B --> PS
C --> PS
ORS --> A
ORS --> B
ORS --> C
核心组件
- 电脑网站支付(alipay)
- Provider:Dou\Plugin\Alipay\AlipayProvider
- Service:Dou\Plugin\Alipay\AlipayService
- SDK:pagepay/AlipayTradeService
- 手机网站支付(alipaywap)
- Provider:Dou\Plugin\Alipaywap\AlipaywapProvider
- Service:Dou\Plugin\Alipaywap\AlipaywapService
- SDK:wappay/AlipayTradeService
- 扫码支付/当面付(alipayf2f)
- Provider:Dou\Plugin\Alipayf2f\Alipayf2fProvider
- Service:Dou\Plugin\Alipayf2f\Alipayf2fService
- SDK:f2fpay/AlipayTradeService
这些组件共同遵循统一的 PaymentRequest/PaymentCallbackPayload/PaymentQueryRequest 契约,并通过 PaymentService 推进支付台账与订单状态机。
架构总览
下图展示从发起支付到回调落库、再到主动对账的端到端流程。
sequenceDiagram
participant U as "用户浏览器"
participant P as "支付入口(前端/后端)"
participant Prov as "Provider(按渠道)"
participant Svc as "Service(业务编排)"
participant SDK as "支付宝SDK"
participant Ali as "支付宝网关"
participant PS as "PaymentService"
participant Cron as "定时对账"
U->>P : 选择支付方式并下单
P->>Prov : start(PaymentRequest)
Prov->>Svc : start()
Svc->>SDK : 构建请求并生成支付表单/二维码
SDK->>Ali : 提交支付
Ali-->>U : 跳转至支付宝收银台
Ali-->>Svc : notify/finish(异步/同步回调)
Svc->>PS : markSucceeded(paymentSn, tradeNo, raw)
Note over Svc,PS : 幂等推进支付成功状态
Cron->>Svc : query(PaymentQueryRequest)
Svc->>SDK : 查询交易状态
SDK->>Ali : alipay.trade.query
Ali-->>Svc : 返回交易结果
Svc->>PS : 根据结果更新为成功/关闭/待处理
详细组件分析
电脑网站支付(alipay)
- 发起支付:通过 pagepay 的 AlipayTradePagePayContentBuilder 构造页面支付请求,使用 RSA2 签名,返回 HTML 表单由浏览器自动提交至支付宝。
- 回调处理:notify 与 finish 均会验签,成功后调用 PaymentService::markSucceeded 推进状态。
- 主动对账:query 使用 alipay.trade.query,将 TRADE_SUCCESS/TRADE_FINISHED 映射为成功,TRADE_CLOSED 映射为关闭,其他为待处理。
flowchart TD
Start(["开始"]) --> BuildCfg["加载配置(app_id/私钥/公钥)"]
BuildCfg --> CheckCfg{"配置是否完整?"}
CheckCfg -- 否 --> Err["抛出异常/返回失败"]
CheckCfg -- 是 --> BuildReq["构建页面支付请求<br/>subject/totalAmount/outTradeNo"]
BuildReq --> CallSDK["调用 SDK pagePay"]
CallSDK --> ReturnHTML["返回HTML表单给浏览器"]
ReturnHTML --> End(["结束"])
手机网站支付(alipaywap)
- 发起支付:使用 wappay 的 AlipayTradeWapPayContentBuilder,设置移动端超时时间等参数,调用 wapPay 输出支付页面。
- 回调与对账:与电脑网站一致,但 require 路径指向 wappay SDK。
sequenceDiagram
participant U as "用户"
participant W as "AlipaywapService"
participant SDK as "wappay SDK"
participant Ali as "支付宝"
U->>W : 发起手机网站支付
W->>SDK : wapPay(builder, return_url, notify_url)
SDK->>Ali : 打开支付宝H5收银台
Ali-->>W : notify/finish
W->>W : 验签+提取out_trade_no/trade_no
W->>W : PaymentService.markSucceeded
扫码支付/当面付(alipayf2f)
- 创建二维码:调用 f2fpay 的 AlipayTradePrecreateContentBuilder 生成二维码内容,前端渲染二维码并轮询 status 接口。
- 轮询与回调:status 用于前端轮询,notify/finish 用于异步通知与同步回跳。
- 主动对账:query 与主 alipay 保持一致的状态映射规则。
sequenceDiagram
participant F as "前端"
participant S as "Alipayf2fService"
participant Q as "轮询接口"
participant SDK as "f2fpay SDK"
participant Ali as "支付宝"
F->>S : start(金额/订单号/商品名)
S->>SDK : qrPay(builder)
SDK-->>S : 返回qr_code
S-->>F : 返回二维码图片URL + JS轮询脚本
loop 每N秒
F->>Q : POST {out_trade_no}
Q->>S : status(payload)
S->>SDK : queryTradeResult(out_trade_no)
SDK->>Ali : 查询交易
Ali-->>SDK : 返回状态
alt 已支付
SDK-->>S : SUCCESS
S->>S : markSucceeded()
S-->>F : SUCCESS
else 未支付
SDK-->>S : 非SUCCESS
S-->>F : FAIL
end
end
支付回调与订单状态同步
- 所有渠道在 notify/finish 中先进行签名校验,再提取 out_trade_no 与 trade_no,调用 PaymentService::markSucceeded 推进状态。
- 成功时可选发送站内邮件通知(部分渠道)。
flowchart TD
NStart(["收到回调"]) --> Verify["验签(check/rsaCheckV1)"]
Verify --> |失败| Fail["返回fail/重定向"]
Verify --> |成功| Extract["提取 paymentSn/tradeNo"]
Extract --> Mark["PaymentService.markSucceeded"]
Mark --> NotifyMail{"是否需要发送邮件?"}
NotifyMail -- 是 --> Send["发送支付成功通知"]
NotifyMail -- 否 --> Redirect["重定向到订单页"]
Send --> Redirect
主动对账(定时任务)
- 系统提供定时任务入口,周期性调用 OrderReconciliation::reconcilePendingPayments,内部对各渠道 query 方法执行对账。
- 各渠道 query 将支付宝返回的交易状态映射为 succeeded/closed/pending/notFound。
sequenceDiagram
participant Cron as "定时任务"
participant OS as "OrderScheduledTasks"
participant OR as "OrderReconciliation"
participant Prov as "各渠道Provider"
participant Svc as "各渠道Service"
participant SDK as "支付宝SDK"
participant Ali as "支付宝"
Cron->>OS : reconcilePendingPayments()
OS->>OR : reconcilePendingPayments(options)
OR->>Prov : query(PaymentQueryRequest)
Prov->>Svc : query()
Svc->>SDK : Query / queryTradeResult
SDK->>Ali : 查询交易
Ali-->>SDK : 返回结果
SDK-->>Svc : 返回对象/数组
Svc->>OR : PaymentQueryResult(succeeded/closed/pending/notFound)
OR->>Svc : 必要时再次 markSucceeded
依赖关系分析
- Provider 仅做路由与透传,Service 承载具体业务逻辑。
- Service 依赖支付宝 SDK 的不同子模块(pagepay/wappay/f2fpay)。
- 所有渠道共享 PaymentService 作为状态机推进点,保证幂等与一致性。
- 定时任务通过 OrderScheduledTasks 统一触发对账。
classDiagram
class AlipayProvider
class AlipayService
class AlipaywapProvider
class AlipaywapService
class Alipayf2fProvider
class Alipayf2fService
class PaymentService
class AlipayTradeService_pagepay
class AlipayTradeService_wappay
class AlipayTradeService_f2fpay
AlipayProvider --> AlipayService : "委托"
AlipaywapProvider --> AlipaywapService : "委托"
Alipayf2fProvider --> Alipayf2fService : "委托"
AlipayService --> PaymentService : "markSucceeded"
AlipaywapService --> PaymentService : "markSucceeded"
Alipayf2fService --> PaymentService : "markSucceeded"
AlipayService --> AlipayTradeService_pagepay : "调用"
AlipaywapService --> AlipayTradeService_wappay : "调用"
Alipayf2fService --> AlipayTradeService_f2fpay : "调用"
性能与可靠性
- 签名校验优先:回调入口先验签再执行业务,避免无效请求进入状态机。
- 幂等推进:通过 PaymentService::markSucceeded 保证重复回调不重复入账。
- 主动对账兜底:定时任务定期拉取交易状态,弥补网络或回调丢失风险。
- 错误隔离:各渠道 query 捕获异常并返回标准化结果,不影响整体对账流程。
故障排查指南
- 配置不完整:若 app_id/merchant_private_key/alipay_public_key 缺失,会在 start 阶段抛出异常或返回失败。请检查插件配置。
- 验签失败:notify/finish 验签失败将直接返回 fail 或重定向,需核对支付宝公钥与签名算法(RSA2)。
- 查询无结果:query 返回 code=40004 视为 notFound,可能是订单尚未创建或已过期,建议等待后重试或提示用户。
- 轮询无响应:当面付前端轮询间隔与上限已在服务中内置,如长时间未支付,应引导用户重新生成二维码。
结论
本项目通过 Provider/Service/Sdk 的分层设计,实现了支付宝多场景支付的统一接入与可靠闭环。借助 PaymentService 的状态机与定时对账机制,保证了支付结果的最终一致性与容错能力。对于尚未实现的 APP 支付,可参照现有插件模式新增对应 Provider/Service。
附录:配置与常见问题
配置项说明(各渠道通用)
- app_id:支付宝开放平台应用 APPID
- merchant_private_key:应用私钥(商户私钥)
- alipay_public_key:支付宝公钥
- sign_type:固定为 RSA2
- charset:UTF-8
- gatewayUrl:https://openapi.alipay.com/gateway.do
- notify_url/return_url:由各自 Service 的 buildConfig 生成
常见场景与要点
- 网页支付(电脑网站):使用 pagepay 的页面支付,返回 HTML 表单由浏览器自动提交。
- 手机网站支付:使用 wappay 的 wapPay,适合移动端 H5 环境。
- 扫码支付(当面付):生成二维码并轮询 status,同时支持异步 notify 回调。
- 退款申请:当前仓库未提供退款相关实现;可在 Service 中扩展调用相应 API 并维护本地退款单。
- 交易查询:各渠道均已实现 query,用于主动对账与状态同步。