Next.js部署Vercel后Stripe支付集成出现405方法不允许错误
Vercel部署Stripe支付出现405 Method Not Allowed错误排查与解决
问题描述
本地测试Stripe支付集成功能正常,但将代码部署到Vercel后,出现405 Method Not Allowed错误。
用户提供的Stripe API代码:
import Stripe from "stripe"; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, { apiVersion: "2023-10-16", }); export default async function POST(req, res) { if (req.method === "POST") { try { const orderData = req.body; if (!orderData || !Array.isArray(orderData.items)) { console.error("Invalid order data:", orderData); throw new Error( "Invalid order data or lineItems missing or not an array" ); } const lineItems = orderData.items.map((product) => ({ quantity: product.quantity, price_data: { currency: "inr", unit_amount: product.price * 100, product_data: { name: product.name, }, }, })); const session = await stripe.checkout.sessions.create({ payment_method_types: ["card"], line_items: lineItems, mode: "payment", success_url: `${process.env.VERCEL_URL}/thank-you`, cancel_url: `${process.env.VERCEL_URL}/`, }); res.status(200).json({ id: session.id }); res.redirect(302, session.url); } catch (err) { console.error("Error creating Stripe session:", err); res.status(400).json({ error: err.message }); } } else { res.setHeader("Allow", "POST"); res.status(405).end("Method Not Allowed"); } }
核心问题与修复方案
1. API路由处理函数导出错误
Vercel部署的Next.js Pages Router API路由要求默认导出通用处理函数,而非按HTTP方法命名的函数(如POST)。你的代码将处理函数命名为POST,导致Vercel无法识别该函数作为API路由的入口,请求无法被正确处理,进而返回405错误。
修复代码:
将命名函数改为默认导出的通用处理函数:
import Stripe from "stripe"; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, { apiVersion: "2023-10-16", }); // 默认导出通用处理函数 export default async function handler(req, res) { if (req.method === "POST") { try { const orderData = req.body; if (!orderData || !Array.isArray(orderData.items)) { console.error("Invalid order data:", orderData); throw new Error( "Invalid order data or lineItems missing or not an array" ); } const lineItems = orderData.items.map((product) => ({ quantity: product.quantity, price_data: { currency: "inr", unit_amount: product.price * 100, product_data: { name: product.name, }, }, })); const session = await stripe.checkout.sessions.create({ payment_method_types: ["card"], line_items: lineItems, mode: "payment", success_url: `${process.env.VERCEL_URL}/thank-you`, cancel_url: `${process.env.VERCEL_URL}/`, }); // 二选一:返回JSON让前端跳转,或后端直接跳转 res.status(200).json({ id: session.id, url: session.url }); // res.redirect(303, session.url); } catch (err) { console.error("Error creating Stripe session:", err); res.status(400).json({ error: err.message }); } } else { res.setHeader("Allow", "POST"); res.status(405).end("Method Not Allowed"); } }
2. 重复响应问题
代码中同时调用res.status(200).json(...)和res.redirect(...),会导致响应重复发送,属于无效操作,必须二选一:
- 若前端发起请求后自行跳转:返回包含
session.url的JSON响应,前端通过window.location.href = session.url实现跳转。 - 若后端直接跳转:仅保留
res.redirect(303, session.url)(使用303状态码确保后续请求为GET方法,符合Stripe要求),删除res.json()代码。
3. 其他验证步骤
- 确认Vercel项目设置中已正确配置
STRIPE_SECRET_KEY和VERCEL_URL环境变量,且部署时已生效。 - 检查前端请求方式,确保发起的是POST请求到该API路由,无请求方法错误。
内容的提问来源于stack exchange,提问作者Sakib Ansari
相关产品推荐
相关产品推荐

