Choorai
Critical integration issue

Fixing Webhook Signature Verification Errors

If signature verification failed occurs on payment or external webhooks, events may be dropped and state can diverge.

TL;DR

1) Verify against raw body 2) Confirm environment-specific webhook secrets 3) Add idempotency handling for retries

심각

Webhook signature verification failed

원인

Payload integrity check failed. Common causes are raw body mutation, secret mismatch, and missing signature headers.

해결책
  1. Validate signature using raw body before JSON parsing
  2. Check that production/test webhook secrets are not mixed
  3. Follow provider-specific signature algorithm and header format
  4. Handle duplicate retries with idempotency keys

Validation points

Express + Stripe example
import express from 'express';
import Stripe from 'stripe';

const app = express();
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || '');

app.post('/webhook/stripe', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['stripe-signature'];
  const secret = process.env.STRIPE_WEBHOOK_SECRET || '';

  try {
    const event = stripe.webhooks.constructEvent(req.body, String(signature), secret);
    // TODO: handle event with idempotency check
    res.status(200).send('ok');
  } catch (err) {
    res.status(400).send('signature verification failed');
  }
});

Important

If JSON/body parsers run first, raw payload may change and signature checks can fail.

Prerequisites

  • You can access webhook provider docs (Stripe/GitHub/etc.).
  • You can read raw request body in your server.
  • Webhook secret keys are managed securely via environment variables.

Validation

  1. Valid webhook payloads pass signature verification.
  2. Invalid or tampered payloads are rejected with 4xx.
  3. Idempotency logic prevents duplicate side effects on retries.

Troubleshooting

  • Verify signatures against raw body before JSON parsing.
  • Ensure production/staging webhook secrets are not mixed.
  • Check timestamp tolerance and replay protection settings.

References

Related Articles

Last updated: February 22, 2026 · Version: v0.0.1

Send Feedback

Opens a new issue page with your message.

Open GitHub Issue