Stripe Checkout Session返回invoice为null问题求助
解决Stripe Checkout Session中invoice字段为null的问题
核心原因
你使用的是mode: 'payment'即时支付模式,这种模式下只有当支付成功完成后,Stripe才会生成对应发票并关联到Checkout Session上。创建会话时还未发生支付,所以session.invoice自然是null;就算跳转到成功页面,如果用户还没完成支付比如提前刷新页面,发票也不会生成。
正确的两种获取方式
1. 通过Stripe Webhook监听支付完成事件推荐
这是最可靠的方式,Webhook是Stripe主动通知你支付完成的信号,此时发票已经生成完毕。
创建Webhook端点,监听checkout.session.completed事件:
// 示例Webhook处理代码 app.post('/stripe-webhook', async (req, res) => { const sig = req.headers['stripe-signature']; let event; try { event = stripe.webhooks.constructEvent( req.rawBody, sig, process.env.STRIPE_WEBHOOK_SECRET ); } catch (err) { return res.status(400).send(`Webhook Error: ${err.message}`); } // 处理支付完成事件 if (event.type === 'checkout.session.completed') { const session = event.data.object; // 此时session.invoice已存在,直接获取ID const invoiceId = session.invoice; if (invoiceId) { // 获取发票PDF链接 const invoice = await stripe.invoices.retrieve(invoiceId); const invoicePdfUrl = invoice.invoice_pdf; // 可将PDF链接存入数据库或发送给用户 console.log('发票PDF链接:', invoicePdfUrl); } } res.json({ received: true }); });
2. 在支付成功页面验证支付状态后获取
如果必须在前端成功页面获取,需先检查会话的payment_status是否为paid,再尝试获取发票:
const successPage = async(ctx:any)=>{ try{ // 获取会话并展开invoice字段 const session = await stripe.checkout.sessions.retrieve(retrievedSession,{ expand: ["invoice"] }); // 先确认支付已完成 if(session.payment_status === 'paid' && session.invoice){ const invoicePdf = session.invoice.invoice_pdf; console.log('发票PDF链接:', invoicePdf); // 渲染页面时传递有效PDF链接 ctx.render('./OBV/checkout/success.ejs',{ Voyant: true, invoiceUrl: invoicePdf }); } else { // 支付未完成,提示用户等待或重新操作 ctx.render('./OBV/checkout/success.ejs',{ Voyant: true, invoiceUrl: '支付未完成,请稍后重试' }); } console.log('success page reached !'); }catch(err) { ctx.response.status = 200; ctx.response.body = { success: false, msg: err.toString() } }finally{ await client.end(); } };
额外注意事项
- 确保你的Stripe SDK是最新版本,旧版本可能存在字段返回逻辑差异。
invoice_creation.enabled: true的配置是正确的,该参数确实会在支付成功后自动生成发票。- 不要在创建会话后立刻尝试获取发票,此时支付未发生,不可能生成发票ID。
内容的提问来源于stack exchange,提问作者Fefe
相关产品推荐
相关产品推荐

