应选用yansongda/pay 4.x封装包,自动处理签名、解密、证书加载与回调验签;安装无需修改config/app.php,配置pay.php并严格校验证书与密钥格式;支付调用分支付宝web跳转与微信JSAPI预支付;异步通知必须调用verify()验签,支付宝返回'success',微信返回空响应体。

要在Laravel项目中快速部署并安全接入第三方支付接口,必须绕过手动拼接签名、硬编码密钥、裸写HTTP请求等高危操作,直接使用经生产验证的封装包,且异步通知验签不可跳过。
选型与安装
优先选用 【yansongda/pay 4.x】 ——它同时支持支付宝、微信(V2/V3)、银联、PayPal 等主流网关,自动处理RSA2签名、AES解密、证书加载、回调验签,且兼容 Laravel 9~13 全版本。
执行安装命令:
composer require yansongda/pay:^4.0 -vvv
该包不依赖 Laravel 服务提供者自动注册,【无需修改 config/app.php】,避免 Laravel 11+ 中因弃用 $providers 数组导致报错。
配置支付参数
在 config 目录下新建 pay.php 文件,内容如下:
<?php
return [
'alipay' => [
'app_id' => env('ALIPAY_APP_ID'),
'notify_url' => 'https://yourdomain.com/api/v1/pay/alipay/notify',
'return_url' => 'https://yourdomain.com/api/v1/pay/alipay/return',
'ali_public_key' => file_get_contents(base_path('storage/certs/alipay_public.key')),
'private_key' => file_get_contents(base_path('storage/certs/app_private.key')),
'log' => [
'file' => storage_path('logs/alipay.log'),
'level' => 'debug'
],
'mode' => 'normal'
],
'wechat' => [
'app_id' => env('WECHAT_APPID'),
'mch_id' => env('WECHAT_MCH_ID'),
'key' => env('WECHAT_API_V3_KEY'),
'cert_client' => base_path('storage/certs/wechat_apiclient_cert.pem'),
'cert_key' => base_path('storage/certs/wechat_apiclient_key.pem'),
'notify_url' => 'https://yourdomain.com/api/v1/pay/wechat/notify'
]
];
注意:微信 V3 的 cert_client 和 cert_key 必须是 PEM 格式,且私钥不能设密码;支付宝的 private_key 必须为原始 RSA 私钥(无头尾标记),ali_public_key 必须为支付宝公钥(非应用公钥)。
发起支付请求
方法一:手机网站支付(支付宝)
在控制器中调用:
$pay = Pay::alipay()->web([
'out_trade_no' => 'ORD'.date('ymdHis').rand(1000, 9999),
'subject' => '会员年费',
'total_amount' => '99.00',
'quit_url' => url('/'),
]);
return response($pay->redirect());
这一步会返回一个自动提交的 HTML form,前端无需 JS 干预即可跳转至支付宝收银台。
方法二:JSAPI 支付(微信公众号)
需先获取用户 openid,再调用:
$pay = Pay::wechat()->mp([
'out_trade_no' => 'WX'.now()->format('ymdHis').Str::random(4),
'body' => '课程购买',
'total_fee' => 19900,
'openid' => $request->input('openid'),
]);
return response()->json($pay->getPrepayId());
注意:微信 JSAPI 返回的是 prepay_id,前端需用 wx.requestPayment 拼装签名后唤起支付,不是直接跳转 URL。
处理异步通知
第一步:定义路由(必须为 POST,且路径与配置中 notify_url 严格一致)
Route::post('/api/v1/pay/alipay/notify', [PaymentController::class, 'alipayNotify'])->withoutMiddleware(['web']);
第二步:在 PaymentController 中编写验签与状态更新逻辑
public function alipayNotify(Request $request)
{
$data = Pay::alipay()->verify();
if ($data->trade_status === 'TRADE_SUCCESS') {
$order = Order::where('no', $data->out_trade_no)->firstOrFail();
if ($order->status !== 'paid') {
$order->update(['status' => 'paid', 'paid_at' => now()]);
event(new OrderPaid($order));
}
}
return 'success'; // 必须原样返回字符串 success,否则支付宝持续重发
}
【关键点:verify() 方法已内置验签+参数过滤+重复通知拦截,绝不允许跳过此步直接读 $_POST】
第三步:微信 V3 通知处理需额外校验平台证书
public function wechatNotify(Request $request)
{
$payload = $request->getContent();
$headers = $request->header();
$verified = Pay::wechat()->verify($payload, $headers);
if ($verified && $verified['event_type'] === 'TRANSACTION.SUCCESS') {
$order = Order::where('no', $verified['resource']['out_trade_no'])->first();
$order?->update(['status' => 'paid', 'paid_at' => now()]);
}
return response()->raw(''); // 微信要求空响应体 + 200 状态码
}


















