
MPAY V2 是一套基于 Webman 的支付中台后端服务,面向多商户、多通道、多支付方式的统一收款、支付路由、订单管理、退款、转账、清算和资金流水场景。
程序通过发行版安装包部署,内置安装向导会完成环境检测、数据库初始化、系统配置写入和管理员账号创建。
MPAY V2 的核心目标是把支付系统里容易分散的能力统一起来:商户、支付方式、支付插件、插件配置、支付通道、轮询组、路由策略、业务单、支付单、回调通知、退款、清算和资金账户都由后端统一建模和管理。
它不是简单的支付接口转发程序,而是一套可二次开发的支付中台底座:
| 模块 | 能力 |
|---|---|
| 管理后台 API | 管理员登录、商户、商户分组、商户策略、支付方式、支付插件、插件配置、支付通道、轮询组、路由预览、订单、退款、清算、资金、文件、系统配置 |
| 商户后台 API | 商户登录、商户资料、API 凭证、我的通道、自助插件配置、商户路由、路由预览、支付订单、退款订单、清算记录、可提现余额、资金流水 |
| 收银台 API | 收银台上下文、确认支付、支付单详情、支付状态、身份授权上下文、微信网页授权回调、身份回填继续支付 |
| 开放支付协议 | ePay V1、ePay V2、页面跳转支付、API 创建订单、订单查询、退款、退款查询、关闭订单、商户信息、商户订单、转账、转账查询、转账余额 |
| 支付核心 | 业务单、支付单、支付路由、插件运行时、支付状态生命周期、回调幂等、主动查单、商户通知任务、交易追踪 |
| 插件体系 | pay()、query()、notify()、refund()、refundQuery()、close()、transfer()、transferQuery()、channelNotify() |
| 资金清算 | 平台代收、商户自收、服务费、冻结、释放、清算单、清算明细、资金流水、退款净额重算 |
| 异步任务 | Webman 自定义进程、Redis Queue、通知重试、退款派发、转账派发、转账延迟查单、清算自动入账、网页流水通知 |
| 文件资产 | 本地存储、远程 URL 导入、阿里云 OSS、腾讯云 COS、预览、下载 |
| 运维能力 | 安装向导、环境检测、系统配置同步、运行状态、日志记录、命令行测试、反向代理部署 |
以下截图用于展示 MPAY V2 的完整业务效果。
| 管理后台运营首页 | 商户后台首页 |
|---|---|
![]() |
![]() |
| 插件中心 | 插件配置 |
|---|---|
![]() |
![]() |
| 商户列表 | 商户资料 |
|---|---|
![]() |
![]() |
| 通道轮询 | 系统配置 |
|---|---|
![]() |
![]() |
| 运行监控 | 账户资金 |
|---|---|
![]() |
![]() |
| 支付订单 | 支付通道 |
|---|---|
![]() |
![]() |
| 二维码收银台 | 文件管理 |
|---|---|
![]() |
![]() |
| 类型 | 技术 |
|---|---|
| 运行环境 | PHP 8.2+ |
| 后端框架 | Webman 2.x、Workerman |
| 数据库 | MySQL |
| 缓存与队列 | Redis、webman/redis-queue |
| 命令行 | webman/console |
| 鉴权 | JWT,管理后台、商户后台和开放 API 独立鉴权 |
| 存储 | 本地存储、阿里云 OSS、腾讯云 COS |
| 日志 | Monolog、Webman runtime logs |
| 依赖管理 | Composer |
| 静态资源 | public 目录承载首页、安装页、文档页或自行构建的前端产物 |
外部业务系统 / 商城 / 发卡系统
|
| ePay V1/V2 / Open API
v
MPAY Webman 后端
|
|-- 管理后台 API:商户、插件、通道、路由、订单、资金、系统配置
|-- 商户后台 API:商户资料、API 凭证、订单、退款、清算、流水
|-- 收银台 API:支付上下文、确认支付、身份授权、支付状态
|-- 支付运行时:业务单、支付单、路由、插件调用、查单、回调、通知
|-- Redis Queue:通知、退款、转账、清算、网页流水监听
|
v
第三方支付 / 官方 API / 个人收款监听 / 网页流水监听
核心支付链路:
商户系统发起支付
-> 校验商户状态和签名
-> 创建业务单 ma_biz_order
-> 创建支付单 ma_pay_order
-> 按商户分组和支付方式解析路由
-> 轮询组选择支付通道
-> 加载支付插件和插件配置
-> 插件返回二维码、跳转链接、HTML、JSAPI 参数或身份授权地址
-> 上游回调或主动查单推进支付状态
-> 创建商户通知任务
-> 平台代收场景生成清算单并入账
app/command/ 命令行任务、迁移、测试和联调命令
app/common/ 基类、常量、工具、中间件、支付插件、SDK
app/http/ admin、mer、api 控制器、中间件和参数校验
app/model/ 数据模型
app/process/ Webman 自定义进程
app/queue/ Redis Queue 消费者
app/repository/ 仓库层
app/route/ 显式路由
app/service/ 支付、商户、资金、文件、安装、系统配置等服务
config/ Webman 配置、业务配置、进程配置、队列配置
database/ 迁移、种子和完整 DDL
public/ 静态资源目录
runtime/ 运行日志、缓存、PID、上传文件等运行时目录
support/ Webman 支撑代码
tools/ 辅助工具,例如 receipt_watcher
最低要求:
| 依赖 | 要求 |
|---|---|
| PHP | 8.2 或更高版本 |
| MySQL | 5.7+ / 8.x |
| Redis | 5.x+ |
| PHP 扩展 | pdo_mysql、redis、pcntl、fileinfo |
开发环境可以直接使用 PHP CLI 启动;生产环境建议使用 Nginx 或 Apache 反向代理到 Webman HTTP 服务。
具体要求可以看webman官方教程:宝塔安装,nginx代理
MPAY V2 面向实际部署提供发行版安装包。正式安装建议从 Gitee 发行版下载,不建议直接用源码仓库作为生产安装包。
发行版安装包结构:
app/ 后端业务源码
config/ 配置文件
database/ 数据库迁移、种子和完整 DDL
public/ 首页、安装页、接口文档页和静态资源
runtime/ 运行时目录
support/ Webman 支撑代码
vendor/ Composer 依赖
.env.example 环境变量示例
composer.json Composer 配置
composer.lock Composer 锁定文件
webman Webman 命令入口
windows.php Windows 开发启动入口
start.php Webman 启动入口
进入项目发行版页面下载最新安装包:
https://gitee.com/technical-laohu/mpay_v2_webman/releases
下载后解压到站点目录,例如:
/www/wwwroot/pay.example.com
服务器需要准备:
| 依赖 | 说明 |
|---|---|
| PHP | 8.2 或更高版本 |
| MySQL | 建议 5.7+ / 8.x |
| Redis | 用于缓存、登录态、队列和运行时任务 |
| 程序依赖 | 发行版已包含 vendor,通常不需要在服务器单独安装依赖 |
| PHP 扩展 | pdo_mysql、redis、pcntl、fileinfo |
Webman 是常驻内存服务,不依赖 PHP-FPM 处理请求。
确保运行用户可以写入以下目录:
runtime/
public/storage/
安装程序会写入 .env、安装锁、日志、缓存和上传目录。若服务器权限较严格,请先确认站点目录对 Webman 运行用户可写。
Linux / macOS:
# 调试方式运行(用于开发调试,打印数据会显示在终端,终端关闭后webman服务也随之关闭)
php webman start
# 守护进程方式运行(用于正式环境,打印数据不会显示在终端,终端关闭后webman服务会持续运行)
php webman start -d
Windows 开发环境:
# 双击 windows.bat 或者终端运行 php windows.php 启动
php windows.php
默认监听地址:
http://127.0.0.1:8787
生产环境使用Linux系统,建议使用 Supervisor、systemd、宝塔守护进程等方式守护 Webman 进程,再通过 Nginx 或 Apache 反向代理访问。
浏览器访问:
http://你的域名/install
或本地访问:
http://127.0.0.1:8787/install
安装程序会引导填写:
安装程序会自动完成:
.env 配置文件。安装完成后重启 Webman:
php webman restart
安装完成后建议检查:
| 地址 | 说明 |
|---|---|
/ 或 /home |
项目首页 |
/install |
已安装后应提示安装状态 |
/docs |
内置接口文档页 |
/adminapi/system/public-config |
管理后台公开配置接口 |
/api/cashier/config |
收银台公开配置接口 |
页面入口 /admin、/mer、/cashier 依赖对应构建产物是否存在;后端接口不受影响。
下面以宝塔 Linux 面板安装 MPAY V2 发行版为例,演示从运行环境、站点创建、安装包部署、Webman 启动到安装向导完成的完整流程。示例域名、数据库名和账号仅用于演示,正式部署时请替换为自己的域名和安全密码。
进入宝塔面板的「软件商店」,先确认服务器已安装并启动 Nginx、MySQL、Redis 和 PHP 8.2+。MPAY V2 使用 Webman 常驻内存运行,动态请求最终会由 Nginx 反向代理到 Webman HTTP 服务。

