PAYATHON 2026

Laravel CallBack URL 无法找到,应如何正确配置?

支付老李

结论

如果路由写在 routes/api.php 中,并且项目已加载 API 路由,回调地址通常是:

https://myApp.com/api/qp

地址“无法访问”时,最常见的原因并不是 URL 有误,而是该路由只接受 POST 请求。在浏览器地址栏中直接打开 URL,浏览器发送的是 GET 请求,因此可能收到 404 或 405 Method Not Allowed。

不需要在 api.php 和 web.php 中重复定义同一个回调。支付网关回调一般放在 routes/api.php,由网关通过 POST 请求调用。

配置路由

可以使用控制器类和方法数组来定义路由:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\MainAPIController;

Route::post('/qp', [MainAPIController::class, 'qp'])
    ->name('payment.qp.callback');

将这段路由放在:

routes/api.php

该文件中的路由默认带有 /api 前缀,所以完整地址通常是:

https://myApp.com/api/qp

如果路由放在 routes/web.php 中,地址通常是:

https://myApp.com/qp

不过,web.php 中的 POST 路由一般受 CSRF 中间件保护。第三方支付平台无法提供 Laravel 的 CSRF Token,因此这里不适合直接作为外部回调入口。

确认路由已经注册

在项目目录中执行:

php artisan route:list

查找 qp。正常情况下,可以看到类似内容:

POST   api/qp   payment.qp.callback

如果列表中没有这条路由,先清理路由和应用缓存:

php artisan optimize:clear

然后再次执行:

php artisan route:list

部分较新的 Laravel 项目可能没有默认启用 routes/api.php。遇到这种情况,需要检查 bootstrap/app.php 是否配置了 API 路由,例如:

->withRouting(
    web: __DIR__.'/../routes/web.php',
    api: __DIR__.'/../routes/api.php',
    commands: __DIR__.'/../routes/console.php',
    health: '/up',
)

具体写法与 Laravel 版本有关,应以当前项目的 bootstrap/app.php 配置和路由列表为准。

编写回调方法

Laravel 不需要手动读取 php://input,可以直接通过 Request 获取 JSON 或表单数据:

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class MainAPIController extends Controller
{
    public function qp(Request $request): JsonResponse
    {
        $data = $request->validate([
            'user_id'      => ['required'],
            'amount'       => ['required', 'numeric'],
            'funds_source' => ['nullable', 'string'],
            'status'       => ['required', 'string'],
            'client_ref'   => ['required', 'string'],
            'trans_date'   => ['nullable'],
            'naration'     => ['nullable', 'string'],
            'charges'      => ['nullable', 'numeric'],
        ]);

        $user = $data['user_id'];
        $amount = $data['amount'];
        $transactionSource = $data['funds_source'] ?? null;
        $transactionStatus = $data['status'];
        $reference = $data['client_ref'];
        $transactionDate = $data['trans_date'] ?? null;
        $narration = $data['naration'] ?? null;
        $charges = $data['charges'] ?? null;

        if ($transactionStatus === 'SUCCESS') {
            // 根据 reference 更新支付记录
        } elseif ($transactionStatus === 'FAILED') {
            // 将对应支付记录标记为失败
        }

        return response()->json([
            'received' => true,
        ], 200);
    }
}

字段名 naration 可能是支付平台使用的拼写。如果对方实际发送的是 narration,代码也要随之修改。最终应以支付网关文档和真实的回调数据为准。

测试回调地址

这是一个 POST 路由,不能只在浏览器地址栏中测试。可以使用 curl 发送请求:

curl -i -X POST 'https://myApp.com/api/qp' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "user_id": 123,
    "amount": 1000,
    "funds_source": "card",
    "status": "SUCCESS",
    "client_ref": "PAY-123456",
    "trans_date": "2026-09-01 12:00:00",
    "naration": "Payment",
    "charges": 10
  }'

如果路由存在,但通过 GET 请求访问,返回 405 是正常的。如果 POST 请求仍然返回 404,需要检查:

  • 域名是否指向 Laravel 项目的 public 目录。
  • Web 服务器的 URL Rewrite 是否配置正确。
  • routes/api.php 是否已经加载。
  • 线上环境是否仍在使用旧的路由缓存。
  • 回调 URL 是否带有正确的 /api 前缀。
  • 网关是否要求使用公网可访问的 HTTPS 地址。
  • 防火墙或反向代理是否拦截了请求。

支付回调的安全事项

回调接口不能只根据请求中的 status 更新订单。任何人都可能向公开 URL 发送伪造请求,因此至少要做好以下处理:

  1. 按照支付网关文档验证签名、Token 或 HMAC。
  2. 使用 client_ref 查询本地已有交易,不能直接创建成功记录。
  3. 核对金额、币种、商户号等重要数据。
  4. 做好幂等处理,避免网关重复回调造成重复入账。
  5. 记录原始回调和处理结果,但不要在日志中保存银行卡号、密钥等敏感信息。
  6. 处理成功后,返回网关要求的 HTTP 状态码或响应内容。

路由可以只定义在 routes/api.php 中,回调地址使用 POST https://myApp.com/api/qp。配置后,通过 php artisan route:list 确认路由已经注册,再发送真实的 POST 请求进行测试。

备注:内容仅供参考。