STRIPE Checkout 会话 Invoice:session.invoice 在响应对象中为 null,而我在 stripe.checkout.sessions.create 中启用了 invoice_creation

STRIPE Checkout session Invoice : session.invoice is null in the response object whereas i enabled invoice_creation in stripe.checkout.sessions.create

提问人:Fefe 提问时间:10/2/2023 最后编辑:Fefe 更新时间:10/6/2023 访问量:131

问:

结账会话响应的发票 ID 为 null,即使我在 Request 对象中启用了 invoice_creation也是如此。它以前有效,我能够得到这个id,但现在我得到一个空值。我需要此发票 ID 以允许客户以 PDF 格式下载其发票。

const session = await stripe.checkout.sessions.create({
            payment_method_types: ['card'],
            line_items: lineItems,
            mode: 'payment',
            success_url: 'http://localhost:80/OBV/success',
            cancel_url: 'http://localhost:80/OBV/cancel',
            invoice_creation: {
                enabled: true,
                
            },

          });

          const retrievedSession = session.id;
          console.log('retrieved session : ' + retrievedSession);
          const sessionInvoice = session.invoice;
          console.log('session Invoice : ' + sessionInvoice);
          

这是我在控制台中得到的响应:

在此处输入图像描述

那么我怎样才能从这个结帐会话中获取这个发票ID?

[编辑 1] : 回应@Tarzan评论:

现在,在加载成功页面后,我在Checkout会话完成后放置检索到的请求:

const successPage = async(ctx:any)=>{

    try{
        
        const session = await stripe.checkout.sessions.retrieve(
            retrievedSession
          );
          console.log('session id : ' + session.id);
          
           const sessionInvoice = session.invoice;
          console.log('session Invoice : '+ sessionInvoice);

          const invoice = await stripe.invoices.retrieve(
            sessionInvoice
          );

          const invoicePdf = invoice.invoice_pdf;
          console.log('invoice pdf url : '+ invoicePdf);
        
         /* ctx.cookies.set('invoice_pdf', invoicePdf);*/

        ctx.render('./OBV/checkout/success.ejs',{Voyant: true, invoiceUrl: 'Empty'});
        console.log('success page reached !');
    }catch(err) {
        ctx.response.status = 200;
            ctx.response.body = {
                success: false,
                msg: err.toString()
            }
    }finally{
        
        await client.end();
    }
    

我得到了 session.invoice 的相同 null 值响应,并且此消息显示在我的屏幕上:

在此处输入图像描述

[编辑 2]

const successPage = async(ctx:any)=>{

    try{
        
         const session = await stripe.checkout.sessions.retrieve(retrievedSession,{expand: ["invoice"]});

         console.log('session invoice : ' + session.invoice);

        ctx.render('./OBV/checkout/success.ejs',{Voyant: true, invoiceUrl: 'Empty'});
        
        console.log('success page reached !');
    }catch(err) {
        ctx.response.status = 200;
            ctx.response.body = {
                success: false,
                msg: err.toString()
            }
    }finally{
        
        await client.end();
    }
    
};

原木:

控制台日志

retrievedSession 是会话的 ID

节点 .js 条带支付 结账 Deno 发票

评论

0赞 Tarzan 10/2/2023
你是在前端还是后端运行它?
0赞 Fefe 10/2/2023
从后端运行它

答:

0赞 Tarzan 10/2/2023 #1

在结账会话完成之前,不会创建发票。您似乎正在尝试在创建时访问发票字段。这是预期的结果。

编辑: 我认为你正面临某种竞争条件。让我解释一下:

通常,发票创建是异步进行的,在结账会话完全完成(发票已创建并分配给结账会话)之前,您的客户将被重定向到成功页面。快速解决方法是设置一个侦听 .出于以下几个原因,这是一个非常好的做法checkout.session.completed

  1. 这是完成结账订单的最佳方式,如此处所述
  2. 通过这样做,您将能够等到将 发送到 Webhook 端点,然后再将客户重定向到您的成功页面,届时应填充发票。checkout.session.completed

另外,将 作为全局变量是一个糟糕的主意,出于并发原因,您根本不应该使用它。相反,您应该改用传递到成功页面的结账会话 ID。retrievedSession

评论

0赞 Fefe 10/2/2023
在我分享的代码的第一部分中,其中有 const session,我们可以看到 const retrievedsession 值是从对象响应中获取的,并且是 session.id 因此 session.invoice 不应为 null。在此顺序中,结帐会话已完成,如果它没有完成,我应该无法拥有 session.id 值......我错了吗?
0赞 Tarzan 10/3/2023
创建结账会话时,起初,该会话没有附加任何发票。结账会话在创建时具有一个 ID。只有当结账会话完成(客户已成功输入其付款方式信息)时,才会创建发票。
0赞 Fefe 10/3/2023
现在我移动了一些行:在 sucesspage 渲染 ( ctx.render ) 后触发检索到的请求,这意味着结帐会话已完成,但我得到相同的结果......它以前运行良好,我可以获取发票 ID 和发票 pdf 的链接,我不知道为什么它突然停止工作......但是,我仍然在我的仪表板中创建带有 pdf 链接、发票 ID 等的发票......
0赞 Tarzan 10/3/2023
但是,如果它没有通过,你会得到什么?retrievedSessionctx
0赞 Tarzan 10/3/2023
顺便说一句,您不必进行 2 次 API 调用。你可以这样做const session = await stripe.checkout.sessions.retrieve(id,{expand: ["invoice"]});
0赞 Fefe 10/6/2023 #2

为了完成@Tarzan答案,以便检索一些您想要返回的有用信息,例如您需要设置 Webhook 的发票链接,当您转到“https://dashboard.stripe.com/test/webhooks”时,您的 stripe dashborad 中有一个文档,它们会向您解释如何设置端点以及他们创建 webhook 的方式。我不知道为什么,但我以前不需要 webhook,而且它正在工作,但现在我认为这是获取一些未显示在默认响应流中的信息的唯一方法。如果您想了解有关我将他们的节点 js 解释转换为 deno oak 的更多详细信息,请告诉我