在 PHP 设置中进入「安装扩展」,确认当前 PHP 版本已安装 fileinfo 和 redis 扩展。redis 扩展用于连接 Redis 服务,fileinfo 用于文件类型识别和上传相关处理。

进入「网站」页面点击「添加站点」,选择「传统项目」。填写访问域名,站点根目录建议使用 /www/wwwroot/你的域名;同时创建 MySQL 数据库并记录数据库名、用户名和密码。因为 Webman 不依赖 PHP-FPM 处理动态请求,PHP 版本可以选择「纯静态」,后续通过伪静态规则反向代理到 Webman 服务。

进入刚创建的站点目录,上传从发行版页面下载的 MPAY V2 安装包,例如 mpay_v2.zip,然后解压到站点当前目录。解压后站点根目录下应能看到 app、config、database、public、runtime、support、vendor、webman、start.php 等文件和目录。

在站点当前目录打开宝塔终端,执行以下命令解除 Webman 运行所需的 PHP CLI 禁用函数:
cd /www/wwwroot/项目目录
php webman fix-disable-functions
# 如果解除不成功,可以使用下面脚本再试一遍
curl -Ss https://www.workerman.net/webman/fix-disable-functions | php
命令会检查当前 PHP CLI 配置,并尝试启用 exec、shell_exec、proc_open、pcntl_alarm、pcntl_fork、pcntl_signal、pcntl_signal_dispatch 等函数。执行完成后如有提示,请按宝塔或 PHP 配置要求重载对应服务。

