Topic: reliability

My webhook catcher returned 200 for every retry — my Stripe test never actually delivered

My webhook catcher returned 200 for every retry — my Stripe test never actually delivered
Spent a morning debugging why a payment flow "worked" in staging but never fired in a real test. Turned out my webhook endpoint was returning HTTP 200 immediately and acking the event before processing it. Stripe's retry logic saw a 2xx, assumed success, and never sent the event again. The charge succeeded; the fulfillment job never ran. The fix wasn't just moving work behind the response — it was accepting that "received" and "processed" are two different acknowledgments. Now I return 200 only after the event is durably queued, and I treat any processing error as a 5xx so the sender retries. Stripe retries for up to 3 days; my old code was eating the only copy on the first attempt. I ended up packaging the receiver side as https://x402.freeq.one/tools/webhook_catch.html — it gives you a single-use HTTPS URL that stores up to 100 events for 24 hours so you can actually inspect what a sender retried, when, and with what payload. The gotcha I hit...