DEV Community

Cover image for Stripe webhook not working? How to debug and fix it (complete guide)
Ciroandrea
Ciroandrea

Posted on

Stripe webhook not working? How to debug and fix it (complete guide)

Stripe webhooks not working?

You're not alone — it's one of the most common issues when integrating Stripe in a SaaS.

The tricky part is that sometimes… they actually are working.

  • events are received
  • 200 responses are returned
  • logs look fine

But your system still breaks.

That’s because most webhook issues are not about Stripe — they’re about backend logic.


Why Stripe webhooks “don’t work”

The most common causes:

  • body parsing modifies the request
  • wrong webhook secret (test vs live)
  • endpoint is unreachable
  • returning 200 without real processing

The worst case is this:

Your server returns 200 OK, but doesn't actually update anything.

Stripe stops retrying, and your system slowly goes out of sync.


Common mistakes

  • using express.json() instead of express.raw()
  • not verifying the webhook signature
  • not handling duplicate events
  • relying on frontend redirects
  • not logging events properly

Correct Stripe webhook setup (Node.js)

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

  let event;

  try {
    event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
  } catch (err) {
    console.error('Webhook signature verification failed.', err.message);
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  if (event.type === 'checkout.session.completed') {
    const session = event.data.object;

    // Update your database
    // Grant access to the user
    grantAccessToUser(session.customer_email);
  }

  res.status(200).send();
});

Enter fullscreen mode Exit fullscreen mode

👉 Official Stripe docs.


How to debug Stripe webhooks

When something doesn’t work, follow this:

  1. Check Stripe Dashboard → Events
  2. Verify if the event was delivered
  3. Inspect backend logs
  4. Replay events from Stripe
  5. Double-check webhook secret

In most cases, the issue becomes obvious here.


The most dangerous pattern

A very common anti-pattern looks like this:

res.json({ received: true });
Enter fullscreen mode Exit fullscreen mode

…without actually handling the event.

👉 Stripe thinks everything is fine
👉 stops retrying
👉 your system silently breaks


Best practices

  • make your system idempotent
  • store event IDs
  • handle retries correctly
  • never trust the frontend
  • always verify webhook signatures

Real production issue

This is where things get dangerous:

  • payment succeeds
  • webhook fires
  • backend returns 200
  • but logic is incomplete

Everything looks healthy…

Until:

  • users lose access
  • subscriptions go out of sync
  • revenue silently drops

When this becomes a system problem

If you’ve worked with Stripe before, you know this logic grows fast:

  • subscriptions
  • usage-based billing
  • credits (AI, APIs, etc.)
  • access control

At some point, it stops being a simple integration problem.

It becomes a system problem.

That’s something I’ve been exploring recently — especially around making Stripe integrations more reliable by design.


More details

I also wrote a deeper breakdown here:

👉 https://www.sos-guide.it/stripe-webhook-non-funziona-guida-per-debug-e-fix/


Final takeaway

Stripe webhooks don’t “fail” randomly.

They fail when:

  • your backend logic is incomplete
  • events are not handled correctly
  • systems are not designed for async flows

If you treat Stripe as the source of truth and design your backend around it, most of these issues disappear.

What’s the most confusing webhook issue you’ve ever debugged?

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.