微信支付回调收不到通知主因是未通过可达性校验:需公网HTTPS地址、有效证书、GET验证echostr、POST解析XML;Laravel应使用overtrue/wechat SDK验签并查单,结合唯一索引或Redis防重,预支付须用configForJsApiPayment生成合规参数。

微信支付回调地址为什么收不到通知?
微信支付回调不是靠前端跳转或用户点击触发的,而是微信服务器主动 POST 请求你的接口。如果收不到,大概率是没过微信的「可达性校验」。
- 确保回调 URL 是公网可访问的(本地
localhost或内网地址一律失败) - 微信要求回调地址必须是 HTTPS,且证书有效(自签名证书不行)
- 首次接入时,微信会先发一个
echostrGET 请求做验证,你的路由必须原样返回该字符串(Laravel 中需临时允许 GET,不能只写Route::post()) - 正式回调是 POST,但微信不带
Content-Type: application/json,而是application/xml—— 别用request()->json()去取,要用file_get_contents('php://input')解析原始 XML
Laravel 怎么安全地验签并解析微信回调 XML?
微信回调里所有字段都可能被伪造,必须严格验签。别自己手写签名逻辑,直接用官方 SDK 或成熟封装(如 overtrue/wechat),否则极易漏掉字段排序、空值处理、编码差异等细节。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
- 安装 SDK:
composer require "overtrue/wechat:~5.0"(适配 Laravel 8+) - 配置好商户号
app_id、mch_id、key和cert_path(退款等操作需要证书) - 在控制器中用
$app->payment->handleNotify()处理回调:它自动验签、解密(如有)、转数组,并抛出异常拦截非法请求 - 切记:验签通过后,必须主动调用微信的
orderquery接口查单,确认订单真实状态 —— 因为回调可能重复发、延迟发,甚至伪造
怎么避免 Laravel 支付回调重复处理?
微信明确说明:回调可能多次推送(网络超时、你没返回成功响应等)。如果每次回调都发货、扣库存、改状态,业务就乱了。
- 用数据库唯一约束防重:比如在订单表加
transaction_id字段(微信返回的transaction_id),设为唯一索引 - 或者用 Redis 加锁:
Redis::setex('pay_lock_'.$request->out_trade_no, 300, '1'),先抢锁再处理,5 分钟内相同订单只进一次 - 更稳妥的是「幂等更新」:只执行状态从
pending→paid的更新,SQL 加条件WHERE status = 'pending',哪怕重复执行也不翻车 - 千万别在回调里直接调外部 HTTP 接口(比如发短信、推消息),这些操作应丢进队列异步执行,否则超时会导致微信重试
微信 JSAPI 支付在 Laravel 怎么生成预支付参数?
前端调 wx.requestPayment 需要后端返回 7 个字段,缺一不可,且 timeStamp 必须是字符串类型的时间戳(不是整数),package 必须是 prepay_id=xxx 格式。
- 用
$app->payment->prepare()构建预支付,传入trade_type为JSAPI,并带上用户的openid - 注意
notify_url必须和公众号后台配置的一致,且不能带查询参数(微信不认?v=1这种) - 返回给前端的数据必须经过
$app->payment->configForJsApiPayment()包装,它会自动补全appId、生成正确timeStamp、计算paySign - 常见错误:
invalid appid多半是公众号 AppID 和商户号绑定关系没配对;package error一般是package字段格式不对或大小写错误


















