优先选用社区 Laravel 封装包(如 lokielse/laravel-alipay),避免直接集成官方 SDK;PC 支付需正确配置公网可访问的 return_url 和 notify_url;异步通知验签失败主因是原始 POST 被 Laravel 预处理,须用 php://input 获取原始数据并剔除 sign/sign_type 后按字典序拼接;上线前须验证 notify 接口可达性、响应速度及补单机制。

支付宝 SDK 官方不支持 Laravel,别直接 composer require alipay
支付宝官方 PHP SDK(alipay-sdk-php)是面向原生 PHP 设计的,没有 Laravel 服务提供者、Facade 或配置驱动机制。强行拉进来会卡在签名构造、异步通知验签、响应格式封装这些环节——不是不能用,而是每次都要手动 new AlipayAopClient、拼 AlipayTradePagePayRequest、处理 $_POST 原始数据,和 Laravel 的请求生命周期脱节。
实操建议:
- 优先选社区维护的 Laravel 封装包,比如
lokielse/laravel-alipay(Laravel 8+ 兼容性好,文档清晰) - 如果项目已上线且用的是旧版 Laravel(如 5.8),可降级使用
laravel-shop/alipay,但注意它依赖guzzlehttp/guzzle: ~6.0,PHP 8+ 会报错 - 绝对不要自己封装「通用支付门面」——支付宝 PC 支付、手机网站支付、App 支付、小程序支付的参数结构、回调路径、验签方式全都不一样,硬统一反而埋坑
Laravel 中怎么生成支付宝 PC 支付跳转链接
核心是调用 alipay()->web()(以 lokielse/laravel-alipay 为例),但它背后实际组装的是 AlipayTradePagePayRequest,必须填对 return_url 和 notify_url ——这两个 URL 必须是**公网可访问的完整地址**,本地 http://localhost:8000 会失败,支付宝服务器根本访问不到。
常见错误现象:INVALID_PARAMETER 错误,或跳转后显示「订单不存在」
实操建议:
-
return_url填用户付款成功后跳回的页面,比如https://yoursite.com/pay/success;它只做展示,不参与业务逻辑校验 -
notify_url必须是 POST 接口,且不能带任何中间件(如auth、VerifyCsrfToken),Laravel 默认会拦截,需在app/Http/Middleware/VerifyCsrfToken.php的$except数组里加上/pay/notify - 订单号
out_trade_no必须全局唯一、不能含中文或特殊字符,建议用date('ymd') . str_pad($id, 8, '0', STR_PAD_LEFT)这类可控格式
支付宝异步通知(notify)验签总失败?检查这三点
90% 的验签失败不是因为密钥配错,而是 Laravel 对原始 POST 数据做了预处理:自动解析 JSON、过滤空格、强制转义,导致支付宝发来的原始 $_POST 数组被篡改,AlipaySignature::rsaCheckV1() 拿到的数据和签名原文对不上。
实操建议:
- 在控制器方法里第一行加
file_get_contents('php://input'),确认是否能拿到原始字符串;如果为空,说明请求没进到 Laravel 而是被 Nginx/Apache 拦截了(检查是否开启client_max_body_size或LimitRequestBody) - 验签前必须剔除
sign、sign_type字段,并对剩余参数按 key 字典序排序后拼接成key=value&key=value格式——lokielse/laravel-alipay内部已处理,但如果你手写验签逻辑,千万别用http_build_query($_POST),它会 urlencode,而支付宝验签要求原始值 - 公钥必须用支付宝开放平台「公钥」(不是应用公钥),且格式要严格为
-----BEGIN PUBLIC KEY-----\n...base64...\n-----END PUBLIC KEY-----,Windows 换行符(\r\n)会导致验签失败
沙箱环境调试通了,上线后支付成功但 notify 不触发
支付宝不会主动「重试」失败的 notify,一旦你的接口返回非 success(哪怕只是多一个空格、HTTP 状态码不是 200),它就停止推送。线上环境还常因 HTTPS 证书链不完整、域名 DNS 解析不稳定、云服务商安全组屏蔽 443 外呼,导致支付宝服务器根本连不上你的 notify_url。
实操建议:
- 在
notify接口开头加日志:Log::info('Alipay notify raw', ['input' => file_get_contents('php://input')]);,先确认请求是否到达 - 用支付宝开放平台「查看回调日志」功能,看返回状态码和响应体;如果显示
Connection refused或timeout,重点查服务器出网策略和 SSL 证书 - 上线前务必用
curl -X POST https://yourdomain.com/pay/notify -d "..."模拟一次通知,确认响应速度在 3 秒内(支付宝超时阈值)
最麻烦的点其实是支付宝的 notify 是「单向不可靠通道」——它不保证送达,也不提供重推开关,你得自己在订单表加个 notify_status 字段,再配个定时任务每 5 分钟扫一次「已支付但未通知」的订单,主动调用 alipay.trade.query 补单。



















