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

如何通过Ajax实现Stripe支付无页面跳转并展示结果

解决无跳转Ajax Stripe支付问题

让我帮你排查下问题,你当前的代码里有几个关键原因导致了页面跳转和Ajax错误,咱们一步步来修复:

核心问题分析

  1. 同时触发了表单提交和Ajax请求:你在Stripe的token回调里先执行了表单提交,这会直接触发页面跳转,导致后续的Ajax请求被中断,自然会抛出错误。
  2. 前后端参数不匹配:Ajax请求传的参数是tokenid,但后端代码里拿的是$request->stripeToken,根本获取不到正确的支付令牌。
  3. Ajax请求缺少CSRF验证:Laravel默认会拦截不带CSRF令牌的POST请求,这也是触发错误的潜在原因。

步骤1:修改前端Stripe代码(核心修复)

移除表单提交逻辑,修正参数名并带上CSRF令牌,同时处理支付结果的提示:

// 可选:全局设置CSRF令牌,避免每个Ajax都手动加
$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

let stripe = StripeCheckout.configure({
    key: "{{config('services.stripe.key')}}",
    image: "",
    locale: "auto",
    token: (token) => {
        // 移除表单提交代码,只保留Ajax请求
        $.ajax({
            type: "POST",
            url: '{{route('registration.charge')}}', // 注意路由名要和后端配置一致,你之前写的conferences.charge是笔误
            data: {
                stripeToken: token.id, // 参数名和后端的$request->stripeToken对应
                email: token.email
            },
            success: function(data) {
                if (data.success) {
                    // 这里替换成你想要的成功提示,比如插入页面元素或弹窗
                    alert('支付成功!');
                    // 示例:隐藏支付按钮,显示成功信息
                    $('#payment').hide();
                    $('#payment-status').html('<div class="alert alert-success">支付已完成</div>');
                } else {
                    alert('支付失败:' + data.message);
                }
                // 恢复支付按钮可用状态
                $('#payment').prop('disabled', false);
            },
            error: function(xhr) {
                let errorMsg = xhr.responseJSON?.message || '支付过程中出现未知错误';
                alert('支付出错:' + errorMsg);
                console.log(xhr);
                // 恢复支付按钮可用状态
                $('#payment').prop('disabled', false);
            }
        });
    }
});

document.getElementById('payment').addEventListener('click', function(e){
    // 点击后禁用按钮,防止重复提交
    this.disabled = true;
    stripe.open({
        name: 'test',
        description: 'test',
        amount: '{{session('total')}}'
    });
    e.preventDefault();
});

步骤2:优化后端Charge方法(统一返回格式)

你的后端代码已经处理了异常,但可以优化返回格式,让前端更易判断状态:

public function charge(Request $request) {
    Stripe::setApiKey(config('services.stripe.secret'));
    $source = $request->stripeToken;
    $selectedRtypes = Session::get('selectedRtypes');
    $amount = (collect($selectedRtypes)->first()['total']) * 100;

    try{
        Charge::create([
            'currency' => 'eur',
            'description' => 'Example charge',
            'amount' => $amount,
            'source' => $source,
        ]);
        return response()->json([
            'success' => true,
            'message' => '支付成功'
        ], 200);
    } catch(\Exception $e){
        return response()->json([
            'success' => false,
            'message' => $e->getMessage()
        ], 422);
    }
}

步骤3:确保页面存在CSRF元标签

在页面的<head>里添加CSRF元标签,配合前面的全局Ajax设置使用:

<meta name="csrf-token" content="{{ csrf_token() }}">

这样修改后,用户点击支付完成Stripe验证后,会通过Ajax提交请求,页面不会跳转,同时能根据后端返回的结果显示对应的成功/失败提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:12:47