You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中如何通过新Ajax将支付结果传递至控制器

没问题,完全可以通过新增一个独立的Ajax请求来实现这个需求!既然原控制器的try块动不了,那我们就把支付结果的处理逻辑完全剥离到新的控制器方法里,再在Midtrans的回调中发起请求传递数据。下面是具体的实现步骤:

1. 创建新的控制器方法接收支付结果

首先在你的控制器(比如沿用原有的订单控制器,或者新建专门的支付处理控制器)里新增一个方法,用来接收Midtrans返回的支付结果并更新数据库:

use Illuminate\Http\Request;

public function updatePaymentStatus(Request $request)
{
    // 验证必要参数,确保订单ID和支付结果存在
    $request->validate([
        'order_id' => 'required|integer',
        'payment_result' => 'required|array'
    ]);

    try {
        // 根据订单ID找到对应的订单记录
        $order = \App\Models\Order::findOrFail($request->order_id);
        
        // 根据Midtrans返回的状态码更新订单状态(状态码请参考Midtrans官方文档调整)
        $statusCode = $request->payment_result['status_code'];
        switch ($statusCode) {
            case '200':
                $order->status = 'paid'; // 支付成功
                break;
            case '201':
                $order->status = 'pending'; // 支付待处理
                break;
            default:
                $order->status = 'failed'; // 支付失败
        }
        
        // 可以额外存储支付结果的完整信息,方便后续排查
        $order->payment_response = json_encode($request->payment_result);
        $order->save();

        return response()->json(['message' => '支付状态更新成功'], 200);
    } catch (\Exception $e) {
        return response()->json(['message' => '更新失败:' . $e->getMessage()], 500);
    }
}
2. 添加对应的路由

在routes/web.php中新增一条POST路由,指向刚才创建的控制器方法:

Route::post('/update-payment-status', [YourController::class, 'updatePaymentStatus'])->name('payment.update');

(记得把YourController::class替换成你实际的控制器类名)

3. 修改前端JavaScript的回调逻辑

接下来修改原有的JS代码,在Midtrans的onSuccess、onPending、onError回调中,新增一个Ajax请求把支付结果和订单ID发送到新控制器。注意要让订单ID变量能被回调函数访问到:

<script type="text/javascript">
$('.pay-button').click(function (event) {
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });
    event.preventDefault();
    var prdfoId = $(this).data('id'); // 把订单ID变量放在外层,让回调能访问

    $.ajax({
        url: '{{url("orderspayonline")}}/'+encodeURI(prdfoId),
        type: "POST",
        cache: false,
        success: function(data) {
            var resultType = document.getElementById('result-type');
            var resultData = document.getElementById('result-data');
            
            function changeResult(type,data){
                $("#result-type").val(type);
                $("#result-data").val(JSON.stringify(data));
            }

            // 封装发送支付结果的函数,避免重复写Ajax代码
            function sendPaymentResult(result) {
                $.ajax({
                    url: '{{url("update-payment-status")}}',
                    type: "POST",
                    cache: false,
                    data: {
                        order_id: prdfoId,
                        payment_result: result
                    },
                    success: function(response) {
                        console.log('支付状态已更新:', response);
                    },
                    error: function(xhr) {
                        console.error('更新支付状态失败:', xhr.responseText);
                    }
                });
            }

            snap.pay(data, {
                onSuccess: function(result){
                    changeResult('success', result);
                    console.log(result.status_message);
                    console.log(result);
                    sendPaymentResult(result); // 发送成功结果到控制器
                    $("#payment-form").submit();
                },
                onPending: function(result){
                    changeResult('pending', result);
                    console.log(result.status_message);
                    sendPaymentResult(result); // 发送待处理结果到控制器
                    $("#payment-form").submit();
                },
                onError: function(result){
                    changeResult('error', result);
                    console.log(result.status_message);
                    sendPaymentResult(result); // 发送失败结果到控制器
                    $("#payment-form").submit();
                }
            });
        }
    });
});
</script>
关键注意事项
  • Midtrans状态码匹配:上面控制器里的状态码(200、201)是示例,你需要根据Midtrans官方文档里的实际返回状态码来调整判断逻辑。
  • CSRF保护:已经通过$.ajaxSetup全局设置了CSRF头,确保POST请求不会出现419错误。
  • 订单ID传递:把点击事件中获取的prdfoId传递给新Ajax,让控制器能精准定位到要更新的订单。
  • 错误调试:新Ajax里添加了error回调,方便你排查更新失败的具体原因。

这样就能在不修改原控制器try块的前提下,完美实现支付结果的数据库更新啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:39:11