You need to enable JavaScript to run this app. Laravel支付网关回调POST请求报错:不支持GET方法如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Laravel支付网关回调POST请求报错:不支持GET方法如何解决

解决方案

问题根因

  • 你混淆了支付网关的两类回调:
    1. 服务器异步通知(notify):是网关服务器后台主动发POST请求到你的服务端,不会经过用户浏览器,用于你可靠更新订单状态
    2. 用户同步跳转(return):是用户支付完成后,网关引导用户浏览器用GET方式跳转回你的站点,仅用于给用户展示支付结果,不可靠,不能用来更新订单状态
  • 你把两类回调的地址都填成了同一个POST路由,用户跳转时走GET请求自然会报方法不支持的错误
  • 放在web.php的路由默认带CSRF校验,网关发来的POST请求没有携带你的站点CSRF令牌,会被中间件拦截,所以你拿不到POST参数

修复步骤

1. 拆分两个回调路由

首先建议把异步通知路由放到routes/api.php里(api路由默认关闭CSRF校验,前缀自动带/api,最终地址是/api/gateway/confirm_payment/{order_id}):

// api.php 中添加,给网关服务器做异步POST回调使用
Route::post('gateway/confirm_payment/{order_id}', 'Website\GatewayController@confirm_payment');

// web.php 中添加,给用户支付完成后跳转使用
Route::get('gateway/payment_return/{order_id}', 'Website\GatewayController@payment_return');

如果一定要把异步路由放在web.php,需要在app/Http/Middleware/VerifyCsrfToken.php中把该路由加入CSRF白名单:

protected $except = [
    'gateway/confirm_payment/*',
];

2. 调整控制器异步通知逻辑

use Illuminate\Http\Request;
public function confirm_payment(Request $request, $order_id){
    $merchant_key    = 'xxxxxx';
    $merchant_salt   = 'xxxxxx';
    // 不要用原生$_POST,直接用Laravel的Request对象获取参数
    $hash = base64_encode( hash_hmac('sha256', 
    $request->merchant_oid.$merchant_salt.$request->status.$request->total_amount, $merchant_key, true) );
    
    if( $hash != $request->hash) {
        // 签名校验失败直接返回错误,按网关要求返回指定失败字符串即可
        return 'fail';
    }

    if( $request->status == 'success' ) {
        // 这里不要用dd(),dd会终止请求且输出调试信息,网关会认为回调失败
        // 处理订单成功逻辑:更新订单状态、入账等
        // 必须按网关要求返回指定的成功标识,比如大部分网关要求输出success
        return 'success';
    }else{
        // 处理支付失败逻辑
        return 'success'; // 即使支付失败也要返回成功标识,避免网关重复回调
    }
}

// 新增同步跳转的处理方法
public function payment_return(Request $request, $order_id){
    // 这里可以查询订单当前状态,给用户展示支付结果即可,不要在这里做订单状态更新
    $order = \App\Models\Order::find($order_id);
    return view('payment.result', compact('order'));
}

3. 网关后台配置调整

把网关后台的异步通知地址填/api/gateway/confirm_payment/订单id的格式,同步跳转地址填/gateway/payment_return/订单id的格式即可。

注意事项

  • 异步通知是网关服务器直接发起请求,和用户浏览器无关,所以不要在该逻辑里使用session、auth、cookie等依赖用户会话的功能
  • 必须按网关文档要求返回指定的回调成功响应,否则网关会重复发起多次回调
  • 同步跳转的参数仅做参考,订单状态必须以异步通知的结果为准

内容的提问来源于stack exchange,提问作者Mahlika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 02:27:04