Fix Stripe Webhook in Fastify

Fastify parses JSON automatically for all routes. The fix is addContentTypeParser with parseAs: 'buffer' — registered before any other JSON consumer on the webhook route.

The complete webhook plugin

// plugins/webhooks.js
import Stripe from 'stripe';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
const secret = process.env.STRIPE_WEBHOOK_SECRET;

async function webhookPlugin(fastify) {
  // Override JSON parsing for this plugin — get raw Buffer
  fastify.addContentTypeParser(
    'application/json',
    { parseAs: 'buffer' },
    (req, body, done) => done(null, body)
  );

  fastify.post('/api/webhooks/stripe', async (request, reply) => {
    const sig = request.headers['stripe-signature'];

    if (!sig) {
      return reply.code(400).send({ error: 'Missing stripe-signature header' });
    }

    let event;
    try {
      // request.body is a Buffer from parseAs: 'buffer'
      event = stripe.webhooks.constructEvent(request.body, sig, secret);
    } catch (err) {
      return reply.code(400).send({ error: \`Webhook Error: \${err.message}\` });
    }

    switch (event.type) {
      case 'checkout.session.completed':
        // fulfill order
        break;
    }

    return { received: true };
  });
}

export default webhookPlugin;

Registration order in server.js

// server.js — register webhook plugin BEFORE other JSON routes
await fastify.register(import('./plugins/webhooks.js'));

// Other routes that use JSON parsing can come after
await fastify.register(import('./routes/api.js'), { prefix: '/api' });
Scope matters in Fastify. addContentTypeParser affects all routes in the current plugin scope. Registering it in a dedicated plugin keeps it isolated from your other routes that need normal JSON parsing.

Generate the complete Fastify webhook plugin automatically.

Open WebhookFix →
For informational purposes only. Always test in staging before production. MetricLogic accepts no responsibility for issues arising from use of these tools. © 2026 MetricLogic.
HttpFixer by MetricLogic · Blog · All Tools · Generators MIT · GitHub →