
Stripe Webhook 签名验证失败通常意味着请求体处理不正确或签名验证参数存在问题。 正确配置 Express 中间件以接收原始请求体至关重要,同时需要确保签名验证参数正确无误。以下是详细的步骤和注意事项,帮助您解决该问题。
1. 正确配置 Express 中间件
当处理 Stripe Webhook 时,需要确保 Express 能够接收到原始的请求体(raw request body)。这是因为 Stripe 使用请求体的内容生成签名,而默认情况下,Express 会尝试解析请求体,这可能会导致签名验证失败。
正确的配置方式是使用 express.raw() 中间件,并指定 type 为 'application/json'。这告诉 Express 接收 JSON 格式的原始请求体,而不会进行任何解析。
错误的配置:
app.post("/webhook", express.raw({ type: "*/*" }), async (request, response) => {
// ...
});正确的配置:
app.post("/webhook", express.raw({ type: 'application/json' }), async (request, response) => {
// ...
});2. 正确使用 stripe.webhooks.constructEvent 方法
stripe.webhooks.constructEvent 方法用于验证 Stripe Webhook 的签名。该方法接收三个参数:
一个常见的错误是在将 payload 传递给 stripe.webhooks.constructEvent 之前对其进行字符串化处理。stripe.webhooks.constructEvent 方法期望接收的是原始的 Buffer 或字符串,而不是 JSON 字符串。
错误的使用方式:
try {
event = stripe.webhooks.constructEvent(
JSON.stringify(payload),
sig,
process.env.WEBHOOK_SECRET
);
} catch (err) {
return response.status(400).send(`Webhook Error: ${err.message}`);
}正确的使用方式:
try {
event = stripe.webhooks.constructEvent(
payload,
sig,
process.env.WEBHOOK_SECRET
);
} catch (err) {
return response.status(400).send(`Webhook Error: ${err.message}`);
}3. 完整代码示例
以下是一个完整的代码示例,展示了如何正确处理 Stripe Webhook 的签名验证:
const express = require('express');
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const app = express();
app.post("/webhook", express.raw({ type: 'application/json' }), async (request, response) => {
const payload = request.body;
const sig = request.headers["stripe-signature"];
let event;
try {
event = stripe.webhooks.constructEvent(
payload,
sig,
process.env.WEBHOOK_SECRET
);
} catch (err) {
return response.status(400).send(`Webhook Error: ${err.message}`);
}
if (event.type === "checkout.session.completed") {
// Retrieve the session. If you require line items in the response, you may include them by expanding line_items.
const sessionWithLineItems = await stripe.checkout.sessions.retrieve(
event.data.object.id,
{
expand: ["line_items"],
}
);
const lineItems = sessionWithLineItems.line_items;
// Fulfill the purchase...
console.log("Fulfilling purchase");
}
response.status(200).end();
});
app.listen(4242, () => console.log('Running on port 4242'));4. 注意事项
5. 总结
解决 Stripe Webhook 签名验证失败的关键在于正确处理请求体和使用正确的签名验证方法。通过配置 express.raw() 中间件以接收原始请求体,并直接将 payload 传递给 stripe.webhooks.constructEvent 方法,可以有效地解决此问题。 遵循这些步骤,您可以确保您的 Webhook 安全可靠地处理 Stripe 事件。
以上就是Stripe Webhook 签名验证失败:问题诊断与解决方案的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号