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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:18:21