Z-Pay 支付宝收款配置(易支付协议)
Sub2API 后端内置了易支付(EasyPay)协议 Provider,Z-Pay(https://zpayz.cn/)是标准的易支付兼容平台。集成不需要改任何代码,也不需要改环境变量或重启服务,全部工作是在管理后台完成一次配置,然后按本文的清单验收。
内置 Provider 已经覆盖 Z-Pay 的全部接口:页面跳转下单(submit.php)、API 下单(mapi.php)、订单查询(api.php?act=order)、退款(api.php?act=refund)、MD5 验签、异步通知应答纯文本 success,通知的 GET / POST 两种方式均可接收。
如果要理解支付子系统内部的订单状态机、回调幂等和履约逻辑,请阅读支付与订单子系统;充值到账异常的处置流程见计费 Runbook。
参数对照
Z-Pay 商户资料与后台配置字段的对应关系:
| Z-Pay 提供的信息 | 后台配置项 | 本次的值 |
|---|---|---|
| 网关地址 | API 基础地址(apiBase) | https://zpayz.cn |
| 商户 ID(PID) | PID(pid) | 2026071611292588 |
| 商户密钥(KEY) | PKey(pkey) | 从 Z-Pay 商户后台获取,只填入后台,不要写进文档、脚本或代码库 |
| notify_url | 由「回调基础地址」自动拼出 | https://<站点域名>/api/v1/payment/webhook/easypay |
| return_url | 由「回调基础地址」自动拼出 | https://<站点域名>/payment/result |
| 支付渠道 ID(cid,可选) | 支付宝渠道 ID(cidAlipay) | 不填则由 Z-Pay 随机调度通道 |
API 基础地址只填网关根地址即可,系统会自动拼接 /submit.php、/mapi.php、/api.php;即使误填了带 submit.php 的完整地址,后端也会自动裁剪。
商户密钥同时用于下单验签、订单查询和退款,泄漏等同于资金风险。密钥在数据库中加密存储,后台界面按敏感字段处理;除 Z-Pay 商户后台和本系统支付设置外,任何地方都不应再出现这个值。
前置条件
- 站点有公网可达的 HTTPS 域名,且
/api/v1/payment/webhook/easypay能被 Z-Pay 服务器直接访问(Webhook 路由不走用户 JWT,但会被反代、WAF 或地域封锁拦截,见下文网络要求)。 - 已从 Z-Pay 商户后台获取 PID 和商户密钥。
- 具有 Sub2API 管理员权限。
配置步骤
全部在 管理后台 → 系统设置 → 支付设置 中完成。
第一步:全局支付开关与参数
- 打开「启用支付」。
- 在「启用的服务商」中勾选「易支付」。
- 核对经营参数:最低金额 / 最高金额 / 每日限额、余额充值倍率(每支付 1 CNY 折算多少 USD 余额)、充值手续费率、订单超时时间、最大待支付订单数。
- 建议设置「商品名前缀 / 后缀」,让 Z-Pay 侧的商品名称体现真实售卖内容(例如
API服务-余额充值)。Z-Pay 明确要求商品名体现具体商品,否则容易被风控封禁。
第二步:创建易支付服务商实例
进入「管理服务商」,新增实例:
| 配置项 | 填写内容 |
|---|---|
| 服务商类型 | 易支付 |
| 名称 | 便于识别即可,如 Z-Pay 支付宝 |
| 支持的支付方式 | 勾选支付宝(alipay);如后续开通微信再勾选 wxpay |
| 支付模式 | 「二维码」或「弹窗」,区别见下节 |
| PID | 2026071611292588 |
| PKey | Z-Pay 商户密钥 |
| API 基础地址 | https://zpayz.cn |
| 回调基础地址 | 站点公网 HTTPS 地址,如 https://api.example.com,界面会显示自动拼接后的异步通知地址和同步跳转地址 |
| 支付宝渠道 ID | 可选。Z-Pay 后台如分配了指定通道则填入,多个用英文逗号分隔;留空随机调度 |
保存后 Provider Registry 会立即刷新,单实例部署无需重启。多副本部署时后台保存只刷新处理该请求的进程,其余副本可能仍持有旧配置,变更后应逐副本验证或滚动重启(详见支付与订单子系统的 Registry 说明)。
第三步(可选):用户可见支付方式
如果站点配置过「用户可见支付方式」,确认支付宝已开启并指向刚创建的易支付实例,否则用户充值页不会出现该选项。
支付模式怎么选
| 模式 | 后端行为 | 用户体验 | 适用场景 |
|---|---|---|---|
| 二维码(默认) | 服务端调用 mapi.php 下单,拿到 payurl / qrcode | 站内弹出二维码扫码支付;移动端自动带 device=mobile,优先使用 H5 支付链接 | 推荐。体验统一,下单失败能立即拿到 Z-Pay 的错误信息 |
| 弹窗 | 服务端只拼签名后的 submit.php 链接,不发起 API 调用 | 浏览器跳转到 Z-Pay 收银台页面 | 二维码模式在部分通道不可用、或希望完全由 Z-Pay 收银台承接时 |
补充两点:
- 移动端支付宝用户默认会走手机跳转支付;如果希望移动端也统一扫码,打开支付设置中的「支付宝强制二维码支付」。
- 「易支付自定义支付方式」用于 Z-Pay 额外开通的非标准 type(本次只做支付宝,无需配置)。
回调链路:系统已自动处理的部分
以下行为是内置逻辑,运维不需要额外开发,但排障时需要知道:
- Z-Pay 的异步通知按易支付规范可能以 GET 或 POST 到达,两种方法均已注册路由。
- 每条通知都会做 MD5 验签(按参数 ASCII 排序拼接 + 商户密钥,
sign/sign_type/空值不参与),验签失败返回 400 并记录日志。 - 只有
trade_status=TRADE_SUCCESS视为支付成功;订单金额会与本地订单核对,防止假通知和改价。 - 处理成功返回纯文本
success,Z-Pay 据此停止重试;重复通知靠订单状态机条件更新做幂等,不会重复到账。 - 找不到对应订单的通知会应答
success并记 WARN(防止别人误配我们的地址后无限重试刷日志)。 - 用户取消订单前、以及订单接近超时时,系统会主动调
api.php?act=order查单对账,错过回调也能补单。
网络与反向代理要求
Z-Pay 判定通知失败的条件是「应答不是纯 success 或超过 5 秒」,失败后按 0/15/15/30/180/1800/… 秒的节奏重试,但不保证最终送达。因此:
/api/v1/payment/webhook/easypay必须放行:不要在反代或 WAF 层对该路径做登录校验、地域封锁、人机验证(Cloudflare 挑战页会直接吃掉通知)。- 反代到后端的超时不低于 10 秒,保证 5 秒内能返回应答。
- HTTPS 证书必须有效且完整(含中间证书),Z-Pay 侧证书校验失败同样表现为收不到通知。
- 如有 IP 白名单机制,无法预知 Z-Pay 出口 IP 时应放开该路径,安全性由验签保证。
验收清单
配置完成后按顺序验证,前一步不通过不要继续:
- 下单:用测试账号在充值页选择支付宝,创建一笔最小金额订单(受「最低金额」限制,建议临时调低到 0.1 元)。二维码模式应看到二维码;若报错,错误信息来自 Z-Pay(常见:商品名违规、通道未开通、金额低于通道下限)。
- 支付:真实扫码支付。易支付类平台没有沙箱,验收就是小额实付。
- 到账:支付后订单应在数秒内流转
pending → paid → recharging → completed,用户余额按充值倍率入账。卡在pending说明异步通知没进来,按下文排查。 - 日志:后端日志搜
[Payment Webhook],应看到 easypay 的成功处理记录,且无verify failed。 - 对账:管理后台 → 订单管理中核对订单金额、渠道、外部订单号与 Z-Pay 商户后台一致。
- 退款:对这笔测试订单在后台发起退款(走
api.php?act=refund,Z-Pay 要求退款金额与原订单一致),确认 Z-Pay 侧退款成功、本地订单状态正确。 - 验收完把「最低金额」等临时参数改回经营值。
故障排查
| 症状 | 最可能原因 | 处置 |
|---|---|---|
用户已付款,订单一直 pending | 异步通知未到达:回调基础地址填错、域名不可公网访问、WAF/反代拦截、证书问题 | 从外网 curl -X POST https://<域名>/api/v1/payment/webhook/easypay 应答 400(verify failed)说明链路通;通不了先修网络。链路通后可等系统查单对账或在后台手动同步订单 |
日志出现 verify failed | PKey 填错(含复制时带入空格),或 Z-Pay 后台重置过密钥 | 核对并重新保存 PKey;注意多副本刷新 |
创建订单直接报 easypay error: … | Z-Pay 侧拒单:商品名违规、渠道 ID 无效、金额超出通道限制 | 按错误信息处理;调整商品名前缀、清空或修正支付宝渠道 ID |
订单 paid 后卡在 failed | 支付成功但履约(加余额/开订阅)失败 | 后台订单详情中「重试履约」,并按计费 Runbook排查 |
| 退款失败 | 金额与原订单不一致,或该通道不支持原路退回 | 按原订单金额全额退款;仍失败时在 Z-Pay 商户后台人工处理 |
| 改了配置不生效(多副本) | Provider Registry 只在保存请求命中的副本刷新 | 滚动重启其余副本 |
安全红线
- 商户密钥只存在于 Z-Pay 商户后台和本系统支付设置中,不进 Git、不进聊天记录、不进监控面板。
- 不要关闭或绕过验签逻辑「先跑通再说」——易支付生态的假通知攻击就是靠商户不验签、不核金额得手的。
- 定期(建议每月)用 Z-Pay 商户后台账单与本地订单做一次对账,关注金额不一致和只在单侧存在的订单。