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

Stripe Checkout Session异常:product_data缺失、payment_intent为null

问题

使用stripe@7版本开发,调用接口创建Checkout Session时无报错,但返回结果不符合预期:

  1. product_data未在返回的session中显示
  2. payment_intent字段为null

当前返回结果:

{"status": "success","session": {"id": "cs_test_a1mZ6W9dAO1n7IgpBkvZFJR3Uoe0TTAv3BV9U76b9JVpogcbOyImkaAvU2","object": "checkout.session","after_expiration": null,"allow_promotion_codes": null,"amount_subtotal": 99700,"amount_total": 99700,"automatic_tax": {"enabled": false,"status": null},"billing_address_collection": null,"cancel_url": "http://127.0.0.1:3000/tour/the-mountain-biker","client_reference_id": "64482b81fc72db55d5ab256c","consent": null,"consent_collection": null,"created": 1682624190,"currency": "usd","currency_conversion": null,"custom_fields": [],"custom_text": {"shipping_address": null,"submit": null},"customer": null,"customer_creation": "if_required","customer_details": {"address": null,"email": "leo@example.com","name": null,"phone": null,"tax_exempt": "none","tax_ids": null},"customer_email": "leo@example.com","expires_at": 1682710590,"invoice": null,"invoice_creation": {"enabled": false,"invoice_data": {"account_tax_ids": null,"custom_fields": null,"description": null,"footer": null,"metadata": {},"rendering_options": null}},"livemode": false,"locale": null,"metadata": {},"mode": "payment","payment_intent": null,"payment_link": null,"payment_method_collection": "always","payment_method_options": {},"payment_method_types": ["card"],"payment_status": "unpaid","phone_number_collection": {"enabled": false},"recovered_from": null,"setup_intent": null,"shipping_address_collection": null,"shipping_cost": null,"shipping_details": null,"shipping_options": [],"status": "open","submit_type": null,"subscription": null,"success_url": "http://127.0.0.1:3000/","total_details": {"amount_discount": 0,"amount_shipping": 0,"amount_tax": 0},"url": "https://checkout.stripe.com/c/pay/cs_test_a1mZ6W9dAO1n7IgpBkvZFJR3Uoe0TTAv3BV9U76b9JVpogcbOyImkaAvU2#fidkdWxOYHwnPyd1blpxYHZxWjA0SzRTa1FWQkNTSE9%2FN3BEXFF3RlJvVXJnVn02bV0yQEh8ZEJrVW01bHFPYHxqUzxtbjFBRkpdc2phMU9oUTA8NVFUU19BQXE0XGRHXHBcMTBGQH1PYUI2NTVmf1xTd0FhSicpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl"}}

代码(stripe@7):

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const Tour = require('./../models/tourModel');
const catchAsync = require('./../utils/catchAsync');
const factory = require('./handlerFactory');
const AppError = require('./../utils/appError');

exports.getCheckoutSession = catchAsync(async (req, res, next) => {
  //1) Get the currently booked tour
  const tour = await Tour.findById(req.params.tourId);
  //2) Create checkout session
  console.log(tour);
  const session = await stripe.checkout.sessions.create({
    payment_method_types: ['card'],
    success_url: `${req.protocol}://${req.get('host')}/`,
    cancel_url: `${req.protocol}://${req.get('host')}/tour/${tour.slug}`,
    customer_email: req.user.email,
    client_reference_id: req.params.tourId,

    line_items: [
      {
        quantity: 1,
        price_data: {
          currency: 'usd',
          unit_amount: tour.price * 100,
          product_data: {
            name: `${tour.name} Tour`,
            description: tour.summary,
            images: [`https://www.natours.dev/img/tours/${tour.imageCover}`],
          },
        },
      },
    ],

    // metadata: {
    //   name: `${tour.name} Tour`,
    //   description: tour.summary,
    //   image: `https://www.natours.dev/img/tours/${tour.imageCover}`,
    // },

    mode: 'payment',
  });

  //3) Create session as response
  res.status(200).json({
    status: 'success',
session,
  });
});
解决方案

1. product_data未显示的原因及处理

Stripe Checkout Session的返回结果中,不会直接包含product_data字段。当你通过price_data.product_data动态创建产品和价格时,Stripe会自动生成对应的Product和Price对象,但这些信息不会嵌套在Session的返回结果里。

如果需要获取产品相关信息,有两种方式:

  • 调用stripe.checkout.sessions.listLineItems(session.id)获取Session的完整商品条目,从中拿到Price ID,再调用stripe.prices.retrieve(priceId)获取价格对象,最后通过价格对象的product字段调用stripe.products.retrieve(productId)拿到产品详情。
  • 提前在Stripe后台创建好Product和Price,在line_items中直接使用price字段(而非price_data),后续可直接通过Price ID关联查询产品信息。

2. payment_intent为null的原因及处理

payment_intent为null是因为当前Session状态为open(未支付)。在Stripe的payment模式下,只有用户完成支付后,Checkout Session才会关联生成Payment Intent,此时payment_intent字段才会被赋值。

如果需要获取支付完成后的相关信息,可通过以下方式:

  • 监听Stripe的checkout.session.completed webhook事件,用户完成支付后Stripe会推送该事件,事件中包含完整的Session信息(包括payment_intent)。
  • 支付完成后,主动调用stripe.checkout.sessions.retrieve(session.id)查询Session,此时返回的结果中会包含payment_intent字段。

当前代码中mode: 'payment'的配置是正确的,用于一次性支付场景,支付完成后Session状态会变为complete,payment_intent字段会被填充。


内容的提问来源于stack exchange,提问作者xitij

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:17:55