SvelteKit部署Vercel时Stripe Webhook原始请求体获取失败
问题现象
搭建SvelteKit、Stripe、Vercel集成项目时,本地环境、Heroku Node服务部署、本地Vercel CLI运行均正常,仅Vercel线上部署时Stripe Webhook接口返回400状态码,报错信息:
{"msg": "Webhook Error: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?"}
原有代码配置如下:
接口处理逻辑:
export async function post({ request }) { let event; try { const sig = request.headers.get('stripe-signature'); const rawBody = request.Buffer(); event = stripe.webhooks.constructEvent(rawBody, sig, STRIPE_HOOK_ENDPOINT_SECRET); } catch (err) { console.log(err); return { status: 400, // @ts-ignore body: { msg: `Webhook Error: ${err.message}` } }; }
svelte.config.js配置:
import adapter from '@sveltejs/adapter-auto'; /** @type {import('@sveltejs/kit').Config} */ const config = { kit: { adapter: adapter(), } }; export default config;
已验证的运行场景表现:
- 本地运行(正常)
- 本地使用Vercel CLI运行(正常)
- 使用adapter-node部署至Heroku(正常)
- 部署至Vercel(运行异常)
故障原因
Vercel适配器默认会对请求体做自动解析,且默认运行时环境下request对象不存在非标准的Buffer()方法,原有代码拿到的不是Stripe发来的原始未修改请求体,导致Stripe签名校验失败。
修复方案
- 在Stripe Webhook对应的服务端路由文件中,新增路由配置,强制使用Node.js运行时、关闭默认请求体解析:
// 写在post方法同文件内 export const config = { runtime: 'nodejs18.x', api: { bodyParser: false } };
- 替换原有错误的rawBody获取逻辑,使用标准Request API读取原始请求体后转成Buffer,把
const rawBody = request.Buffer();替换为:
const rawBody = Buffer.from(await request.arrayBuffer());
- 确认Vercel平台配置的
STRIPE_HOOK_ENDPOINT_SECRET环境变量,与Stripe后台对应生产环境Webhook的签名密钥完全一致。 - 重新部署项目到Vercel即可恢复正常。
内容的提问来源于stack exchange,提问作者winterandrea
相关产品推荐
相关产品推荐

