文档目录
微信支付集成

简介

本文件面向开发者,系统化说明在本项目中如何集成微信支付,覆盖 JSAPI、Native、H5、小程序支付四种方式的实现要点;并给出通知处理、订单查询、退款申请、关闭订单等关键流程的落地方式与排错建议。文档基于仓库内实际代码进行分析与归纳,便于快速上手与二次开发。

项目结构

微信支付能力以“插件”形式提供,核心位于 plugin/wxpay 目录,对外暴露 Provider 接口,内部通过 SDK 完成统一下单、签名验签、回调处理等。小程序端支付在 api 层提供独立控制器与服务,用于小程序环境下的统一下单与参数组装。

graph TB
subgraph "前端/客户端"
FE["浏览器/小程序"]
end
subgraph "应用入口"
API["API 控制器<br/>WeixinController"]
ROUTE["路由/中间件"]
end
subgraph "支付插件"
PROV["WxpayProvider"]
SVC["WxpayService"]
NCALL["Internal\\NotifyCallback"]
QR["qrcode.php"]
end
subgraph "微信SDK"
SDK_API["WxPayApi / WxPayConfig"]
APP_PAY["wechatAppPay.class.php"]
end
subgraph "外部系统"
WX["微信支付平台"]
end
FE --> API
API --> SVC
SVC --> SDK_API
SVC --> APP_PAY
SVC --> QR
SVC --> NCALL
SVC --> WX
API --> WX

核心组件

  • WxpayProvider:对外暴露支付插件能力(start/notify/finish/status/query),供框架统一调度。
  • WxpayService:业务编排层,负责按 UA 选择支付方式(JSAPI/Native/H5)、统一下单、轮询状态、异步通知处理、对账查询。
  • Internal\NotifyCallback:继承 SDK 的 WxPayNotify,重写签名校验与订单查询,成功后调用 PaymentService 推进订单与支付单状态。
  • API WeixinController + WxPayService:小程序端发起支付的专用控制器与服务,负责统一下单与返回小程序支付参数。
  • qrcode.php:生成 Native 扫码二维码图片,供页面展示。

架构总览

整体采用“控制器/服务 -> 插件 Provider -> 业务 Service -> SDK”的分层设计。不同终端通过 UA 或上下文自动选择支付方式;所有支付结果最终通过统一的异步通知与主动查询机制收敛到 PaymentService,保证幂等与一致性。

sequenceDiagram
participant U as "用户"
participant C as "WeixinController"
participant S as "WxpayService"
participant P as "WxpayProvider"
participant N as "NotifyCallback"
participant X as "微信支付"
U->>C : 发起支付(小程序/网页)
C->>S : 构建下单参数/调用统一下单
S->>X : 统一下单(NATIVE/JSAPI/MWEB)
X-->>S : 返回预支付信息/二维码URL
S-->>C : 返回前端所需参数
Note over S,X : 支付完成后微信回调
X->>P : 回调通知
P->>N : 验签+二次查询
N->>S : markSucceeded(推进状态)
S-->>U : 跳转订单页/轮询成功

详细组件分析

支付方式与入口分发

  • 入口:WxpayProvider::start 委托给 WxpayService::start。
  • 分发策略:根据 UA 判断 MicroMessenger 走 JSAPI;移动端走 H5;否则走 Native。
  • 输出:JSAPI 返回前端拉起支付的参数;Native 返回二维码与轮询地址;H5 返回 mweb_url 重定向链接。
flowchart TD
A["start(request)"] --> B{"UA包含MicroMessenger?"}
B -- 是 --> J["startJsapi()"]
B -- 否 --> C{"是否移动端?"}
C -- 是 --> H["startH5()"]
C -- 否 --> N["startNative()"]

JSAPI 支付(微信公众号)

  • 关键点:获取 OpenID,构造统一下单参数 trade_type=JSAPI,使用 JsApiPay 生成前端参数,页面通过 WeixinJSBridge 拉起支付。
  • 回调:统一由 notify 处理,验签后二次查询确认,再标记成功。

Native 支付(PC 扫码)

  • 关键点:trade_type=NATIVE,获取 code_url,通过 qrcode.php 生成二维码图片;前端轮询 status 接口查询支付结果。
  • 轮询:status 使用 orderQuery 主动查询,命中 SUCCESS 即推进状态。

H5 支付(移动网页)

  • 关键点:trade_type=MWEB,统一下单后返回 mweb_url,拼接 redirect_url 完成支付后回跳。
  • 注意:需确保域名与授权配置正确。

小程序支付(API)

  • 入口:api/controller/user/WeixinController::pay,读取小程序 appid/openid/mch_id/key,调用 api/service/WxPayService::unifiedorder 统一下单,返回小程序支付参数。
  • 回调:小程序支付同样走统一 notify 处理。

异步通知处理

  • 统一入口:WxpayService::notify 加载 SDK 并实例化 NotifyCallback,交由 SDK 验签。
  • 安全校验:NotifyCallback 重写 Queryorder 进行二次查询,CheckSign 失败直接拒绝。
  • 业务落库:验证通过后调用 PaymentService::markSucceeded 推进支付单与订单状态,并发送邮件通知站点管理员。
