使用Netlify Functions对接Stripe Webhook返回400签名不匹配问题求助
问题排查与修复方案
1. 签名验证失败根因
你遇到的签名不匹配错误核心原因是Netlify Functions默认会自动解析JSON格式的请求体,此时你拿到的body是解析后的对象,不是Stripe发送的原始未修改字符串,签名校验需要完全匹配原始payload才能通过。
2. 修复步骤
第一步:禁用Netlify自动请求体解析
有两种配置方式可选:
- 方式1:直接在函数代码中添加配置(推荐)
在你的函数文件顶部添加如下配置,告诉Netlify不要解析请求体,直接返回原始内容:
exports.config = { parser: "none" };
- 方式2:在项目根目录的
netlify.toml中配置
将下面的your-webhook-function-name替换为你的Netlify Function文件名:
[functions."your-webhook-function-name"] parser = "none"
第二步:调整代码使用原始请求体
禁用自动解析后,拿到的body是原始Buffer,需要转成字符串后再传给Stripe的签名校验方法,修改后的完整代码如下:
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY); const sgMail = require("@sendgrid/mail"); sgMail.setApiKey(process.env.SENDGRID_API_KEY); // 禁用自动解析请求体 exports.config = { parser: "none" }; exports.handler = async ({ body, headers }) => { try { // 将原始Buffer转为字符串 const rawBody = body.toString(); const stripeEvent = stripe.webhooks.constructEvent( rawBody, headers["stripe-signature"], process.env.STRIPE_WEBHOOK_SECRET ); if (stripeEvent.type === "charge.succeeded") { const emailTo = stripeEvent.data.object.billing_details.email; const msg = { to: emailTo, from: process.env.FROM_EMAIL_ADDRESS, subject: `Thanks!`, html: `elox`, }; await sgMail.send(msg); } return { statusCode: 200, body: JSON.stringify({ received: true }), }; } catch (err) { console.log(`Stripe webhook failed with ${err}`); return { statusCode: 400, body: `Webhook Error: ${err.message}`, }; } };
3. 其他校验项
- 确认Netlify控制台配置的
STRIPE_WEBHOOK_SECRET与Stripe控制台生成的Webhook签名密钥完全一致,无多余空格或字符。 - 确认Stripe控制台配置的Webhook端点与你的Netlify Function访问地址完全匹配。
- 确认
FROM_EMAIL_ADDRESS是你在Sendgrid控制台已验证通过的发件人地址,否则邮件会发送失败。
4. 关于Webhook重发与Sendgrid记录
当前Sendgrid无记录是因为签名校验失败,代码根本没有走到发送邮件的逻辑。修复代码部署生效后,再到Stripe控制台重发失败的Webhook请求即可正常触发邮件发送流程。
内容的提问来源于stack exchange,提问作者seven
相关产品推荐
相关产品推荐

