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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 12:40:56