Laravel5.6中如何接收Payone支付网关的POST回调数据?
解决Laravel 5.6中Payone支付网关回调数据无法捕获的问题
从你提供的服务器返回内容来看,核心问题是Laravel的CSRF验证拦截了Payone的POST请求,返回的"PAGE EXPIRED"页面就是CSRF验证失败的典型表现。因为你的回调路由在web.php中,而Laravel的web路由组默认启用了CSRF保护,Payone作为第三方服务无法提供Laravel所需的CSRF令牌,导致请求被直接拦截。
下面是分步解决方案:
1. 排除回调路由的CSRF验证
修改app/Http/Middleware/VerifyCsrfToken.php文件,在$except数组中添加你的回调URL,让Laravel不对该路由进行CSRF校验:
<?php namespace App\Http\Middleware; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware; class VerifyCsrfToken extends Middleware { /** * The URIs that should be excluded from CSRF verification. * * @var array<int, string> */ protected $except = [ '/payment/response', // 添加这一行 ]; }
2. 优化请求数据获取方式(推荐)
你当前使用原生$_POST获取数据,更符合Laravel规范的方式是使用框架的Request对象,它能自动处理请求数据的安全过滤:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class PaymentController extends Controller { public function response(Request $request) { $validKey = hash("md5", env('KEY')); // 验证Payone的密钥 if ($request->input('key') === $validKey) { // 必须输出"TSOK"告知Payone回调已接收 echo "TSOK"; // 处理不同的交易动作 switch ($request->input('txaction')) { case 'appointed': // 交易初始化成功,可通过reference字段关联本地订单 \Log::info('Payone transaction appointed', $request->all()); break; case 'paid': // 交易支付完成,更新本地订单状态 \Log::info('Payone transaction paid', $request->all()); break; } } else { // 密钥验证失败,记录日志并返回403 \Log::warning('Invalid Payone callback key', $request->all()); abort(403, 'Invalid verification key'); } } }
3. 验证回调的可达性
确保你的回调URLhttps://demo.project.de/payment/response是公网可访问的:
- 用Postman等工具模拟POST请求,携带Payone格式的参数,测试是否能正常进入控制器方法
- 检查服务器防火墙、Nginx/Apache配置,确保没有拦截Payone的IP或请求
额外注意事项
- 确认
env('KEY')的配置值和Payone后台设置的密钥完全一致,否则密钥验证会失败 - 生产环境不要使用
dd(),它会中断响应,导致Payone重复发送回调请求,建议用Log::info()记录数据 - 查看
storage/logs/laravel.log日志文件,若仍有问题,可从中获取更详细的错误信息
内容的提问来源于stack exchange,提问作者Sarath TS
相关产品推荐
相关产品推荐

