处理 Stripe webhook 时收到“未找到与预期签名匹配的签名”错误”

问题描述 投票:0回答:1

我正在开发一个 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函数?

我已经检查了环境变量,它们加载正确。 我已尝试调试应用程序并验证请求正文是否正确。

stripe-payments supabase edge-function
1个回答
0
投票

此问题的常见原因是请求正文不再是原始形式,尤其是在使用解码器或转换函数时。

我建议使用以下函数(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();
© www.soinside.com 2019 - 2024. All rights reserved.