Laravel怎么实现微信支付接入 _ Laravel 微信支付SDK集成方法【指南】

1次阅读

微信支付回调验签失败主因是配置错误:notify_url需公网https且无参数,证书须放storage/app/certs/并设600权限,sdk中cert_path和key_path用绝对路径;laravel需禁用trimstrings中间件防header过滤。

Laravel怎么实现微信支付接入 _ Laravel 微信支付SDK集成方法【指南】

微信支付回调验签总失败?别急着改代码,先检查 notify_url 和证书路径

Laravel 接入微信支付最常卡在回调验签失败,错误通常是 INVALID_SIGNATUREMISSING_PARAM。这不是 SDK 本身的问题,而是配置没对齐。

  • notify_url 必须是公网可访问的 https 地址,且不能带查询参数(如 https://xxx.com/pay/callback?from=wechat 会失败)
  • 微信支付 V3 接口要求传 apiclient_cert.pemapiclient_key.pem,这两个文件必须由商户平台下载后,**直接放在 storage/app/certs/ 下,且权限为 600**(Laravel 进程需有读取权限)
  • SDK 初始化时传的 cert_pathkey_path 必须是绝对路径,推荐用 storage_path('app/certs/apiclient_cert.pem'),别用相对路径或 public_path()
  • 微信回调请求头里带 Wechatpay-Serial,Laravel 默认会过滤掉带连字符的 header,需在 AppHttpKernel$middleware 中确认没启用 TrimStrings 或类似中间件干扰原始 header

Laravel 10+ 用 wechatpay-apiv3 SDK 怎么发统一下单?关键在 HttpClient 配置

官方推荐的 wechatpay-apiv3 是纯 PHP SDK,不依赖 Laravel,但和 Laravel 的 Http facade 冲突——它自己封装curl,不能复用 Laravel 的全局 HTTP 设置。

  • 下单前必须调用 WechatPayHttpClient::create(...) 构造客户端,其中 merchantIdserialNoprivateKey 缺一不可;serialNo 不是证书序列号,而是微信商户平台「API 安全」页里显示的「证书序列号」(32 位十六进制字符串
  • 下单参数中 notify_url 必须和后台配置完全一致(包括末尾斜杠),amount 单位是分,description 不能含 emoji 或控制字符,否则返回 PARAM_ERROR
  • 不要手动拼接 jsON body,用 SDK 提供的 json::encode($data),否则中文乱码或空格差异会导致签名失败
  • 调用 $client->post('/v3/pay/transactions/jsapi', $body) 后,响应是标准 JSON,直接 json_decode($response->getBody()->getContents(), true) 即可,不用再解密(V3 接口已取消响应加密)

前端 JSAPI 支付唤起失败?检查 prepay_id 签名和域名白名单

后端返回了 prepay_id,但前端调用 WXJSSDK.chooseWXPay 报错 invalid signature,90% 是签名环节出了问题。

  • 签名字段必须严格按顺序: appIdnonceStrpackagesignTypetimestamp,少一个、顺序错、大小写错都不行
  • package 值是字符串 prepay_id=xxx,不是数组,不是 JSON,不能加引号
  • 签名用的 nonceStrtimeStamp 必须和后端统一下单时传给微信的一致(很多同学前端自己生成一套,后端又生成一套,必然失败)
  • 公众号 JSAPI 支付的调用域名,必须在微信公众号后台「公众号设置 → 功能设置 → JS 接口安全域名」里配置,且只能填一级域名(如 pay.example.com,不能填 https://pay.example.com

沙箱环境能跑通,正式环境一直 SYSTEMERROR?重点查 sub_mch_id 和子商户资质

如果你接入的是服务商模式(比如帮客户代商户收款),SYSTEMERROR 往往不是代码问题,而是资质或参数错位。

  • 正式环境必须用正式证书,沙箱证书无效;且 sub_mch_id 必须是微信分配的真实子商户号,不能是测试号
  • 服务商调用统一下单接口时,sub_mch_id 要放在请求 body 顶层,同时 headers 里还得带 Authorization: WECHATPAY2-SHA256-RSA2048 ...,这个签名要包含 sub_mch_id 字段(SDK 默认不包含,得手动 patch 或换用支持服务商模式的封装库)
  • 子商户必须已在微信服务商平台完成「产品签约」,且开通了 JSAPI 支付权限;仅签约不等于可用,还得在「子商户管理 → 权限配置」里手动勾选
  • 调试时别只看返回体,用微信支付「商户平台 → 交易中心 → API 安全 → 查看调用日志」,那里能看到真实错误原因(比如 sub_mch_id not exist

微信支付正式环境的限制比文档写的更死板,尤其是服务商场景下,sub_mch_id、证书、权限、签名字段这四样,漏一个就卡住,而且错误码统一返回 SYSTEMERROR,得靠日志反推。

text=ZqhQzanResources