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

Spring Boot集成Stripe支付报错:需改用Payment Intents API

解决Stripe Payment元素支付报错及Token创建问题

问题原因分析

  1. Charge API报错:后端使用的Charge API属于Stripe旧版支付流程,而payment元素生成的是PaymentMethod对象,无法通过Charge API的source参数传递,Stripe明确要求此类场景必须使用Payment Intents API。
  2. createToken失败:stripe.createToken()仅适配旧版card元素,新版payment元素不支持该方法,调用后必然进入catch块。

具体修复步骤

一、前端代码修改

保留payment元素创建逻辑,调整表单提交流程,直接用Stripe的confirmPayment方法完成支付确认(无需手动传递PaymentMethod到后端):

<form id="payment-form" method="post">
   <input id="api-key" type="hidden" value="${stripePublicKey}">
   <div class="form-group mb-3">
       <div class="w-100" id="card-element">
           <!-- A Stripe Element will be inserted here. -->
       </div>
       <div id="card-errors" class="text-danger mt-2"></div>
   </div>
   <button class="btn w-100 btn-success mt-4" type="submit" id="submitButton">Pay $230</button>
</form>
<script>
    const stripe = Stripe($('#api-key').val());
    const elements = stripe.elements({clientSecret:'${client_secret}'});
    const paymentElement = elements.create('payment');
    paymentElement.mount('#card-element');

    paymentElement.addEventListener('change', function (event) {
        $('#card-errors').text(event.error ? event.error.message : '');
    });

    $('#payment-form').on('submit', async function (e) {
        e.preventDefault();
        $('#submitButton').prop('disabled', true);

        const { error } = await stripe.confirmPayment({
            elements: elements,
            confirmParams: {
                return_url: 'https://your-domain.com/payment-success', // 替换为你的支付成功跳转地址
                receipt_email: '${customer.email}'
            },
        });

        if (error) {
            $('#card-errors').text(error.message);
            $('#submitButton').prop('disabled', false);
        } else {
            // 支付成功后会自动跳转到return_url,无需额外处理
        }
    });
</script>

二、后端代码修改

移除Charge相关逻辑,改用Payment Intents API处理支付。注意:前端用到的client_secret必须来自后端提前创建的Payment Intent。

1. 调整支付接口

@PostMapping("/create-charge")
public @ResponseBody StripeResponse createCharge(String email) {
    try {
        Stripe.apiKey = API_SECRET_KEY;
        // 创建Payment Intent并自动确认支付(根据业务需求调整confirm参数)
        Map<String, Object> params = new HashMap<>();
        params.put("amount", 23000); // $230,单位为分
        params.put("currency", "usd");
        params.put("receipt_email", email);
        params.put("payment_method_types", Arrays.asList("card"));
        params.put("confirm", true);

        PaymentIntent paymentIntent = PaymentIntent.create(params);
        return new StripeResponse(true, "支付成功,Intent ID: " + paymentIntent.getId());
    } catch (Exception e) {
        e.printStackTrace();
        return new StripeResponse(false, "支付失败: " + e.getMessage());
    }
}

2. 替换原createCharge方法

@Override
public String createCharge(String email, int amount) {
    try {
        Stripe.apiKey = API_SECRET_KEY;
        Map<String, Object> params = new HashMap<>();
        params.put("amount", amount);
        params.put("currency", "usd");
        params.put("receipt_email", email);
        params.put("payment_method_types", Arrays.asList("card"));
        PaymentIntent intent = PaymentIntent.create(params);
        return intent.getId();
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

关键注意事项

  • 前端的client_secret必须由后端提前创建Payment Intent生成,不能凭空赋值。
  • 建议开启Stripe Webhook监听payment_intent.succeeded等事件,避免前端跳转异常导致支付状态不一致。
  • 若需自定义payment元素布局,可通过style参数配置,无需退回旧版card元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 11:02:07