如何在Stripe Checkout中实现多收款方支付分账功能
针对Stripe多卖家分账的解决方案
首先明确:Stripe Checkout的payment_intent_data.transfer_data只能指定一个收款账户,无法在单次结账会话中直接拆分金额给多个卖家。Payment Intent本身是单一支付意向,不支持同时关联多个转账目标,所以你当前的思路没法实现按商品对应卖家分账。
针对Express账户的最佳简便方案:先归集资金到平台,再通过转账分发给卖家
核心逻辑是:先让用户把钱支付到你的平台Stripe账户,待支付成功后,再通过Stripe Transfer API把对应金额分别转到每个卖家的Express账户。具体步骤如下:
1. 修改结账会话创建代码
去掉transfer_data,同时在会话的metadata中存储购物车关键信息(卖家ID、商品价格ID、数量等),方便后续webhook使用:
router.post('/create-checkout-session', async(req, res) => { const {cartItems} = req.body; const cartPriceArray = cartItems.map((item) => { return {price: item.stripePriceId, quantity: 1}; }); const session = await stripe.checkout.sessions.create({ line_items: cartPriceArray, mode: 'payment', success_url: `${process.env.CLIENT_URL}checkout-success`, cancel_url: `${process.env.CLIENT_URL}cart`, // 平台手续费:可选固定金额(application_fee_amount)或百分比(application_fee_percent) payment_intent_data: { application_fee_percent: 5, // 示例:收取5%平台手续费 }, // 存储购物车信息,供webhook分账使用 metadata: { cartItems: JSON.stringify(cartItems.map(item => ({ stripeAccountId: item.stripeAccountId, priceId: item.stripePriceId, quantity: item.quantity, }))), }, }); res.json({url: session.url}); });
2. 配置Webhook监听支付成功事件
用户支付完成后,Stripe会触发checkout.session.completed事件,你需要在webhook中处理这个事件完成分账:
router.post('/webhook', express.raw({type: 'application/json'}), async (req, res) => { const sig = req.headers['stripe-signature']; const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET; let event; try { event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret); } catch (err) { return res.status(400).send(`Webhook Error: ${err.message}`); } if (event.type === 'checkout.session.completed') { const session = event.data.object; const cartItems = JSON.parse(session.metadata.cartItems); const paymentIntentId = session.payment_intent; // 获取支付意图的详细数据 const paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId); const totalAmount = paymentIntent.amount; // 单位为分 const feePercent = paymentIntent.application_fee_percent; const availableAmount = totalAmount * (100 - feePercent) / 100; // 可分发给卖家的总金额 // 按卖家分组,合并同一卖家的所有商品金额 const sellerGroups = {}; for (const item of cartItems) { const price = await stripe.prices.retrieve(item.priceId); const itemTotal = price.unit_amount * item.quantity; if (!sellerGroups[item.stripeAccountId]) { sellerGroups[item.stripeAccountId] = { accountId: item.stripeAccountId, total: 0, }; } sellerGroups[item.stripeAccountId].total += itemTotal; } // 给每个卖家转账 for (const seller of Object.values(sellerGroups)) { // 按商品占总金额的比例分配可提现金额 const sellerShare = Math.round((seller.total / totalAmount) * availableAmount); await stripe.transfers.create({ amount: sellerShare, currency: paymentIntent.currency, destination: seller.accountId, source_transaction: paymentIntentId, // 关联支付意图,避免平台资金占用 }); } } res.json({received: true}); });
关键注意事项
- 必须在Stripe Dashboard中配置Webhook,启用
checkout.session.completed事件,并设置正确的签名密钥。 - 处理转账失败场景:比如卖家账户未完成验证、状态异常等,需添加重试逻辑或错误告警。
- 同一卖家的多个商品要合并转账,避免多次小额转账产生额外手续费。
- 确保你的Stripe账户已开启Connect功能,且所有卖家都是通过你的平台创建的Express账户。
内容的提问来源于stack exchange,提问作者dusk
相关产品推荐
相关产品推荐

