Stripe结账集成报错:No such price: '{{PRICE_ID}}' 请求失败
Stripe结账集成报错修复
报错信息
POST http://localhost:3000/api/stripe 400 (Bad Request)Uncaught (in promise) SyntaxError: Unexpected token 'N', "No such price: '{{PRICE_ID}}'"... is not valid JSON
相关代码片段
Cart.jsx
const Cart = () => { const cartRef = useRef(); const { totalPrice, totalQuantities, cartItems, setShowCart, toggleCartItemQuantity, onRemove } = useStateContext(); const handleCheckout = async () => { const stripe = await getStripe(); const response = await fetch('/api/stripe', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(cartItems), }); console.log(response) if(response.statusCode === 500) return; const data = await response.json(); toast.loading('Redirecting...'); stripe.redirectToCheckout({ sessionId: data.id }); }
api/stripe.js
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); //const stripe = require(`${process.env.STRIPE_SECRET_KEY}`) export default async function handler(req, res) { if (req.method === 'POST') { console.log(req.body.cartItems) try { const params = { submit_type: 'pay', mode: 'payment', payment_method_types: ['card'], billing_address_collection: 'auto', shipping_options: [ { shipping_rate: 'shr_1MmbQsDxppDAFTDHT3PKZP9Q'}, { shipping_rate: 'shr_1MmbSBDxppDAFTDHAnfijv4n'}, ], line_items: [ { // Provide the exact Price ID (for example, pr_1234) of the product you want to sell price: '{{PRICE_ID}}', quantity: 1, }, ], mode: 'payment', success_url: `${req.headers.origin}/?success=true`, cancel_url: `${req.headers.origin}/?canceled=true`, } // Create Checkout Sessions from body params. const session = await stripe.checkout.sessions.create(params); 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'); } }
getStripe.js
import { loadStripe } from "@stripe/stripe-js"; let stripePromise; const getStripe = () => { if(!stripePromise) { //stripePromise = loadStripe(`${process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY}`) stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY); } return stripePromise; } export default getStripe;
问题分析与修复步骤
占位符未替换导致价格ID错误
报错核心原因是stripe.js中line_items的price字段使用了示例占位符{{PRICE_ID}},必须替换为你在Stripe后台创建的真实价格ID(格式类似pr_xxxxxx)。未对接前端购物车数据
前端已通过POST请求发送cartItems,但后端硬编码了固定的line_items,且错误尝试读取req.body.cartItems(实际应直接读取req.body,因为前端发送的是JSON.stringify(cartItems))。需要遍历req.body生成对应商品条目。错误响应格式不符合JSON要求
后端捕获错误后返回的是字符串格式的err.message,导致前端response.json()解析失败。需改为返回标准JSON格式的错误信息。
修复后的api/stripe.js示例
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); export default async function handler(req, res) { if (req.method === 'POST') { const cartItems = req.body; console.log(cartItems); try { // 从购物车数据生成Stripe所需的line_items const lineItems = cartItems.map(item => ({ price: item.priceId, // 确保cartItems中每个商品包含正确的Stripe价格ID quantity: item.quantity, })); const params = { submit_type: 'pay', mode: 'payment', payment_method_types: ['card'], billing_address_collection: 'auto', shipping_options: [ { shipping_rate: 'shr_1MmbQsDxppDAFTDHT3PKZP9Q'}, { shipping_rate: 'shr_1MmbSBDxppDAFTDHAnfijv4n'}, ], line_items: lineItems, success_url: `${req.headers.origin}/?success=true`, cancel_url: `${req.headers.origin}/?canceled=true`, }; const session = await stripe.checkout.sessions.create(params); // 返回session.id给前端用于跳转结账 res.status(200).json({ id: session.id }); } catch (err) { // 返回JSON格式的错误信息 res.status(err.statusCode || 500).json({ error: err.message }); } } else { res.setHeader('Allow', 'POST'); res.status(405).end('Method Not Allowed'); } }
额外注意事项
- 确认
cartItems中每个商品都包含正确的Stripe价格ID,该ID需从Stripe控制台的商品价格设置中获取。 - 检查环境变量
STRIPE_SECRET_KEY和NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY配置是否正确,修改后需重启开发服务器。 - 前端
handleCheckout中需将response.statusCode改为response.status,因为Fetch API响应对象使用status字段表示状态码。
内容的提问来源于stack exchange,提问作者mojo45
相关产品推荐
相关产品推荐

