Next.js集成Stripe支付遇data.map is not a function错误求助
解决Next.js集成Stripe时的data.map is not a function错误
问题根源
你的控制台输出已经明确显示:后端收到的req.body是一个包含body属性的对象,而非直接的商品数组。你直接对这个对象调用.map()方法,自然会报错——对象本身没有map方法。
看你前端的请求代码:
const postData = async () => { const response = await axios.post("/api/checkout_sessions", { body: basket, // 这里把数组额外包在了body字段里 }) return response.json(); };
后端req.body拿到的就是{ body: [你的商品数组] },所以const data = req.body后,data是对象,不是数组。
两种解决办法
方法一:修改前端请求,直接传数组
把axios.post的第二个参数改成basket本身,不用额外嵌套一层body:
const postData = async () => { const response = await axios.post("/api/checkout_sessions", basket) return response.data; // axios的响应数据直接在response.data里,无需调用.json() };
这样后端req.body直接就是商品数组,data.map()就能正常执行。
方法二:修改后端代码,取正确的数组字段
如果不想调整前端,就在后端把data指向req.body里的body属性:
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); export default async function handler(req, res) { if (req.method === 'POST') { // 改为读取req.body中的body数组 const data = req.body.body; console.log(data) // 注意:Stripe的unit_amount要求是货币最小单位的整数(比如美元用分) const transformedItems = data.map(item => ({ price_data: { unit_amount: Math.round(item.price * 100), // 将55.99美元转为5599分 currency: 'usd', product_data: { name: item.title, description: item.description, }, }, quantity: 1, })) try { const session = await stripe.checkout.sessions.create({ shipping_address_collection: { allowed_countries: ["US", "CA", "GB"], }, line_items: transformedItems, mode: 'payment', success_url: `${req.headers.origin}/?success=true`, cancel_url: `${req.headers.origin}/?canceled=true`, }); 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'); } }
额外提醒
Stripe的unit_amount必须是货币最小单位的整数(比如美元对应分),你现在直接传入item.price(如55.99)会触发报错,一定要做转整数处理,上面代码已经通过Math.round(item.price * 100)解决了这个问题。
内容的提问来源于stack exchange,提问作者Cameron Austin
相关产品推荐
相关产品推荐