sequenceDiagram
participant WX as "微信支付"
participant SVC as "WxpayService"
participant NC as "NotifyCallback"
participant PS as "PaymentService"
WX->>SVC : POST 通知
SVC->>NC : Handle(config, false)
NC->>NC : CheckSign()
NC->>WX : Queryorder(transaction_id)
WX-->>NC : 返回交易状态
NC->>PS : markSucceeded(paymentSn, transactionId, raw)
PS-->>NC : 成功/失败
NC-->>SVC : true/false
SVC-->>WX : 返回响应

订单查询与对账

  • 主动查询:WxpayService::query 使用 orderQuery,将微信返回的交易状态映射为成功/待支付/已关闭/不存在等结果。
  • 轮询查询:Native 模式通过 status 接口按 paymentSn 轮询,成功后推进状态。

退款申请与关闭订单

  • 关闭订单:SDK 中定义了 CLOSEORDER_URL,可在需要时调用关闭订单接口(例如超时未支付)。
  • 退款申请:可复用 SDK 的退款相关类与方法(如 refund),传入商户订单号、退款金额、退款原因等参数,并在成功后更新本地退款记录。
  • 建议:退款前务必先查询订单状态,避免重复退款;退款回调与查询逻辑可参照通知与查询的实现模式。

证书与密钥配置

  • 配置项:APPID、MCHID、KEY、APPSECRET、SSL 证书路径(apiclient_cert.pem/apiclient_key.pem)。
  • 配置来源:通过插件配置注入到全局 $GLOBALS['config_from_plugin'],SDK 侧通过 WxPayConfigInterface 抽象获取。
  • 证书放置:插件目录下 cert 子目录,路径由 buildConfig 动态拼装。

依赖关系分析

  • WxpayProvider 依赖 WxpayService,仅做接口适配与路由转发。
  • WxpayService 依赖 SDK(WxPayApi、WxPayConfig、JsApiPay、NativePay、wechatAppPay)与 PaymentService。
  • NotifyCallback 依赖 SDK 的 WxPayNotify 与 WxPayApi,同时依赖 PaymentService 与邮件服务。
  • API 层 WeixinController 依赖 api/service/WxPayService,用于小程序下单。
classDiagram
class WxpayProvider {
+pluginId()
+meta()
+start(request)
+notify(payload)
+finish(payload)
+status(payload)
+query(request)
}
class WxpayService {
+start(request)
+notify(payload)
+finish(payload)
+status(payload)
+query(request)
-startNative(request)
-startJsapi(request)
-startH5(request)
-callOrderQuery(sn)
}
class NotifyCallback {
+Queryorder(transactionId) bool
+NotifyProcess(objData, config, msg) bool
}
class WeixinController {
+pay(request)
}
class ApiWxPayService {
+pay()
-unifiedorder()
-weixinapp()
}
WxpayProvider --> WxpayService : "委托"
WxpayService --> NotifyCallback : "使用"
WxpayService --> ApiWxPayService : "概念上类似"
WeixinController --> ApiWxPayService : "调用"

性能与可靠性

  • 幂等性:通知处理中二次查询订单状态后再推进,避免重复入账。
  • 重试与轮询:Native 模式前端轮询 + 后端主动查询,提高成功率。
  • 日志:SDK 日志写入 storage/log/payment/wxpay/ 按日分割,便于问题定位。
  • 超时控制:统一下单与查询均设置合理超时,避免阻塞。
  • 建议:在高并发场景下,结合队列处理通知与后续业务(发货、积分、报表),降低同步链路压力。

故障排查指南

  • 签名错误:检查 KEY 配置与参数排序,查看回调日志中的签名错误记录。
  • 回调未到达:确认 notify_url 公网可达且未被防火墙拦截;检查服务器时间与时区。
  • 订单查询失败:核对 out_trade_no 是否为 payment_sn;关注 err_code 与 return_msg。
  • H5 无法跳转:检查 redirect_url 域名是否在白名单;确认 mweb_url 有效。
  • 小程序支付失败:确认 openid 与 appid 匹配;检查统一下单参数 total_fee 单位(分)。

结论

本项目通过插件化架构将微信支付能力解耦,支持多终端支付方式,并以统一的通知与查询机制保障一致性与可靠性。开发者只需按模块配置证书与密钥,即可快速接入 JSAPI、Native、H5、小程序支付,并通过现有接口扩展退款、关单等业务。

附录:配置与示例路径

  • 插件元信息与配置字段定义:WxpayProvider.php:43-77
  • 插件清单与提供者注册:manifest.php:7-10
  • 统一下单与小程序支付参数组装:WxPayService.php:78-99、WxPayService.php:183-197
  • JSAPI 拉起支付与 H5 重定向:WxpayService.php:262-326、WxpayService.php:332-370
  • Native 二维码与轮询:WxpayService.php:193-256、qrcode.php:10-16
  • 通知处理与二次查询:NotifyCallback.php:73-118
  • 配置接口与证书路径:WxPay.Config.Interface.php:6-36、WxpayService.php:398-414
添加日期:2026-10-05