Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Add Docs
Yansongda Pay
https://github.com/yansongda/pay
Admin
A unified PHP SDK for integrating multiple payment gateways including Alipay, WeChat Pay, Douyin
...
Tokens:
75,244
Snippets:
579
Trust Score:
9.1
Update:
3 weeks ago
Context
Skills
Chat
Benchmark
82
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Yansongda Pay Yansongda Pay 是一款优雅的 PHP 支付 SDK,支持支付宝、微信支付、抖音支付、银联支付、江苏银行等多种支付网关。该 SDK 采用灵活的插件机制和丰富的事件系统,隐藏了复杂的签名、加密细节,让开发者可以用最简洁的代码完成支付集成。SDK 完全兼容各支付平台的官方 API,支持多租户配置、Swoole 协程环境,并遵循 PSR 标准,可与 Laravel、Hyperf、ThinkPHP 等主流框架无缝集成。 核心功能包括:网页支付、H5 支付、APP 支付、小程序支付、扫码支付、刷卡支付(付款码)、账户转账等。同时提供订单查询、退款、关闭订单、取消订单等完整的支付生命周期管理。内置自动获取微信平台证书功能,大幅降低了证书配置的复杂度。 ## 安装 ```bash # Laravel/Hyperf 用户 composer require yansongda/pay:~3.7.0 -vvv # 其它框架用户 composer require yansongda/pay:~3.7.0 -vvv composer require guzzlehttp/guzzle:^7.0 composer require hyperf/pimple:~2.2.0 ``` ## 初始化配置 SDK 初始化需要配置各支付平台的密钥和证书信息,配置一次后全局生效,支持多租户场景。 ```php <?php use Yansongda\Pay\Pay; $config = [ 'alipay' => [ 'default' => [ 'app_id' => '2016082000295641', 'app_secret_cert' => 'MIIEvAIBADANBgkqhkiG9w0BAQEFAASC...', // 应用私钥 'app_public_cert_path' => '/path/to/appCertPublicKey.crt', 'alipay_public_cert_path' => '/path/to/alipayCertPublicKey_RSA2.crt', 'alipay_root_cert_path' => '/path/to/alipayRootCert.crt', 'return_url' => 'https://example.com/alipay/return', 'notify_url' => 'https://example.com/alipay/notify', 'mode' => Pay::MODE_NORMAL, // MODE_NORMAL, MODE_SANDBOX, MODE_SERVICE ], ], 'wechat' => [ 'default' => [ 'mch_id' => '1900000109', 'mch_secret_key' => 'your-v3-secret-key-32bytes', 'mch_secret_cert' => '/path/to/apiclient_key.pem', 'mch_public_cert_path' => '/path/to/apiclient_cert.pem', 'notify_url' => 'https://example.com/wechat/notify', 'mp_app_id' => 'wx55955316af4ef13', 'mini_app_id' => 'wx55955316af4ef14', 'app_id' => 'wx55955316af4ef15', 'wechat_public_cert_path' => [ '45F59D4DABF31918AFCEC556D5D2C6E376675D57' => '/path/to/wechatPublicKey.crt', ], 'mode' => Pay::MODE_NORMAL, ], ], 'logger' => [ 'enable' => true, 'file' => './logs/pay.log', 'level' => 'info', 'type' => 'daily', 'max_file' => 30, ], 'http' => [ 'timeout' => 5.0, 'connect_timeout' => 5.0, ], ]; // 方式一:全局初始化(推荐) Pay::config($config); // 方式二:调用时初始化 Pay::alipay($config)->web($order); // 强制覆盖配置 Pay::config(array_merge($config, ['_force' => true])); // 多租户切换 $order = [ 'out_trade_no' => '1514027114', '_config' => 'tenant_a', // 切换到 tenant_a 租户配置 ]; $result = Pay::alipay()->query($order); ``` ## 支付宝网页支付 网页支付适用于电脑端浏览器发起的支付场景,返回自动提交的 HTML 表单,用户打开后自动跳转到支付宝收银台。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); // 基础网页支付 $result = Pay::alipay()->web([ 'out_trade_no' => date('YmdHis').mt_rand(1000, 9999), 'total_amount' => '99.99', 'subject' => '商品订单-iPhone 15 Pro', ]); return $result; // 返回 Response 对象,包含自动跳转的 HTML // GET 方式提交(返回跳转 URL) $result = Pay::alipay()->web([ 'out_trade_no' => date('YmdHis').mt_rand(1000, 9999), 'total_amount' => '0.01', 'subject' => '测试订单', '_method' => 'get', ]); // 完整参数示例 $result = Pay::alipay()->web([ 'out_trade_no' => date('YmdHis').mt_rand(1000, 9999), 'total_amount' => '188.00', 'subject' => '订单标题', 'body' => '订单描述信息', 'timeout_express' => '30m', // 订单有效期 30 分钟 'goods_detail' => json_encode([ ['goods_id' => 'SKU001', 'goods_name' => '商品A', 'quantity' => 1, 'price' => '188.00'] ]), 'extend_params' => [ 'sys_service_provider_id' => '2088511833207846', // 系统服务商ID ], ]); ``` ## 支付宝 H5 支付 H5 支付适用于手机浏览器发起的支付场景,用户在手机浏览器中完成支付后返回商户页面。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::alipay()->h5([ 'out_trade_no' => date('YmdHis').mt_rand(1000, 9999), 'total_amount' => '29.90', 'subject' => '手机商城订单', 'quit_url' => 'https://example.com/order/detail', // 用户取消支付后返回的地址 ]); return $result; // 返回 Response 对象 // GET 方式 $result = Pay::alipay()->h5([ 'out_trade_no' => time().'', 'total_amount' => '0.01', 'subject' => '测试 H5 订单', 'quit_url' => 'https://example.com', '_method' => 'get', ]); ``` ## 支付宝 APP 支付 APP 支付返回用于客户端调用支付宝 SDK 的 orderString 字符串,供 iOS/Android 客户端调用。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::alipay()->app([ 'out_trade_no' => date('YmdHis').mt_rand(1000, 9999), 'total_amount' => '6.00', 'subject' => 'APP内购订单', ]); // 返回 orderString 供 APP 客户端调用 // Android: alipay.payV2(orderString, callback) // iOS: [[AlipaySDK defaultService] payOrder:orderString callback:^(NSDictionary *resultDic) {}]; return $result->getBody()->getContents(); ``` ## 支付宝小程序支付 小程序支付返回 trade_no,用于在支付宝小程序中调用 my.tradePay 完成支付。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::alipay()->mini([ 'out_trade_no' => date('YmdHis').mt_rand(1000, 9999), 'total_amount' => '0.01', 'subject' => '小程序订单', 'buyer_id' => '2088622190161234', // 买家支付宝用户ID ]); // 获取支付宝交易号,供小程序端调用 $tradeNo = $result->get('trade_no'); // 或 $tradeNo = $result->trade_no; // 小程序端调用示例: // my.tradePay({ // tradeNO: tradeNo, // success: (res) => { console.log(res); }, // fail: (err) => { console.log(err); } // }); ``` ## 支付宝扫码支付 扫码支付返回二维码链接,商户可将此链接生成二维码供用户扫描支付。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::alipay()->scan([ 'out_trade_no' => date('YmdHis').mt_rand(1000, 9999), 'total_amount' => '15.00', 'subject' => '扫码支付订单', ]); // 获取二维码链接 $qrCode = $result->qr_code; // 使用第三方库如 endroid/qr-code 生成二维码图片 ``` ## 支付宝刷卡支付(付款码/被扫码) 刷卡支付用于线下收银场景,用户展示付款码,商户扫描完成支付。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::alipay()->pos([ 'out_trade_no' => date('YmdHis').mt_rand(1000, 9999), 'auth_code' => '284776044441477959', // 用户付款码 'total_amount' => '25.00', 'subject' => '线下门店订单', ]); // 检查支付结果 if ($result->code === '10000' && $result->trade_status === 'TRADE_SUCCESS') { echo '支付成功,交易号:' . $result->trade_no; } ``` ## 支付宝账户转账 账户转账用于向支付宝账户转账,适用于用户提现、佣金发放等场景。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::alipay()->transfer([ 'out_biz_no' => date('YmdHis').mt_rand(1000, 9999), 'trans_amount' => '100.00', 'product_code' => 'TRANS_ACCOUNT_NO_PWD', 'biz_scene' => 'DIRECT_TRANSFER', 'payee_info' => [ 'identity' => 'user@example.com', // 收款方支付宝登录号 'identity_type' => 'ALIPAY_LOGON_ID', 'name' => '张三', // 收款方真实姓名 ], 'remark' => '佣金提现', ]); // 检查转账结果 if ($result->code === '10000') { echo '转账成功,订单号:' . $result->order_id; } ``` ## 支付宝查询订单 查询订单状态,支持查询支付订单、退款订单和转账订单。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); // 查询支付订单 $result = Pay::alipay()->query([ 'out_trade_no' => '20231225143052001', // 或使用支付宝交易号 // 'trade_no' => '2023122522001419121412345678', ]); echo '交易状态:' . $result->trade_status; // WAIT_BUYER_PAY, TRADE_SUCCESS, TRADE_CLOSED // 查询不同类型订单 $result = Pay::alipay()->query([ 'out_trade_no' => '20231225143052001', '_action' => 'app', // web(默认), app, mini, pos, scan, h5 ]); // 查询退款订单 $result = Pay::alipay()->query([ 'out_trade_no' => '20231225143052001', 'out_request_no' => '20231225143052001_refund', // 退款请求号 '_action' => 'refund', // refund_web, refund_app, refund_mini, refund_pos, refund_scan, refund_h5 ]); // 查询转账订单 $result = Pay::alipay()->query([ 'out_biz_no' => '202312250001', '_action' => 'transfer', ]); ``` ## 支付宝退款 对已支付成功的订单进行退款,支持部分退款和全额退款。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); // 全额退款 $result = Pay::alipay()->refund([ 'out_trade_no' => '20231225143052001', 'refund_amount' => '99.99', 'out_request_no' => '20231225143052001_refund_001', // 退款请求号,部分退款必填 ]); // 部分退款(可多次) $result = Pay::alipay()->refund([ 'out_trade_no' => '20231225143052001', 'refund_amount' => '30.00', 'out_request_no' => '20231225143052001_refund_002', 'refund_reason' => '用户申请部分退款', ]); // 指定订单类型退款 $result = Pay::alipay()->refund([ 'out_trade_no' => '20231225143052001', 'refund_amount' => '10.00', '_action' => 'app', // web(默认), app, mini, pos, scan, h5 ]); if ($result->code === '10000') { echo '退款成功,退款金额:' . $result->refund_fee; } ``` ## 支付宝关闭订单 关闭未支付的订单,关闭后用户将无法继续支付该订单。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::alipay()->close([ 'out_trade_no' => '20231225143052001', // '_action' => 'web', // web(默认), mini, scan, pos, h5 ]); if ($result->code === '10000') { echo '订单已关闭'; } ``` ## 支付宝取消订单 取消订单会尝试撤销交易,如果用户已付款则自动退款,适用于刷卡支付等线下场景。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::alipay()->cancel([ 'out_trade_no' => '20231225143052001', '_action' => 'pos', // pos(默认), mini, scan ]); if ($result->code === '10000') { echo '订单取消成功,操作类型:' . $result->action; // close(关闭), refund(退款) } ``` ## 支付宝回调处理 处理支付宝的同步返回和异步通知,SDK 自动完成签名验证。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); // 同步返回(return_url)处理 public function returnCallback() { try { $data = Pay::alipay()->callback(); // 获取回调数据 $outTradeNo = $data->out_trade_no; // 商户订单号 $tradeNo = $data->trade_no; // 支付宝交易号 $totalAmount = $data->total_amount; // 订单金额 return redirect('/order/success'); } catch (\Throwable $e) { return redirect('/order/fail'); } } // 异步通知(notify_url)处理 public function notifyCallback() { try { $data = Pay::alipay()->callback(); // 验证通知数据 // 1. 验证 out_trade_no 是否为商户系统创建的订单号 // 2. 判断 total_amount 是否正确 // 3. 校验 seller_id 是否正确 // 4. 验证 app_id 是否为商户本身 if ($data->trade_status === 'TRADE_SUCCESS' || $data->trade_status === 'TRADE_FINISHED') { // 处理业务逻辑,更新订单状态 Order::where('out_trade_no', $data->out_trade_no)->update(['status' => 'paid']); } return Pay::alipay()->success(); // 返回 success 告知支付宝处理成功 } catch (\Throwable $e) { Log::error('支付宝回调失败:' . $e->getMessage()); return 'fail'; } } // Swoole/Hyperf 环境使用 ServerRequestInterface public function notifyCallback(ServerRequestInterface $request) { $data = Pay::alipay()->callback($request); // ... return Pay::alipay()->success(); } // 切换租户配置 $data = Pay::alipay()->callback(null, ['_config' => 'tenant_b']); ``` ## 微信公众号支付(JSAPI) 公众号支付返回调用微信 JSAPI 所需的参数,用于在微信内 H5 页面中调起微信支付。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::wechat()->mp([ 'out_trade_no' => date('YmdHis').mt_rand(1000, 9999), 'description' => '公众号支付订单', 'amount' => [ 'total' => 1, // 单位:分 'currency' => 'CNY', ], 'payer' => [ 'openid' => 'oUpF8uMEb4qRXf22hE3X68TekukE', // 用户 openid ], ]); // 返回前端调用所需参数 $jsApiParams = [ 'appId' => $result->appId, 'timeStamp' => $result->timeStamp, 'nonceStr' => $result->nonceStr, 'package' => $result->package, 'signType' => $result->signType, 'paySign' => $result->paySign, ]; // 前端 JS 调用示例: // WeixinJSBridge.invoke('getBrandWCPayRequest', jsApiParams, function(res) { // if (res.err_msg == "get_brand_wcpay_request:ok") { // // 支付成功 // } // }); ``` ## 微信 H5 支付 微信 H5 支付适用于非微信浏览器发起的支付,返回跳转 URL,用户跳转后完成支付。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::wechat()->h5([ 'out_trade_no' => date('YmdHis').mt_rand(1000, 9999), 'description' => 'H5支付订单', 'amount' => [ 'total' => 100, // 单位:分 ], 'scene_info' => [ 'payer_client_ip' => request()->ip(), // 用户 IP 'h5_info' => [ 'type' => 'Wap', // 场景类型 ], ], ]); // 获取支付跳转链接 $h5Url = $result->h5_url; // 拼接 redirect_url 参数指定支付完成后跳转地址 $redirectUrl = $h5Url . '&redirect_url=' . urlencode('https://example.com/order/result'); return redirect($redirectUrl); // 使用小程序 appid 关联 H5 支付 $result = Pay::wechat()->h5([ '_type' => 'mini', // 使用小程序 appid 'out_trade_no' => time().'', 'description' => '测试订单', 'amount' => ['total' => 1], 'scene_info' => [ 'payer_client_ip' => '1.2.4.8', 'h5_info' => ['type' => 'Wap'], ], ]); ``` ## 微信 APP 支付 APP 支付返回客户端调用微信 SDK 所需的参数。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::wechat()->app([ 'out_trade_no' => date('YmdHis').mt_rand(1000, 9999), 'description' => 'APP内购订单', 'amount' => [ 'total' => 100, ], ]); // 返回 APP 客户端调用所需参数 $appParams = [ 'appid' => $result->appid, 'partnerid' => $result->partnerid, 'prepayid' => $result->prepayid, 'package' => $result->package, 'noncestr' => $result->noncestr, 'timestamp' => $result->timestamp, 'sign' => $result->sign, ]; return response()->json($appParams); ``` ## 微信小程序支付 小程序支付返回调用 wx.requestPayment 所需的参数。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::wechat()->mini([ 'out_trade_no' => date('YmdHis').mt_rand(1000, 9999), 'description' => '小程序订单', 'amount' => [ 'total' => 1, 'currency' => 'CNY', ], 'payer' => [ 'openid' => 'oUpF8uMEb4qRXf22hE3X68TekukE', ], ]); // 返回小程序调用参数 $miniParams = [ 'timeStamp' => $result->timeStamp, 'nonceStr' => $result->nonceStr, 'package' => $result->package, 'signType' => $result->signType, 'paySign' => $result->paySign, ]; // 小程序端调用: // wx.requestPayment({ // timeStamp: miniParams.timeStamp, // nonceStr: miniParams.nonceStr, // package: miniParams.package, // signType: miniParams.signType, // paySign: miniParams.paySign, // success(res) { console.log('支付成功'); }, // fail(err) { console.log('支付失败', err); } // }); ``` ## 微信扫码支付(Native) 扫码支付返回二维码链接,用于生成收款二维码。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::wechat()->scan([ 'out_trade_no' => date('YmdHis').mt_rand(1000, 9999), 'description' => '扫码支付订单', 'amount' => [ 'total' => 100, ], ]); // 获取二维码内容 $codeUrl = $result->code_url; // 使用二维码库生成图片展示给用户扫描 ``` ## 微信刷卡支付(付款码) 线下收银场景,商户扫描用户付款码完成支付。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::wechat()->pos([ 'out_trade_no' => date('YmdHis').mt_rand(1000, 9999), 'description' => '线下门店订单', 'amount' => [ 'total' => 100, ], 'payer' => [ 'auth_code' => '134567890123456789', // 用户付款码 ], 'scene_info' => [ 'id' => 'store_001', // 门店编号 ], ]); ``` ## 微信商家转账 向用户零钱转账,适用于红包、佣金提现等场景。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); // 新版商家转账(2025年1月15日后新商户使用) $result = Pay::wechat()->transfer([ 'out_bill_no' => date('YmdHis').mt_rand(1000, 9999), 'transfer_scene_id' => '1001', // 转账场景ID 'openid' => 'oUpF8uMEb4qRXf22hE3X68TekukE', 'transfer_amount' => 100, // 单位:分 'transfer_remark' => '佣金提现', 'transfer_scene_report_infos' => [ ['info_type' => '活动名称', 'info_content' => '推广返佣'], ['info_type' => '奖励说明', 'info_content' => '邀请好友奖励'], ], ]); // 旧版批量转账(2025年1月15日前商户可用) $result = Pay::wechat()->transfer([ 'out_batch_no' => date('YmdHis').mt_rand(1000, 9999), 'batch_name' => '2023年12月推广佣金', 'batch_remark' => '佣金发放', 'total_amount' => 200, 'total_num' => 2, 'transfer_detail_list' => [ [ 'out_detail_no' => date('YmdHis').'001', 'transfer_amount' => 100, 'transfer_remark' => '推广佣金', 'openid' => 'oUpF8uMEb4qRXf22hE3X68TekukE', // 'user_name' => '张三', // 明文传参,SDK 自动加密 ], [ 'out_detail_no' => date('YmdHis').'002', 'transfer_amount' => 100, 'transfer_remark' => '推广佣金', 'openid' => 'oUpF8uMEb4qRXf22hE3X68TekukF', ], ], ]); ``` ## 微信查询订单 查询支付订单、退款订单和转账订单。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); // 查询支付订单 $result = Pay::wechat()->query([ 'out_trade_no' => '20231225143052001', // '_action' => 'jsapi', // jsapi(默认), app, h5, mini, native, combine ]); echo '交易状态:' . $result->trade_state; // SUCCESS, NOTPAY, CLOSED, REFUND // 查询退款订单 $result = Pay::wechat()->query([ 'out_refund_no' => '20231225143052001_refund', '_action' => 'refund', // refund_jsapi, refund_app, refund_h5, refund_mini, refund_native ]); // 查询转账订单(新版) $result = Pay::wechat()->query([ 'out_bill_no' => '20231225143052001', // 商户单号 '_action' => 'mch_transfer', ]); // 查询转账订单(旧版) $result = Pay::wechat()->query([ 'out_batch_no' => '20231225143052001', 'out_detail_no' => '20231225143052001001', '_action' => 'transfer', ]); ``` ## 微信退款 对已支付订单进行退款操作。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); $result = Pay::wechat()->refund([ 'out_trade_no' => '20231225143052001', 'out_refund_no' => '20231225143052001_refund_001', 'amount' => [ 'refund' => 50, // 退款金额(分) 'total' => 100, // 原订单金额(分) 'currency' => 'CNY', ], 'reason' => '用户申请退款', // '_action' => 'jsapi', // jsapi(默认), app, h5, mini, native, combine ]); if ($result->status === 'SUCCESS') { echo '退款成功'; } ``` ## 微信回调处理 处理微信支付的异步通知,SDK 自动完成签名验证和数据解密。 ```php <?php use Yansongda\Pay\Pay; Pay::config($config); public function notifyCallback() { try { $data = Pay::wechat()->callback(); // 回调数据已自动解密 $outTradeNo = $data->out_trade_no; $transactionId = $data->transaction_id; $tradeState = $data->trade_state; if ($tradeState === 'SUCCESS') { // 更新订单状态 Order::where('out_trade_no', $outTradeNo)->update([ 'status' => 'paid', 'transaction_id' => $transactionId, ]); } return Pay::wechat()->success(); // 返回成功响应 } catch (\Throwable $e) { Log::error('微信回调失败:' . $e->getMessage()); return response()->json(['code' => 'FAIL', 'message' => '失败']); } } // Swoole/Hyperf 环境 public function notifyCallback(ServerRequestInterface $request) { $data = Pay::wechat()->callback($request); // ... return Pay::wechat()->success(); } ``` ## 抖音小程序支付 抖音支付目前支持小程序支付场景。 ```php <?php use Yansongda\Pay\Pay; $config = [ 'douyin' => [ 'default' => [ 'mch_id' => '73744242495132490630', 'mch_secret_token' => 'your_token', 'mch_secret_salt' => 'your_salt_key', 'mini_app_id' => 'tt226e54d3bd581bf801', 'notify_url' => 'https://example.com/douyin/notify', ], ], ]; Pay::config($config); $result = Pay::douyin()->mini([ 'out_order_no' => date('YmdHis').mt_rand(1000, 9999), 'total_amount' => 100, // 单位:分 'subject' => '商品订单标题', 'body' => '商品订单描述', 'valid_time' => 600, // 有效期 600 秒 ]); // 获取小程序调用参数 $orderId = $result->data['order_id']; $orderToken = $result->data['order_token']; // 小程序端调用 tt.pay // tt.pay({ // orderInfo: { order_id: orderId, order_token: orderToken }, // success(res) { console.log('支付成功'); }, // fail(err) { console.log('支付失败'); } // }); // 回调处理 public function notifyCallback() { $data = Pay::douyin()->callback(); // 处理业务逻辑 return Pay::douyin()->success(); } ``` ## 银联支付 银联支付支持网页支付、H5 支付、扫码支付和刷卡支付。 ```php <?php use Yansongda\Pay\Pay; $config = [ 'unipay' => [ 'default' => [ 'mch_id' => '777290058167151', 'mch_cert_path' => '/path/to/unipayAppCert.pfx', 'mch_cert_password' => '000000', 'unipay_public_cert_path' => '/path/to/unipayCertPublicKey.cer', 'return_url' => 'https://example.com/unipay/return', 'notify_url' => 'https://example.com/unipay/notify', 'mode' => Pay::MODE_NORMAL, ], ], ]; Pay::config($config); // 电脑网页支付 $result = Pay::unipay()->web([ 'txnTime' => date('YmdHis'), 'txnAmt' => 100, // 单位:分 'orderId' => 'unipay'.date('YmdHis'), ]); return $result; // 返回自动提交的 HTML 表单 // H5 支付 $result = Pay::unipay()->h5([ 'txnTime' => date('YmdHis'), 'txnAmt' => 100, 'orderId' => 'unipay'.date('YmdHis'), ]); // 扫码支付 $result = Pay::unipay()->scan([ 'txnTime' => date('YmdHis'), 'txnAmt' => 100, 'orderId' => 'scan'.date('YmdHis'), ]); $qrCode = $result->qrCode; // 刷卡支付 $result = Pay::unipay()->pos([ 'qrNo' => '123456789012345678', 'txnTime' => date('YmdHis'), 'txnAmt' => 100, 'orderId' => 'pos'.date('YmdHis'), ]); ``` ## 事件监听 SDK 提供丰富的事件系统,可在支付流程的各个阶段进行监听和处理。 ```php <?php use Yansongda\Pay\Pay; use Yansongda\Pay\Event; use Yansongda\Pay\Event\PayStart; use Yansongda\Pay\Event\PayEnd; use Yansongda\Pay\Event\HttpStart; use Yansongda\Pay\Event\HttpEnd; use Yansongda\Pay\Event\CallbackReceived; // 需要先安装事件组件 // composer require symfony/event-dispatcher Pay::config($config); // 监听支付开始事件 Event::addListener(PayStart::class, function (PayStart $event) { Log::info('支付开始', [ 'params' => $event->params, 'plugins' => $event->plugins, ]); }); // 监听支付完成事件 Event::addListener(PayEnd::class, function (PayEnd $event) { Log::info('支付完成', [ 'result' => $event->rocket->getDestination(), ]); }); // 监听 API 调用开始 Event::addListener(HttpStart::class, function (HttpStart $event) { Log::info('开始调用支付接口'); }); // 监听 API 调用结束 Event::addListener(HttpEnd::class, function (HttpEnd $event) { Log::info('支付接口调用完成'); }); // 监听收到回调通知 Event::addListener(CallbackReceived::class, function (CallbackReceived $event) { Log::info('收到支付回调', [ 'provider' => $event->provider, 'contents' => $event->contents, ]); }); // 使用类方式监听 class PaymentListener { public function onPayStart(PayStart $event) { // 发送支付开始通知 } public function onPayEnd(PayEnd $event) { // 记录支付日志 } } $listener = new PaymentListener(); Event::addListener(PayStart::class, [$listener, 'onPayStart']); Event::addListener(PayEnd::class, [$listener, 'onPayEnd']); ``` ## 获取微信平台证书 SDK 内置获取微信平台公钥证书的方法,简化证书配置流程。 ```php <?php use Yansongda\Pay\Pay; use function Yansongda\Pay\get_wechat_public_certs; Pay::config($config); // 方式一:直接保存证书到指定目录 get_wechat_public_certs( ['_config' => 'default'], // 多租户时指定配置 '/path/to/cert/wechat' // 保存目录 ); // 证书将保存为:/path/to/cert/wechat/{serial_no}.pem // 方式二:获取证书内容(用于调试或自定义处理) $certs = get_wechat_public_certs(['_config' => 'default']); var_dump($certs); // 输出证书序列号和内容,可自行保存使用 ``` ## 总结 Yansongda Pay 是一个功能全面、设计优雅的 PHP 支付 SDK,主要适用于以下场景:电商平台的在线支付集成、SaaS 系统的多租户支付需求、线下门店的收银系统、小程序/APP 的支付功能开发、企业级的资金管理(转账、退款)等。SDK 通过统一的 API 接口封装了支付宝、微信支付、银联等主流支付平台的差异,让开发者无需深入了解各平台的复杂协议细节。 在集成模式上,SDK 支持多种框架环境:Laravel/Hyperf 用户可直接使用框架扩展包获得更好的集成体验;ThinkPHP 及其他框架用户通过简单配置 Container 即可使用;Swoole 协程环境下支持自动复用连接和协程安全。推荐的最佳实践包括:生产环境务必配置 logger 记录支付日志、使用事件系统解耦业务逻辑、回调处理时做好幂等性校验、敏感配置信息使用环境变量管理、定期更新平台证书确保安全性。