继续在站点目录执行守护进程启动命令:
php webman start -d
看到 Start success 且监听地址为 http://0.0.0.0:8787 时,说明 Webman 服务已经启动。后续访问域名时,Nginx 会把动态请求转发到该端口。

进入站点设置的「网站目录」,将「运行目录」设置为 /public 并保存。这样静态资源、首页、安装页和前端构建产物会从 public 目录对外提供。

进入站点设置的「伪静态」,写入 Nginx 规则并保存。规则的核心是:静态文件优先由 Nginx 直接处理,不存在的动态请求交给 Webman;同时兼容 ePay V1 的 /submit.php、/mapi.php、/api.php 入口。
# ePay V1 兼容入口:/submit.php /mapi.php /api.php
location ~ ^/(submit|mapi|api)\.php$ {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://127.0.0.1:8787/$1;
}
# 静态文件优先由 Nginx 处理,不存在再交给 Webman
location / {
try_files $uri $uri/ @webman;
}
# Webman 动态请求
location @webman {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://127.0.0.1:8787;
}
# 拒绝访问其它 PHP 文件
location ~ \.php$ {
return 404;
}
# 允许访问 .well-known 目录
location ^~ /.well-known/ {
allow all;
}
# 拒绝访问其它以 . 开头的文件或目录
location ~ /\. {
return 404;
}

浏览器访问站点域名,未安装时首页会显示系统状态为「未安装」。点击「开始安装」,或直接访问 /install 进入安装向导。

安装向导会依次完成协议确认、环境检测和基础配置。基础配置中需要填写平台名称、站点 URL、MySQL 连接信息、Redis 连接信息和初始管理员信息。Redis 默认没有密码时可以留空;如果服务器设置了 Redis 密码,则按实际密码填写。

安装完成后重启 Webman 服务:
php webman restart -d
然后访问 /admin 进入管理后台。运营首页能正常打开,并显示运行健康、交易统计、运维告警和快捷入口,说明管理端页面和后台 API 已经连通。

访问 /mer 可进入商户后台。首次上线后建议在管理后台补齐商户资料、接口凭证、插件配置、支付通道和路由策略,再使用商户后台验证订单、退款、资金流水和通道配置是否符合预期。

