Webhooks are at-least-once: duplicated, delayed, and sometimes never delivered.
I built a local drill that drops a Stripe webhook on purpose, then lets the merchant reconciliation job recover the order 5 minutes later.
Repo + write-up:
https://t.co/EGMTPZn6Fx
@HarisJ95e Appreciate it. The ledger angle is the right one: recovery has to be idempotent, or the reconciliation run itself becomes a duplicate source. Curious how you stress the ledger side — balance assertions, or write-count assertions?
Webhooks are at-least-once: duplicated, delayed, and sometimes never delivered.
I built a local drill that drops a Stripe webhook on purpose, then lets the merchant reconciliation job recover the order 5 minutes later.
Repo + write-up:
https://t.co/EGMTPZn6Fx
What I would test in any payment stack:
1. drop a webhook on purpose
2. deliver the same event twice
3. restart mid-retry
4. assert no double recovery
5. make reconciliation visible in logs/metrics
Repo + write-up:
https://t.co/EGMTPZn6Fx
Webhooks are at-least-once. They get retried, duplicated, delayed, and sometimes they never arrive at all. Retry logic helps when your handler fails — it does not help when the delivery never reaches you.
So I built a drill: the emulator drops payment_intent.succeeded. The provider says "succeeded" while the merchant order stays PENDING. Then the sandbox clock jumps 5 minutes, reconciliation pulls the intent, and the order is recovered: status=PAID, paidSource=reconciliation.
Open-sourced my payment QA framework: 42 scenarios (payments, failures, subscriptions, webhooks, auth-capture, chargebacks, edge cases) run against a built-in mock gateway, with CI and generated reports. https://t.co/APFQMsy5rN