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

如何在NextJS+CommerceJS+Stripe电商站添加Bancontact支付?

实现Bancontact支付方案及PaymentIntents的作用

一、PaymentIntents是实现Bancontact的正确方式

Bancontact属于异步支付方式,需要用户跳转至银行页面完成授权,后续通过回调通知支付结果,这种场景必须依赖Stripe的Payment Intents API来跟踪支付状态,无法用原代码中直接创建PaymentMethod的即时支付逻辑实现。

二、代码修改及关键步骤

1. 前端切换为Payment Element(推荐)

Payment Element会自动适配展示Bancontact和银行卡选项,无需单独维护不同支付组件,替换原有CardElement:

import { loadStripe } from "@stripe/stripe-js";
import { Elements, PaymentElement, ElementsConsumer } from "@stripe/react-stripe-js";
import { Stripe, StripeElements } from "@stripe/stripe-js/types/stripe-js";
import { useCheckout } from "@/context/checkout";

const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY as string);

export const PaymentSection: React.FC = () => {
  const { token, shippingData, handleCaptureCheckout } = useCheckout();

  // 配置Elements,指定支付方式和订单信息
  const elementsOptions = {
    mode: "payment",
    amount: token?.total.raw || 0,
    currency: "eur", // Bancontact仅支持欧元
    paymentMethodTypes: ["card", "bancontact"],
  };

  const handleSubmit = async (
    event: React.FormEvent<HTMLFormElement>,
    elements: StripeElements | null,
    stripe: Stripe | null
  ) => {
    event.preventDefault();
    if (!stripe || !elements || !token || !shippingData) return;

    // 调用confirmPayment处理支付流程,Bancontact会自动跳转至银行页面
    const { error } = await stripe.confirmPayment({
      elements,
      confirmParams: {
        return_url: `${window.location.origin}/order-confirmation`,
      },
    });

    if (error) {
      console.error("支付失败:", error.message);
      return;
    }

    // 这里需要先从后端获取PaymentIntent的client_secret
    const orderData = {
      line_items: token.line_items,
      customer: {
        firstname: shippingData.customer.firstname,
        lastname: shippingData.customer.lastname,
        email: shippingData.customer.email,
      },
      shipping: {
        name: shippingData.shipping.name,
        street: shippingData.shipping.street,
        town_city: shippingData.shipping.town_city,
        county_state: shippingData.shipping.county_state,
        postal_zip_code: shippingData.shipping.postal_zip_code,
        country: shippingData.shipping.country,
      },
      fulfillment: { shipping_method: "fadfda" },
      payment: {
        gateway: "stripe",
        stripe: {
          client_secret: "从后端接口获取的PaymentIntent client_secret",
        },
      },
    };

    handleCaptureCheckout(token.id, orderData);
  };

  return (
    <section className="w-full h-screen flex justify-center items-center">
      <Elements stripe={stripePromise} options={elementsOptions}>
        <ElementsConsumer>
          {({ elements, stripe }) => (
            <form
              onSubmit={(e) => handleSubmit(e, elements, stripe)}
              className="w-full"
            >
              <PaymentElement />
              <br /> <br />
              <div style={{ display: "flex", justifyContent: "space-between" }}>
                <button type="submit" disabled={!stripe} color="primary">
                  Pay
                </button>
              </div>
            </form>
          )}
        </ElementsConsumer>
      </Elements>
    </section>
  );
};

2. 后端核心逻辑(不可缺少)

Bancontact的异步特性要求后端处理PaymentIntent创建和支付结果回调:

  • 接收前端传来的CommerceJS checkout token,获取订单金额和货币
  • 调用Stripe SDK创建PaymentIntent,参数包含amount、currency: "eur"、payment_method_types: ["bancontact", "card"]
  • 将PaymentIntent的client_secret返回给前端
  • 配置Stripe webhook监听payment_intent.succeeded事件,触发时调用CommerceJS的checkout.capture完成订单

3. 注意事项

  • Bancontact仅支持欧元,需确保订单货币为EUR
  • 必须配置Stripe webhook,否则无法捕获用户跳转后完成的支付
  • 原代码中直接传入payment_method_id的逻辑仅适用于银行卡,Bancontact需要依赖PaymentIntent的client_secret

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 05:17:03