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 发送伪造请求,因此至少要做好以下处理:
- 按照支付网关文档验证签名、Token 或 HMAC。
- 使用
client_ref查询本地已有交易,不能直接创建成功记录。 - 核对金额、币种、商户号等重要数据。
- 做好幂等处理,避免网关重复回调造成重复入账。
- 记录原始回调和处理结果,但不要在日志中保存银行卡号、密钥等敏感信息。
- 处理成功后,返回网关要求的 HTTP 状态码或响应内容。
路由可以只定义在 routes/api.php 中,回调地址使用 POST https://myApp.com/api/qp。配置后,通过 php artisan route:list 确认路由已经注册,再发送真实的 POST 请求进行测试。
备注:内容仅供参考。
