yansongda/pay v3 接入笔记:支付宝/微信/抖音/银联统一网关的插件化设计
作者在对接多次支付宝与微信支付后,把两端 API 的差异收敛到一个统一封装里,做成了 yansongda/pay。项目基于 PHP,MIT 协议,支持支付宝、微信、抖音、银联、江苏银行。v3 相比 v2 做了一次底层重构,基础架构重新设计,扩展性和易用性都有明显变化。
- GitHub:https://github.com/yansongda/pay
- 文档:https://pay.yansongda.cn
- Laravel 扩展包:https://github.com/yansongda/laravel-pay
- Hyperf 扩展包:https://github.com/yansongda/hyperf-pay
- Yii 扩展包:https://github.com/guanguans/yii-pay
v3 的关键取舍
基础架构重新设计后,v3 与 v2 底层差异较大:
- 多租户与 Swoole 支持
- 灵活的插件机制,支付网关可作为插件引入并自行扩展
- 丰富的事件系统
- 命名不混乱,隐藏开发者不需关注的细节
- 高度抽象类,免去手动拼接 json/xml
- 文件结构清晰,可随意添加支付网关
- 内置自动获取微信公共证书,不用再处理首次取证书的问题
- 符合 PSR2/3/4/7/11/14/18 标准,便于与框架集成
支持范围覆盖支付宝、微信、银联全部线上接口(含服务商)。支付宝包含电脑支付、手机网站支付、APP 支付、刷卡支付、扫码支付、账户转账、小程序支付;微信覆盖公众号、小程序、H5、扫码、APP、刷卡支付;另支持抖音小程序支付、银联手机网站/电脑网站/刷卡/扫码支付、江苏银行(e融支付)聚合扫码支付。网关由插件机制引入。
安装:
composer require yansongda/pay:~3.7.0 -vvv
支付宝(证书模式)
配置参数:
$config = [
'app_id' => '', // 必填
'app_secret_cert' => '', // 应用私钥,字符串或路径
'app_public_cert_path' => '', // 应用公钥证书路径
'alipay_public_cert_path' => '', // 支付宝公钥证书路径
'alipay_root_cert_path' => '', // 支付宝根证书路径
'return_url' => '', // 页面跳转同步回调
'notify_url' => '', // 异步通知
'app_auth_token' => '', // 第三方应用授权 token,选填
'service_provider_id' => '', // 服务商模式
'mode' => '', // MODE_NORMAL / MODE_SANDBOX / MODE_SERVICE
];
还可在配置中设置 logger 及 http(timeout、connect_timeout,底层走 Guzzle)。
电脑网站支付下单:
Pay::config($config);
$result = Pay::alipay()->web([
'out_trade_no' => time(),
'total_amount' => '0.01',
'subject' => '测试',
]);
同步回调直接验签:
$data = Pay::alipay()->callback();
$data 中可取 out_trade_no、trade_no、total_amount。
异步通知:
try {
$data = Pay::alipay()->callback();
} catch (\Throwable $e) {
// 验签失败处理
}
验签只做签名校验,业务上仍要自行判断以下内容:
- 通知中
out_trade_no是否为系统创建的订单号 total_amount是否确为该订单实际金额seller_id/seller_email是否为该笔单据对应操作方(一个商户可能挂多个 seller)app_id是否为商户本身- 其它业务逻辑
只有 trade_status 为 TRADE_SUCCESS / TRADE_FINISHED 才算付款成功。处理完成后需返回:
return Pay::alipay()->success(); // 返回 success 表示通知已处理,支付宝停止重发
微信支付
配置参数:
$config = [
'mch_id' => '', // 商户号
'mch_secret_key_v3' => '', // 必填,v3 商户密钥
'mch_secret_key_v2' => '', // v2 商户私钥,选填
'mch_secret_cert' => '', // 商户私钥
'mch_public_cert_path' => '', // 商户公钥证书
'notify_url' => '',
'mp_app_id' => '', // 公众号 app_id
'mini_app_id' => '', // 小程序 app_id
'app_id' => '', // APP app_id
'wechat_public_cert_path' => '', // 微信平台公钥证书路径
'mode' => '', // MODE_NORMAL / MODE_SERVICE
];
服务商模式下使用 sub_* 系列子商户字段。wechat_public_cert_path 的 key 为证书序列号,value 为 pem 路径,php-fpm 模式下强烈建议配置。
公众号支付下单:
$pay = Pay::wechat()->mp($order);
返回结果包含 appId、timeStamp、nonceStr、package、signType,直接交给前端发起支付。
微信回调:
$data = Pay::wechat()->callback();
return Pay::wechat()->success();
抖音小程序支付
配置参数:mch_id、mch_secret_token(支付 Token,用于回调签名)、mch_secret_salt(支付 SALT,用于支付签名)、mini_app_id 小程序 app_id、thirdparty_id 服务商 id、notify_url。
下单:
$result = Pay::douyin()->mini([
'out_order_no' => '',
'total_amount' => 1,
'subject' => '',
'body' => '',
'valid_time' => '',
]);
回调同样走 Pay::douyin()->callback() + Pay::douyin()->success()。
江苏银行(e融支付)
配置参数:svr_code、partner_id、public_key_code、mch_secret_cert_path、mch_public_cert_path、jsb_public_cert_path(江苏银行公钥,用于解密)、notify_url、mode。
下单:
$result = Pay::jsb()->scan($order);
项目边界
受测试与使用环境限制,目前只开发了支付宝、微信支付、抖音支付、银联、江苏银行相关网关。若有其它网关需求或改进,可以 Fork 后提 PR。