Global Alipay (DFC)
WHMCS 支付网关模块,基于
lokielse/omnipay-global-alipay驱动,为 WHMCS 接入境外/跨境支付宝(Global Alipay,MAPI 老接口)收款与退款,支持 USD/HKD/CNY 等多币种下单、扫码支付及多档汇率自动换算。
说明(2026-07-31 正式化):本目录已按 weimabao-toolkit 规范补齐为完整插件仓——
src/下是可直接构建的全量源码(含已打好 INTALLY_PATCHED 补丁的vendor/、config.php、templates/,由 v1.11 发行包导入),./build.sh [--ioncube]产出发行 ZIP。v1.12.0 起接入微码宝授权(license_key配置项门控收款与退款)。历史的patches/目录保留作补丁溯源,内容与src/中同名文件一致。
功能特性
- 境外支付宝收款:对接老版 MAPI 接口
https://mapi.alipay.com/gateway.do(沙盒openapi.alipaydev.com),create_forex_trade下单、single_trade_query查询。 - 二维码/跳转支付:
globalalipay_link()生成跳转链接,通过 Smarty 模板alipay.tpl渲染支付页(含内置 base64 兜底二维码图)。 - 双签名类型:支持 MD5 与 RSA 两种验签方式,按后台配置选择。
- 多币种 + 汇率换算:下单币种可选 USD/HKD/EUR/GBP/AUD/SGD/NZD/JPY/THB/KRW;内置 USD→HKD、HKD→CNY 汇率,下单时把账单币种换算到收款币种(USDHKD 额外加 0.29 手续费)。
- 汇率自动更新:
globalalipay_exchangerate()定时从外部接口拉取汇率并经UpdateModuleConfiguration回写配置。 - 回调入账:
notify_url.php(服务器异步通知,读$_POST,状态TRADE_SUCCESS)→addInvoicePayment,回success/fail。return_url.php(用户同步跳回,读$_GET,状态TRADE_FINISHED)→ 入账并渲染成功/失败结果页。- 退款(forex_refund):
globalalipay_refund()走get_Refund(),按支付宝原始下单币种/金额退款,含 Add Funds(账户充值)退款时同步扣减客户余额。 - 退款元数据持久化(INTALLY_PATCHED):付款成功时把
out_trade_no / currency / total_fee以 JSON 写入tblaccounts.description,退款时按「JSON > 旧字符串 > 重建」三级取值,避免PURCHASE_TRADE_NOT_EXIST/CURRENCY_NOT_SAME。 - 退款错误码中文提示:对
PURCHASE_TRADE_NOT_EXIST、CURRENCY_NOT_SAME、RETURN_AMOUNT_EXCEED、REPEATED_REFUNDMENT_REQUEST、ILLEGAL_SIGN等给出可读原因;并对每次退款生成带时间戳的唯一out_return_no防重复。
安装方法
./build.sh(或./build.sh --ioncube出加密发行包)得到dist/globalalipay_v<版本>.zip。- 将 ZIP 解压到 WHMCS 根目录(包内为
modules/gateways/...完整结构,vendor 已内置、补丁已打好,无需 composer)。 - 进入 WHMCS 后台 设置 → 支付方式(Payments → Payment Gateways),激活 Global Alipay (DFC)。
- 填写下方「配置说明」中的凭据(含微码宝许可证密钥)并保存。
配置说明
后台网关配置项(来自 globalalipay_config()):
| 配置项 | 类型 | 说明 | |—|—|—| | alipay_partner(Partner ID) | text | 合作身份者 ID / 签约账号,以 2088 开头的 16 位纯数字 | | alipay_signtype(验证类型) | dropdown | MD5 或 RSA | | alipay_key(MD5 密钥) | text | 32 位 MD5 密钥,验证类型为 MD5 时使用 | | PrivateKey(RSA 私钥) | textarea | 应用私钥,验证类型为 RSA 时必填 | | AlipayPublicKey(支付宝公钥) | textarea | 支付宝公钥,验证类型为 RSA 时必填 | | alipay_currency(收款币种) | dropdown | USD/HKD/EUR/GBP/AUD/SGD/NZD/JPY/THB/KRW | | alipay_refund(退款手续费) | text | 每笔退款扣除的手续费(默认 0) | | USDHKD / HKDCNY / UpdateIn | text | 汇率与自动更新时间(多由汇率任务自动回写,一般无需手填) | | sandbox(沙盒模式) | yesno | 启用沙盒环境 | | license_key(许可证密钥) | password | 微码宝商城购买的许可证密钥;无效时收款页与退款均被禁用(v1.12.0 起) |
目录结构
globalalipay/
├── README.md # 本文件
├── weimabao.json # 商城元数据(toolkit 规范;不入发行包)
├── build.sh # 打包脚本(--ioncube 出加密包;vendor 随仓,不跑 composer)
├── src/ # 完整源码(v1.11 发行包导入 + v1.12.0 授权门控)
│ └── modules/gateways/
│ ├── globalalipay.php # 主网关:MetaData/config/link(下单)/refund(退款)/汇率/授权门控
│ └── globalalipay/
│ ├── config.php # omnipay 引导
│ ├── notify_url.php # 异步通知回调($_POST,TRADE_SUCCESS → 入账)
│ ├── return_url.php # 同步跳回回调($_GET,TRADE_FINISHED → 入账 + 结果页)
│ ├── lib/LicenseClient.php # 微码宝授权客户端(Intally_LicenseClient,含失败不缓存修复)
│ ├── templates/ # 支付页(alipay.tpl + assets)
│ ├── docs/usage.md # 用户使用文档
│ └── vendor/ # omnipay 及依赖(INTALLY_PATCHED 补丁已打好)
├── tests/
│ └── LicenseCacheError.test.php # 回归:失败结果不得写 24h 授权缓存
├── dist/ # 打包产物(发行包必须 --ioncube 加密后逐文件核对)
│ ├── globalalipay_v1.11_20260506.zip
│ └── globalalipay_v1.5_20260430.zip
└── patches/ # 历史补丁溯源(内容已合入 src/,与同名文件一致)
系统要求
- WHMCS(网关
APIVersion 1.9,MetaDataAPI 版本 1.9)。 - PHP 8.x(补丁已处理 PHP 8.0+ / 8.4 的 OpenSSL 兼容性)。
- 已安装 OpenSSL 扩展(RSA 验签必需)。
lokielse/omnipay-global-alipay(及其 omnipay 依赖)——已内置于src/.../vendor/,无需 Composer。- Smarty(渲染
alipay.tpl支付页)。 - 出网访问汇率接口(如需汇率自动更新)。
注意事项
- 此为 Global Alipay(境外/跨境支付宝 MAPI 老接口),不是 EasySDK,也不是新版开放平台 OpenAPI。 接口走
mapi.alipay.com/gateway.do,service=single_trade_query,仍用 partner + MD5/RSA 验签的旧模式。 - RSA 密钥格式:本驱动
Signer::format()接受不带 PEM 头尾的单行 base64,会自动补-----BEGIN/END RSA PRIVATE KEY-----;也接受已带头尾的标准 PEM。私钥无效时(PHP8 下)补丁会抛出明确错误而非openssl_free_key(false)的隐晦 TypeError。注意这与「支付宝 EasySDK 只要 base64 body」的坑同源——别把不该带头尾的格式塞错地方。 - vendor 补丁已随仓固化:
Signer.php与TradeQueryRequest.php的补丁已直接合入src/.../vendor/lokielse/omnipay-global-alipay/,构建不跑 composer 所以不会被冲掉;若日后在部署机上手动composer install/composer update,补丁会丢失,须从patches/重新覆盖(详见patches/README.md)。 TradeQueryRequest:上游硬编码sign_type=RSA,MD5-only 商户付款成功后在return_url.php会因空私钥触发 PHP8 TypeError;补丁改为读商户配置的signType。Signer:对openssl_pkey_get_private/public返回false增加守卫并抛清晰异常;openssl_free_key仅对 legacy resource 调用(PHP 8.0+ 自动释放、8.4 已移除该函数)。- forex_refund 仅支持 HKD:退款币种必须与原始下单一致。本插件 v1.10+ 把下单时的
out_trade_no/currency/total_fee持久化到tblaccounts.description,退款据此精确匹配;旧版付款(无持久化)只能在支付宝商家后台手动退款。 - 退款防重复:
out_return_no自动追加时间戳,避免REPEATED_REFUNDMENT_REQUEST。 - 两个回调状态不同:异步
notify_url.php判TRADE_SUCCESS,同步return_url.php判TRADE_FINISHED,二者都做checkCbInvoiceID/checkCbTransID/logTransaction去重后入账。 - 汇率换算副作用:下单金额会按
USDHKD(+0.29) 与HKDCNY换算到收款币种;若商户 WHMCS 未正确配置币种/convertto,回调显示金额需以账单原值为准(return_url 已按账单total显示)。
更新日志
- v1.12.0 (2026-07-31):正式化为 toolkit 规范仓(src 全树 + weimabao.json + build.sh);
接入微码宝授权——新增 license_key 配置项,link()/refund() 授权门控(lib/LicenseClient.php, 含「失败不缓存」修复 + 回归测试);docs/usage.md 品牌信息更新为微码宝;semver 化版本号。 尚未上架(上架属红线人审:--ioncube 加密构建 + 逐文件 //ICB0 核对 + go-live Step 1.0 两条铁律)。
- v1.11 (2026-05-06):见
dist/globalalipay_v1.11_20260506.zip。 - v1.10:付款成功持久化完整支付宝元数据 JSON(
out_trade_no/currency/total_fee);退款三级取值与金额匹配;退款失败按declined处理并附错误码中文提示;Add Funds 退款同步扣减客户余额。 - v1.9:退款
out_return_no加时间戳防重复。 - v1.8:开始持久化原始
out_trade_no供退款使用。 - v1.5 (2026-04-30):见
dist/globalalipay_v1.5_20260430.zip。 - vendor 补丁:
TradeQueryRequest尊重商户 signType;Signer增加 RSA 密钥守卫与 PHP 8.x OpenSSL 兼容。
许可证
随 WeiMaBao 商业项目分发,未单独声明开源许可证。lokielse/omnipay-global-alipay 等第三方依赖遵循其各自许可证。
作者
WeiMaBao / DFC(网关显示名 Global Alipay (DFC))。