Back to DevLog

Deep Diving Into Stripe Webhook Hell (And Coming Out Victorious)

3 min read

Sometimes debugging feels like archaeology — you're digging through layers of code, following breadcrumbs, until you finally hit that "aha!" moment. Today was one of those days with the MemStack Pro Stripe webhook pipeline.

The Problem

Our Stripe webhooks were failing with cryptic 400 errors. Not the fun kind of debugging where you get a nice stack trace — just silent failures that made me question everything.

The Investigation

I pulled out the big guns and ran a full audit of our webhook handler (all 1,158 lines of it) using my Manager/Builder/Reviewer agent team. Three sets of eyes are better than one, especially when you're staring at webhook spaghetti.

The breakthrough came when we traced the failure point: signature verification was failing before any of our logic even ran. Classic "problem exists between keyboard and chair" moment — three critical Stripe environment variables were completely empty:

  • STRIPE_SECRET_KEY
  • MEMSTACK_PRO_STRIPE_WEBHOOK_SECRET
  • MEMSTACK_PRO_STRIPE_PRODUCT_ID

No wonder Stripe was rejecting our webhook signatures!

The Fixes

While I was in there, I knocked out a few other improvements:

1. Source Gating (P2) Added a check to prevent the MemStack Pro handler from running on ImageStack/BunkerVault webhook events. Why make unnecessary Stripe API calls when we know the webhook isn't for us?

2. Email From Address (P1) Hardcoded noreply@memstack.pro for MemStack Pro emails instead of using our generic SendGrid from address. Professional touch.

3. Better Documentation (P0) Added descriptive comments to .env.example because future me (and anyone else touching this code) will thank present me.

The Accidental Restart

In a classic case of having too many terminal tabs open, I accidentally restarted EpsteinScan on our Hetzner box while trying to debug locally. Oops! But hey, everything came back up clean — homepage, AI endpoints, CSRF protection all passing. Sometimes accidents lead to good system health checks.

What's Next

The fixes are committed on the dev branch but not pushed yet. I'm waiting to:

  1. Set those three missing Stripe env vars (both locally and on Netlify)
  2. Verify noreply@memstack.pro is set up as a SendGrid sender
  3. Push and test the full webhook flow end-to-end

There's something deeply satisfying about tracking down a bug that turns out to be missing configuration rather than broken logic. It means the architecture is sound — we just forgot to plug it in properly.

Next up: full end-to-end testing with Stripe's test mode, then we can finally call this webhook pipeline bulletproof.

Share this post