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

如何实现Stripe Connect多商家结账并正确分账至对应关联账户

多商家购物车的Stripe Connect实现方案

要实现跨商家商品的购物车支付,你不能直接在单个Checkout Session的payment_intent_data.transfer_data里指定多个目标账户(Stripe限制单个Payment Intent只能关联一笔转账)。正确的做法是先将全款收至平台账户,支付完成后通过Webhook触发分账,向不同商家的关联账户发起转账,同时利用transfer_group关联所有转账与原支付,避免丢失资金来源信息。

步骤1:修改Checkout Session创建逻辑

移除原代码中payment_intent_data.transfer_data的配置,转而在metadata中记录每个商家的分账明细(关联账户ID、应得金额、对应商品信息),同时指定transfer_group(用订单ID或Checkout Session ID即可),方便后续关联转账与原支付。

export const checkoutSessionMultiMerchant = functions.https.onCall(async (data, context) => {
  // 假设data中包含:
  // line_items: 购物车商品列表
  // merchantSplits: 分账明细数组,格式如[{connectId: 'acct_xxx', amount: 1000, itemIds: ['item_1', 'item_2']}]
  const orderId = `order_${Date.now()}`; // 生成唯一订单ID

  const session = await stripe.checkout.sessions.create({
    line_items: data.line_items,
    mode: "payment",
    success_url: "***",
    cancel_url: "***",
    payment_intent_data: {
      // 不指定transfer_data,全款先进入平台账户
      metadata: {
        orderId,
        // 将分账明细转为JSON字符串存储(Stripe metadata仅支持字符串)
        merchantSplits: JSON.stringify(data.merchantSplits),
      },
      // 指定transfer_group,后续转账时关联此值
      transfer_group: orderId,
    },
  });

  return session;
});

步骤2:配置Stripe Webhook处理分账

监听Stripe的checkout.session.completed事件,当支付成功后,从事件中提取分账明细,向每个商家的关联账户发起转账。同时在转账的metadata中记录对应商品ID,解决你提到的“资金对应商品来源丢失”问题。

export const stripeWebhook = functions.https.onRequest(async (req, res) => {
  const sig = req.headers["stripe-signature"];
  const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;

  let event;
  try {
    event = stripe.webhooks.constructEvent(
      req.rawBody,
      sig,
      webhookSecret
    );
  } catch (err) {
    res.status(400).send(`Webhook Error: ${err.message}`);
    return;
  }

  // 处理支付完成事件
  if (event.type === "checkout.session.completed") {
    const session = event.data.object;
    const paymentIntentId = session.payment_intent;
    const merchantSplits = JSON.parse(session.metadata.merchantSplits);
    const transferGroup = session.payment_intent_data.transfer_group;

    // 遍历分账明细,创建转账
    for (const split of merchantSplits) {
      await stripe.transfers.create({
        amount: split.amount, // 单位:分(如1000=10美元)
        currency: "usd", // 根据你的业务调整币种
        destination: split.connectId,
        transfer_group: transferGroup, // 关联到原支付的transfer_group
        metadata: {
          orderId: session.metadata.orderId,
          itemIds: split.itemIds.join(","), // 记录对应商品ID,方便追踪
        },
        source_transaction: paymentIntentId, // 指定资金来源为该支付Intent
      });
    }
  }

  res.json({ received: true });
});

关键注意事项

  • Transfer Group的作用:通过transfer_group将所有转账与原Payment Intent绑定,在Stripe控制台中可通过该分组查看同一订单下的所有转账,解决你之前丢失资金来源的问题。
  • 手续费计算:你可以选择两种方式收取平台手续费:
    1. 从每个商家的应得金额中扣除后再转账(如商家应得1000分,扣100分手续费,转账900分)
    2. 先将全款收至平台,转账时只转商家应得部分,平台留存剩余金额作为手续费
  • Webhook签名验证:必须配置Stripe Webhook Secret并验证签名,避免恶意请求。
  • 错误处理:建议在转账逻辑中添加重试机制(如遇到网络错误时重试),并记录转账状态到Firebase数据库,方便后续对账与异常处理。

为什么之前的方案不可行

  • payment_intent_data.transfer_data仅支持单个目标账户,无法设置数组;
  • 直接使用Transfer Groups而不通过Webhook触发,会错过支付成功的时机,且无法关联商品信息;
  • Destination Charges模式需要为每个商家单独创建Charge,无法适配同一购物车的一笔支付场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 11:00:55