webhook-rescue-kit is a local Python CLI proof asset for Stripe Duplicate Credit Guard: duplicate-safe webhook side effects for credit grants and similar billing actions.
The main scenario is Stripe invoice.paid duplicate handling. The CLI demonstrates both same-event duplicate delivery and a different Stripe event ID pointing at the same invoice/payment object. In both cases, duplicate credit grants are skipped and recorded in a generated diagnostic report.
Shopify failed-order replay is included as a secondary example of failed webhook capture and local replay bookkeeping. It is not the primary offer or a full Shopify recovery system.
This repository uses synthetic sample data only. It does not use real API keys, call Stripe or Shopify APIs, process customer data, or claim production readiness.
- Same Stripe event ID duplicate detection.
- Different Stripe event ID for the same invoice/payment object.
- Skipped duplicate credit grants before account credits are incremented.
- Failed Shopify order payload capture as a secondary replay example.
- Local simulated replay for failed events.
- Subscription state desync detection from synthetic provider snapshots.
- A generated Markdown diagnostic report.
- Tests covering idempotency, replay updates, desync detection, and report generation.
This is not a SaaS product, gateway, monitoring platform, or full webhook system. It is a small proof-of-work CLI that makes the duplicate-side-effect boundary easy to inspect.
- Synthetic data only.
- No real Stripe or Shopify API calls.
- No secrets required.
- No production customer data.
- Local SQLite state only.
- Replay is simulated locally and does not send network requests.
This repo models duplicate Stripe delivery as a credit-ledger idempotency problem. A webhook retry must not imply a new credit operation.
Event ID dedupe is useful, but the balance mutation should also be protected by a credit operation identity around the actual credit grant. See docs/credit-ledger-boundary.md.
Stripe webhook
-> processed_event_identity
-> credit_operation_identity
-> credit ledger state
-> balance mutation once
Webhook delivery is not the business boundary; the balance mutation is the business boundary. Event ID dedupe helps, but credit operation identity protects the actual credit grant. This repo models that boundary locally with synthetic data.
The demo generates outputs/recovery_report.md, with a committed example at outputs/example_recovery_report.md. The report includes:
- Stripe duplicate credit findings.
- Account credit state.
- Shopify failed order recovery.
- Replay candidates and simulated replay results.
- Subscription desync findings.
- Acceptance criteria.
- Recommended fixes.
- No-live-API/no-secrets safety boundary.
Requires Python 3.11+.
python3 -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
pip install -e ".[dev]"webhook-rescue demoThe demo resets .webhook_rescue/webhook_rescue.db, ingests all sample files, replays one failed Shopify event locally, and writes:
outputs/recovery_report.md
webhook-rescue init
webhook-rescue ingest --file samples/stripe_duplicate_events.json
webhook-rescue ingest --file samples/shopify_failed_orders.json
webhook-rescue ingest --file samples/subscription_desync.json
webhook-rescue inspect --event-id evt_test_invoice_001_b
webhook-rescue replay --event-id shopify_order_failed_timeout
webhook-rescue report --output outputs/recovery_report.mdAll commands use SQLite state. Tests pass temporary database paths with --db equivalents internally and do not depend on the default demo database.
Inspecting the Stripe object duplicate scenario after demo shows account credits of 100, even though the sample contains two different Stripe event IDs for the same invoice object:
Event evt_test_invoice_001_b
provider: stripe
type: invoice.paid
status: duplicate_object
failure_reason: Duplicate Stripe object event already processed for invoice.paid object invoice_demo_001; credit grant skipped.
account: cus_credit_demo_001 credits=100 local_subscription=unknown provider_subscription=unknown
- Production webhook signature verification.
- Real provider API integration.
- Real queue workers or background jobs.
- Alerting, dashboards, or incident management.
- Multi-tenant access controls.
- A complete production replay safety review.
The CLI is Python because it is a small local proof asset. Real buyer code may be Next.js, Express, Rails, Laravel, or another framework. See docs/framework-patch-examples.md for pseudocode showing where the credit-ledger boundary would sit.
The useful review surface is small: samples/ defines synthetic provider events, src/webhook_rescue/ingest.py contains duplicate detection, src/webhook_rescue/report.py renders the diagnostic report, and tests/ verifies the local behavior.
For neutral client scope notes, see docs/client-scope-notes.md. That document is background for webhook reliability review, not a claim that this repository is deployable production infrastructure.
python -m pytestThe test suite verifies persisted SQLite behavior for duplicate detection, credit double-count prevention, failed-event storage, replay updates, desync detection, and report generation.