Stripe Checkout Session中payment_intent为null问题求助
解决Next.js集成Stripe时session.payment_intent为null的问题
问题原因
Stripe API默认不会展开嵌套的payment_intent对象,同时如果在用户未完成支付时直接获取Session,payment_intent可能还未完全生成或返回。以下是两种针对性的解决方案:
方案1:创建Checkout Session时直接获取payment_intent
在创建Session时添加expand参数,强制Stripe返回payment_intent的完整信息,包括client_secret:
修改你的checkout_session.js代码:
const stripe = require("stripe")( "sk_test_xxxxx" ); export default async function handler(req, res) { if (req.method === "POST") { try { const session = await stripe.checkout.sessions.create({ line_items: [ { price: "price_1NhWxaIjDax7Fiks0djPOJXF", quantity: 1, }, ], mode: "payment", success_url: `${req.headers.origin}/?success=true`, cancel_url: `${req.headers.origin}/?canceled=true`, expand: ['payment_intent'] // 添加此行展开payment_intent }); console.log(session.payment_intent); // 此时会包含client_secret res.redirect(303, session.url); } catch (err) { res.status(err.statusCode || 500).json(err.message); } } else { res.setHeader("Allow", "POST"); res.status(405).end("Method Not Allowed"); } }
方案2:支付成功后通过Webhook获取(推荐)
如果你的需求是在用户支付成功后获取client_secret或处理后续业务逻辑,使用Stripe Webhook是最可靠的方式——用户完成支付后,Stripe会主动触发checkout.session.completed事件通知你的服务端。
步骤1:配置Webhook端点
在Stripe Dashboard的Webhook设置中,添加你的Next.js API路由(如/api/stripe-webhook),并勾选checkout.session.completed事件。同时记录下Webhook的签名密钥(whsec_xxxxx)。
步骤2:创建Webhook处理路由
新建pages/api/stripe-webhook.js:
const stripe = require('stripe')('sk_test_xxxxx'); import { buffer } from 'micro'; // 禁用Next.js默认的body解析,需要原始请求体来验证Stripe签名 export const config = { api: { bodyParser: false, }, }; export default async function handler(req, res) { if (req.method !== 'POST') { res.setHeader('Allow', 'POST'); return res.status(405).end('Method Not Allowed'); } const buf = await buffer(req); const sig = req.headers['stripe-signature']; const webhookSecret = 'whsec_xxxxx'; // 替换为你的Webhook签名密钥 let event; try { event = stripe.webhooks.constructEvent(buf.toString(), sig, webhookSecret); } catch (err) { return res.status(400).send(`Webhook Error: ${err.message}`); } // 处理支付完成事件 if (event.type === 'checkout.session.completed') { const session = event.data.object; // 获取完整的Payment Intent信息 const paymentIntent = await stripe.paymentIntents.retrieve(session.payment_intent); console.log('支付完成,Client Secret:', paymentIntent.client_secret); // 这里可以添加你的业务逻辑,比如更新订单状态、发送通知等 } res.status(200).json({ received: true }); }
内容的提问来源于stack exchange,提问作者Fortuna Investing
相关产品推荐
相关产品推荐

