我正在开发一个 webhook 来使用 Deno 和 Stripe 库处理来自 Stripe 的事件。最近,在尝试验证 webhook 签名时,我收到以下错误:
Webhook 错误:未找到与有效负载的预期签名匹配的签名。
详情
API 密钥:我已验证 Stripe API 密钥是否正确,并且与我在应用程序中使用的密钥相同。 Webhook 配置:Webhook 在 Stripe 仪表板中正确设置,并且我正在按预期接收事件。 Webhook 代码:我使用以下代码来处理 webhook:
import "jsr:@supabase/functions-js/edge-runtime.d.ts";
import Stripe from 'https://esm.sh/[email protected]?target=deno';
import { config } from "https://deno.land/x/dotenv/mod.ts";
// Load environment variables from .env file
const env = config();
const stripeApiKey = env.STRIPE_API_KEY;
const stripeWebhookSecret = env.STRIPE_WEBHOOK_SIGNING_SECRET;
// Configure the Stripe client
const stripe = new Stripe(stripeApiKey as string, {
apiVersion: '2022-11-15',
httpClient: Stripe.createFetchHttpClient(),
});
// Start the Deno server
Deno.serve(async (request) => {
const webhookStripeSignatureHeader = request.headers.get('Stripe-Signature');
if (!webhookStripeSignatureHeader) {
return new Response('Missing Stripe signature', { status: 400 });
}
const webhookRawBody = await request.arrayBuffer();
const requestBody = new TextDecoder().decode(webhookRawBody);
const signature = webhookStripeSignatureHeader;
let event;
try {
// Construct the event from Stripe using the raw body and the signature header
event = stripe.webhooks.constructEvent(requestBody, signature, stripeWebhookSecret);
} catch (err) {
console.error(`Webhook Error: ${err.message}`);
return new Response(err.message, { status: 400 });
}
console.log(`🔔 Event received: ${event.id}`);
return new Response(JSON.stringify({ ok: true }), { status: 200 });
});
即使使用正确的 API 密钥,也可能导致错误“未找到与有效负载的预期签名匹配的签名”? 我可以做些什么来确保请求正文正确传递给constructEvent函数?
我已经检查了环境变量,它们加载正确。 我已尝试调试应用程序并验证请求正文是否正确。
此问题的常见原因是请求正文不再是原始形式,尤其是在使用解码器或转换函数时。
我建议使用以下函数(reference)来检索原始请求正文:
// First step is to verify the event. The .text() method must be used as the
// verification relies on the raw request body rather than the parsed JSON.
const body = await request.text();