这是一个非常流行的错误,但是,我找到的解决方案都不适合我。
我有一个由 Vercel 托管的 NextJs 应用程序。 Stripe Webhook 在本地工作,但是,当它在 Vercel 上远程运行时,当它尝试验证请求时,我收到以下 stripe 错误:
No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?
这是我的 NextJs 应用程序中的 Webhook 端点:
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: "2023-08-16",
});
export async function POST (req) {
const buf = await req.text();
const sig = req.headers.get('stripe-signature');
let event;
try {
event = stripe.webhooks.constructEvent(buf, sig, webhookSecret); // this triggers the error
} catch (err) {
console.log(`Error: Stripe webhook failed: ${err.message}`);
return NextResponse.json({ received: false, error: err.message}, { status: 400 });
}
...
}
此行导致错误:
event = stripe.webhooks.constructEvent(buf, sig, webhookSecret);
我知道sig
和webhookSecret
是正确的,我已经检查了太多次。这里奇怪的是,当应用程序托管在 Vercel 上时,相同的 Webhook 请求在本地工作,但不能远程工作。许多人都说应用程序中间件是问题所在,但在这种情况下,会是 Vercel 中间件吗?我还没有找到任何 Vercel 问题干扰 Stripe webhook 的人的实例。
我尝试过以各种方式检索原始请求主体,但都不起作用:
import {buffer} from "micro";
const buf = await buffer(req);
stripe.webhooks.constructEvent(buf.toString(), sig, webhookSecret);
import getRawBody from 'raw-body';
const rawBody = await getRawBody(req);
stripe.webhooks.constructEvent(rawBody, sig, webhookSecret);
有人有什么想法吗?预先感谢您的任何见解!
我犯了一个非常简单的错误。我使用的是 stripe webhook 端点仪表板右上角的值(以“we_”开头),认为它是 webhook 秘密。但实际上,您需要使用也位于 stripe webhook 端点仪表板上且位于端点标题下方的“签名密钥”。它以“whsec_”开头。在上面的示例中,该值应设置为
webhookSecret