Stripe Basil API:如何将PaymentIntent与发票关联?
Stripe Basil API:Invoice与PaymentIntent/Charge的关联问题
我正在使用最新版Stripe Basil API,发现Invoice对象的payment_intent字段已被移除。此前可直接将PaymentIntent与发票关联,但现在无法建立该连接,尤其是在Webhook中——paymentIntent.created事件未提供任何关联信息(无invoice_id等),Charges的情况也类似。
我的使用场景是扩展订阅功能并在系统中记录交易,此前代码可正常运行:
case "invoice.payment_succeeded": const invoicePaymentSucceeded = event.data.object; const subscriptionId = invoicePaymentSucceeded.subscription; const paymentIntentId = invoicePaymentSucceeded.payment_intent; const chargeId = invoicePaymentSucceeded.charge; if (!subscriptionId || typeof subscriptionId !== "string") { console.error("Missing subscription ID:", invoicePaymentSucceeded); return res.status(400).json({ error: "Invalid subscription ID" }); } if (!paymentIntentId || typeof paymentIntentId !== "string") { console.error("Missing payment intent ID:", invoicePaymentSucceeded); return res.status(400).json({ error: "Invalid payment intent ID" }); } if (!chargeId || typeof chargeId !== "string") { console.error("Missing charge ID:", invoicePaymentSucceeded); // Optional: no early return here, just log to show it's unexpectedly null }
我需要获取payment intent ID以及charge以获取Stripe手续费和应用手续费,目前无法理清关联逻辑。请问如何通过Basil API将PaymentIntent与对应发票关联?
解决方案
1. 从invoice.payment_succeeded事件中获取PaymentIntent
Basil API将原Invoice对象的单个payment_intent字段替换为payment_intents数组,存储所有与该发票关联的PaymentIntent记录。对于成功支付的发票,可从数组中筛选出状态为succeeded的PaymentIntent:
case "invoice.payment_succeeded": const invoicePaymentSucceeded = event.data.object; const subscriptionId = invoicePaymentSucceeded.subscription; // 筛选成功的PaymentIntent const succeededPaymentIntent = invoicePaymentSucceeded.payment_intents.find( pi => pi.status === "succeeded" ); const paymentIntentId = succeededPaymentIntent?.id; if (!subscriptionId || typeof subscriptionId !== "string") { console.error("Missing subscription ID:", invoicePaymentSucceeded); return res.status(400).json({ error: "Invalid subscription ID" }); } if (!paymentIntentId || typeof paymentIntentId !== "string") { console.error("Missing payment intent ID:", invoicePaymentSucceeded); return res.status(400).json({ error: "Invalid payment intent ID" }); }
2. 获取关联的Charge并提取手续费
Charge不再直接挂在Invoice对象上,需通过PaymentIntent关联:
- 调用Stripe API获取PaymentIntent详情,从
charges.data数组中取出对应Charge记录 - Charge对象的
application_fee_amount和fee_details字段包含手续费信息
修改后的代码片段:
// 接上面的代码,获取PaymentIntent后 let chargeId; let stripeFee = 0; let applicationFee = 0; if (paymentIntentId) { // 调用Stripe API获取PaymentIntent详情 const paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId); const charge = paymentIntent.charges.data[0]; if (charge) { chargeId = charge.id; // 提取Stripe手续费和应用手续费 stripeFee = charge.fee_details?.reduce((total, fee) => { return fee.type === "stripe_fee" ? total + fee.amount : total; }, 0); applicationFee = charge.application_fee_amount || 0; } } if (!chargeId || typeof chargeId !== "string") { console.error("Missing charge ID:", invoicePaymentSucceeded); }
3. 从PaymentIntent事件反向关联发票
在payment_intent.succeeded或payment_intent.created事件中,PaymentIntent对象的invoice字段会直接指向关联的发票ID,可用于双向关联:
case "payment_intent.succeeded": const paymentIntent = event.data.object; const invoiceId = paymentIntent.invoice; if (invoiceId) { // 根据invoiceId查询对应的发票或订阅信息 const invoice = await stripe.invoices.retrieve(invoiceId); const subscriptionId = invoice.subscription; }
4. 注意事项
- 确保Stripe客户端初始化时指定Basil对应的API版本(如
2024-06-20) - 若Webhook事件返回字段不全,可通过
expand参数在API调用中扩展关联对象(如stripe.invoices.retrieve(invoiceId, { expand: ['payment_intents'] }))
内容的提问来源于stack exchange,提问作者user9247
相关产品推荐
相关产品推荐

