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

Next.js 13集成Stripe收款:如何获取/计算多币种交易手续费?

获取Stripe交易手续费的解决方案

核心原因

前端通过stripe.confirmCardPayment返回的结果不包含手续费信息——手续费属于后端敏感数据,必须通过Stripe后端API或Webhook获取。

方案一:支付成功后后端查询Payment Intent详情

1. 新增后端接口获取Payment Intent详情

在app/api/get-payment-intent/route.ts创建新接口:

import { NextResponse, NextRequest } from "next/server";
import Stripe from "stripe";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  typescript: true,
  apiVersion: "2023-08-16",
});

export async function POST(req: NextRequest) {
  const { paymentIntentId } = await req.json();
  try {
    const paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId);
    // 提取手续费(转换为实际币种单位,Stripe返回的是最小单位如分)
    const fee = paymentIntent.charges.data[0]?.fee;
    return NextResponse.json({
      fee: fee ? fee / 100 : null,
      currency: paymentIntent.currency,
      amountReceived: paymentIntent.amount_received / 100
    }, { status: 200 });
  } catch (error: any) {
    return NextResponse.json({ error: error.message }, { status: 400 });
  }
}

2. 修改前端支付成功逻辑

在onSubmit函数的成功分支中调用新接口,获取并存储手续费:

// ...原有代码
} else {
  // 获取Payment Intent ID
  const paymentIntentId = result.paymentIntent.id;
  // 调用后端接口获取手续费
  const feeRes = await axios.post("/api/get-payment-intent", {
    paymentIntentId: paymentIntentId
  });
  const { fee, currency } = feeRes.data;
  
  const data = {
    campaign,
    transactionRecord: result,
    fee: fee,
    feeCurrency: currency
  };
  
  PaymentService.saveTransactionRecord(data).then((res) => {
    console.log("res: ", res);
    setIsSubmitting(false);
    setPaymentStatus(`Payment succeeded! Fee: ${fee} ${currency}`);
    setShowAlert(true);
    setAlertMessage(`Payment succeeded! Fee: ${fee} ${currency}`);
    setAlertType("success");
    setTimeout(() => {
      router.push("/dashboard/campaigns");
    }, 1000);
  });
}
// ...

方案二:使用Stripe Webhook(推荐)

Webhook是Stripe主动通知后端交易状态变更的方式,可靠性更高,避免前端请求延迟或失败:

1. 创建Webhook接口

在app/api/stripe-webhook/route.ts新增:

import { NextResponse, NextRequest } from "next/server";
import Stripe from "stripe";
import { buffer } from "node:stream/consumers";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  typescript: true,
  apiVersion: "2023-08-16",
});

export async function POST(req: NextRequest) {
  const buf = await buffer(req.body);
  const sig = req.headers.get("stripe-signature")!;
  const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET!;

  let event;

  try {
    event = stripe.webhooks.constructEvent(buf, sig, webhookSecret);
  } catch (err: any) {
    return NextResponse.json({ error: `Webhook Error: ${err.message}` }, { status: 400 });
  }

  // 监听支付成功事件
  if (event.type === "payment_intent.succeeded") {
    const paymentIntent = event.data.object as Stripe.PaymentIntent;
    const fee = paymentIntent.charges.data[0]?.fee;
    if (fee) {
      // 将手续费存储到你的数据库,关联对应交易记录
      await PaymentService.updateTransactionFee({
        paymentIntentId: paymentIntent.id,
        fee: fee / 100,
        currency: paymentIntent.currency
      });
    }
  }

  return NextResponse.json({ received: true }, { status: 200 });
}

2. 配置Stripe后台

在Stripe后台Webhooks设置中,添加端点https://你的域名/api/stripe-webhook,订阅payment_intent.succeeded事件,将生成的Webhook Secret添加到环境变量STRIPE_WEBHOOK_SECRET。

关键说明

  • Stripe返回的手续费为最小货币单位(如欧元分、美元分),需除以100转换为实际金额。
  • 手续费由Stripe根据你的账户费率、交易币种、支付方式自动计算,可通过Stripe后台的费用工具估算。
  • 多币种交易的手续费会以对应交易币种返回,无需额外转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 06:05:36