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

Stripe Webhook无法读取Express请求原始Body,报400错误求助

解决Stripe Webhook "payload must be provided as a string or a Buffer"错误

你的问题核心是Stripe Webhook签名验证依赖原始未解析的请求体,但你用bodyParser.json()把请求体解析成了JSON对象,导致constructEvent无法正确验证签名。

修正步骤:

  • 移除webhook路由上的bodyParser.json(),替换为bodyParser.raw({ type: 'application/json' }),这样获取到的request.body是原始Buffer,符合Stripe的要求。
  • 确保webhook路由的中间件配置在其他express.json()或bodyParser.json()中间件之前,避免请求体被提前解析。

修正后的代码:

dotenv.config()

const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY)
const bodyParser = require('body-parser') // 确保已安装并引入body-parser

const app = express()

app.use(morgan("dev"))

app.use(
  cors({
    origin: process.env.ORIN,
    credentials: true,
    optionsSuccessStatus: 200,
  })
)

// Webhook路由使用raw中间件获取原始请求体
app.post("/webhook", bodyParser.raw({ type: 'application/json' }), (request, response) => {
  const payload = request.body // 此时payload是Buffer类型
  const sig = request.headers["stripe-signature"]

  let event

  try {
    event = stripe.webhooks.constructEvent(
      payload,
      sig,
      process.env.STRIPE_ENDPOINT_SECRET
    )

    if (event.type === "checkout.session.completed") {
      console.log("Session completed successfully")
    }
  } catch (err) {
    return response.status(400).send(`Webhook Error: ${err.message}`)
  }

  response.status(200).end()
})

app.use(cookieParser())

app.use(express.json({ limit: "50mb" }))

//Rest of endpoints

补充说明:

  • 如果你的Express版本是v4.16+,也可以用express.raw({ type: 'application/json' })替代bodyParser.raw,效果一致。
  • 绝对不能在webhook路由之前使用任何会解析请求体的中间件(比如express.json()、bodyParser.json()),否则原始请求体被修改后签名验证必然失败。

内容的提问来源于stack exchange,提问作者dacalite

相关产品推荐
方舟 Agent Plan

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

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