NestJS Stripe Webhook 部署到 Render.com 后出现错误

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

我正在 NestJS 应用程序中使用 Stripe webhook。当我使用 Stripe CLI 和“stripe Listen --forward-to localhost:3333/v1/stripe/webhook”命令在本地测试 webhook 来转发事件时,一切正常。但是,将我的应用程序部署到 Render 后,我遇到以下错误:

Webhook Error: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? 
If a webhook request is being forwarded by a third-party tool, ensure that the exact request body, including JSON formatting and new line style, is preserved.

我的 NestJS main.ts

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule, {
    rawBody: true
  });

  const corsOrigins = process.env.CORS_ORIGINS?.split(',') || [];

  app.enableCors({
    origin: corsOrigins,
    credentials: true
  });

  app.useGlobalPipes(new ValidationPipe({
    whitelist: true,
    transform: true
  }));

  app.enableVersioning({
    type: VersioningType.URI,
  });

  await app.listen(process.env.PORT || 3333);
}
bootstrap();

stripe的Webhook控制器和句柄函数

 @Post('webhook')
  async handleStripeWebhook(
    @Req() req: RawBodyRequest<Request>,
    @Headers('stripe-signature') sig: string,
  ) {
    return this.stripeService.handleStripeWebhook(req, sig);
  }

 async handleStripeWebhook(
        req: any,
        signature: string
    ) {
        const getRawBody = await req.rawBody;

        if (!getRawBody) {
            console.error('No raw body found');
            return console.log('No raw body');
        }

        const endpointSecret = this.config.get('STRIPE_WEBHOOK_SECRET');
        let event: Stripe.Event;

        try {
            event = this.stripe.webhooks.constructEvent(getRawBody, signature, endpointSecret);
        } catch (err) {
            console.error('Webhook Error:', err.message);
            return { error: 'Webhook Error' };
        }

        return { received: true };
    }

我尝试过的:

  • 检查了本地和渲染上的 STRIPE_WEBHOOK_SECRET 环境变量。
  • 还有其他格式,如
  app.useBodyParser('json', { limit: '100mb' });
  app.useBodyParser('urlencoded', { limit: '50mb', extended: true });

  app.use(json(getBodyParserOptions(true, { limit: '50mb' })));
  app.use(urlencoded(getBodyParserOptions(true, { limit: '50mb' })));

  app.use(
    rawBodyMiddleware({
      limit: '200mb',
      rawBodyUrls: ['/v1/stripe/webhook']
    })
  );

  const rawBodyBuffer = (req, res, buffer, encoding) => {
    if (!req.headers['stripe-signature']) { return; }

    if (buffer && buffer.length) {
      req.rawBody = buffer.toString(encoding || 'utf8');
    }
  };

问题:

  • 如何确保原始请求正文在我的部署环境中正确传递?
  • Render 是否需要进行与本地开发不同的具体配置或中间件调整?
  • 有没有人在部署到 Render 时遇到类似的问题,您是如何解决的? 感谢您的帮助!
deployment nestjs stripe-payments webhooks stripes
1个回答
0
投票

此错误很可能是由

rawBodyMiddleware
引起的,因为中间件可能会操纵原始主体并使验证失败(ref)。

您可以删除中间件并重试吗?

© www.soinside.com 2019 - 2024. All rights reserved.