| 场景 | 页面入口 | API 入口 |
|---|---|---|
| 首页 | /、/home |
无 |
| 安装向导 | /install |
/adminapi/install/* |
| 内置接口文档页 | /docs |
无 |
| 管理后台 | /admin,需存在 public/admin/index.html |
/adminapi |
| 商户后台 | /mer,需存在 public/mer/index.html |
/merapi |
| 收银台 | /cashier、/payment,需存在 public/cashier/index.html |
/api/cashier、/api/pay |
| ePay V1 | /submit.php、/mapi.php、/api.php |
同左 |
| ePay V2 | 无固定页面 | /api/pay、/api/merchant、/api/transfer |
| 通道级通知 | 无页面 | /api/pay/{chanId}/notify |
如果对应前端构建产物不存在,页面入口会返回 Admin page not found、Merchant page not found 或 Cashier page not found。这不影响后端 API 使用。
# 启动 Webman 工作进程,默认 DEBUG 模式(前台运行)
php webman start
# 启动 Webman 工作进程,以 DAEMON 模式启动(后台运行)
php webman start -d
# 停止 Webman 工作进程
php webman stop
# 平滑停止,等待当前请求处理完成后再退出
php webman stop -g
# 无停机重载代码,适用于代码更新后热加载。
php webman reload
# 平滑重载,等待当前请求处理完成后再重载
php webman reload -g
# 重启 Webman 工作进程
php webman restart
# 重启后以 DAEMON 模式运行(后台运行)
php webman restart -d
# 平滑停止后再重启
php webman restart -g
# 查看工作进程运行状态
php webman status
# 显示详情(实时状态)
php webman status -d
# Windows 开发环境启动
php windows.php
# 数据库迁移
php webman migrate
php webman migrate:status
# 系统配置默认值同步
php webman system:config-sync
# 商户通知重试
php webman payment:notify-retry
# 支付链路烟雾测试
php webman mpay:test --all
# P0 核心检查
php webman mpay:p0-check
# ePay V1 兼容接口测试
php webman epay:mapi
# ePay V2 初始化联调密钥
php webman epay:v2-bootstrap
# ePay V2 API 烟雾测试
php webman epay:v2-api
# ePay V1/V2 mock 全链路测试
php webman epay:mock-chain
| 入口 | 方法 | 说明 |
|---|---|---|
/submit.php |
GET / POST | 页面跳转支付 |
/mapi.php |
POST | 接口支付 |
/api.php |
GET / POST | 商户信息、订单查询、退款等兼容 API |
V1 使用 MD5 签名,面向已有易支付生态的接入方。
| 入口 | 方法 | 说明 |
|---|---|---|
/api/pay/submit |
GET / POST | 页面跳转支付 |
/api/pay/create |
POST | API 创建支付订单 |
/api/pay/query |
POST | 查询支付订单 |
/api/pay/refund |
POST | 创建退款 |
/api/pay/refundquery |
POST | 查询退款 |
/api/pay/close |
POST | 关闭订单 |
/api/merchant/info |
POST | 查询商户信息 |
/api/merchant/orders |
POST | 查询商户订单 |
/api/transfer/submit |
POST | 提交转账 |
/api/transfer/query |
POST | 查询转账 |
/api/transfer/balance |
POST | 查询转账余额 |
V2 使用 RSA 签名,适合新接入系统。
创建支付订单示例:
curl -X POST "http://127.0.0.1:8787/api/pay/create" \
-H "Content-Type: application/json" \
-d '{
"pid": 1001,
"type": "alipay",
"out_trade_no": "T202605190001",
"notify_url": "https://merchant.example.com/pay/notify",
"return_url": "https://merchant.example.com/pay/return",
"name": "测试订单",
"money": "9.90",
"clientip": "127.0.0.1",
"timestamp": "1779179000",
"sign_type": "RSA",
"sign": "..."
}'
返回结构会根据插件能力不同返回二维码内容、跳转链接、HTML、URL Scheme、JSAPI 参数或身份授权地址。
支付插件位于:
app/common/payment
当前内置插件:
| 插件类 | 插件编码 | 说明 |
|---|---|---|
AlipayApiPayment |
alipay_api |
支付宝官方 API 支付 |
WechatApiPayment |
wechat_api |
微信官方 API 支付 |
EpayV1Payment |
epay_v1 |
彩虹易支付 V1 协议适配 |
EpayV2Payment |
epay_v2 |
彩虹易支付 V2 协议适配 |
AlipayReceiptPayment |
alipay_receipt |
支付宝个人收款监听 |
WechatReceiptPayment |
wxpay_receipt |
微信个人收款监听 |
ShouQianBaReceiptPayment |
shouqianba_receipt |
收钱吧二维码牌网页流水监听 |
PostarReceiptPayment |
postar_receipt |
星驿付收款单网页流水监听 |
插件常用方法:
| 方法 | 职责 |
|---|---|
pay() |
创建支付承接信息 |
query() |
主动查询支付状态 |
notify() |
处理上游支付回调 |
refund() |
发起退款 |
refundQuery() |
查询退款状态 |
close() |
关闭订单 |
transfer() |
发起转账 |
transferQuery() |
查询转账状态 |
channelNotify() / channelNotifyPayload() |
通道级通知先定位平台支付单 |
pay() 返回值会由支付运行时转换为收银台和开放 API 可识别的支付呈现结构,常见类型包括:
| 类型 | 说明 |
|---|---|
qrcode / qr_code |
二维码内容,适合扫码支付 |
url / redirect |
跳转链接 |
html |
上游返回的 HTML 表单或页面片段 |
scheme |
App URL Scheme |
jsapi |
公众号、小程序或 JSAPI 支付参数 |
identity |
缺少 OpenID、buyer_id 等用户身份时返回授权承接地址 |
支付选路固定围绕下面的数据关系展开:
商户
-> 商户分组
-> 路由绑定
-> 轮询组
-> 轮询组通道编排
-> 支付通道
-> 插件配置
-> 支付插件
路由模式:
| 模式 | 说明 |
|---|---|
| 顺序轮询 | 按通道排序和轮询状态选择 |
| 权重随机 | 按权重随机选择可用通道 |
| 默认通道 | 优先使用标记为默认的通道 |
如果支付创建失败并提示“路由无命中”,通常需要检查商户状态、商户分组、路由绑定、轮询组、通道状态、插件状态和支付方式是否一致。
金额在系统内部统一使用“分”作为计算和存储单位。ePay 协议面向商户时使用元字符串,例如 "9.90"。
平台代收:
支付成功
-> 创建商户通知任务
-> 生成待清算单
-> 清算入账后增加商户可提现余额
-> 写入资金流水
商户自收:
支付资金直接进入商户自己的上游账户
-> 平台只处理服务费冻结、扣除或释放
-> 不生成平台代收清算入账
退款创建时必须锁定原支付单,并把 CREATED、PROCESSING、SUCCESS 的退款单计入占用金额,避免并发超退。清算入账前会按支付单和已成功退款重新核算净额。
| 进程 / 队列 | 说明 |
|---|---|
payment-runtime |
商户通知重试、支付超时扫描、支付中订单主动查单 |
receipt-watcher-sync |
将需要查询流水的账号和订单同步到 Redis |
merchant_notify |
商户通知投递 |
refund_dispatch |
退款上游派发 |
transfer_dispatch |
转账上游派发 |
transfer_query |
转账延迟查单 |
settlement_complete |
清算自动入账 |
receipt_flow_notify |
网页流水监听通知处理 |
Linux 生产环境使用 php webman start 会按 Webman 配置启动相关进程。Windows 开发环境请使用 php windows.php。
网页流水监听适用于第三方平台没有标准回调,但可以登录网页后台查询收款流水的场景。
职责边界:
receipt_watcher 负责登录第三方网页后台并抓取流水。当前内置适配方向:
# ePay V1 兼容入口:/submit.php /mapi.php /api.php
location ~ ^/(submit|mapi|api)\.php$ {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://127.0.0.1:8787/$1;
}
# 静态文件优先由 Nginx 处理,不存在再交给 Webman
location / {
try_files $uri $uri/ @webman;
}
# Webman 动态请求
location @webman {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://127.0.0.1:8787;
}
# 拒绝访问其它 PHP 文件
location ~ \.php$ {
return 404;
}
# 允许访问 .well-known 目录
location ^~ /.well-known/ {
allow all;
}
# 拒绝访问其它以 . 开头的文件或目录
location ~ /\. {
return 404;
}
/submit.php、/mapi.php、/api.php,这些是 ePay V1 兼容入口,不是传统 PHP-FPM 文件执行入口。
生产环境建议:
runtime/、public/storage/ 需要可写。.env、证书、私钥、上游支付密钥提交到公开仓库。仓库内包含 LICENSE 文件。使用、二次开发、商用发布和插件分发前,请确认当前仓库许可证、业务代码授权边界和第三方 SDK 的授权要求。