← All projects

02 / BACKEND & RELIABILITY

Webhook Guardian

A lost HTTP response should not activate the same payment twice.

TypeScriptNode.jsFastifySQLite
Explore the code
THE OBSERVABLE RESULT

The documented local demo delivers 100 events and verifies 10 business activations.

01 / CONTEXT

The problem.

Webhook senders retry. A receiver may commit a change, lose the response and receive the event again. Even different event IDs can refer to the same business operation.

02 / IMPLEMENTATION

The approach.

A mock payment receiver that authenticates exact request bytes, validates the payload and separates event identity from payment identity. A SQLite transaction commits the local effect and its completion record together.

01Signed event
02HMAC + schema
03Inbox + business key
04Atomic local commit

Simplified flow. Implementation details and boundaries are documented in the repository.

03 / TRADEOFFS

Decisions that matter.

01

Authenticate the original bytes

HMAC-SHA256 verification runs against the raw request body with timing-safe comparison and a bounded payload size.

02

Deduplicate at two levels

The persistent inbox handles event redelivery. A separate payment business key prevents repeated activation under a new event ID.

03

Commit the effect with its record

One SQLite transaction keeps the local activation and completion state consistent. The demo reopens the database after shutdown to verify persistence.

04 / EVIDENCE & BOUNDARIES

What was checked.

  • Invalid signatures and conflicting event-ID reuse
  • Rollback, restart persistence and controlled process death
  • Separate-process concurrency and SQLite writer locking
  • One-command demo with persisted-state assertions

Checks summarized from the project documentation. See the repository and CI for current details.

Scope of this reference project

Mock payment data and local SQLite effects only. No external payment provider integration and no guarantee for effects in external systems. Provider-specific adapters and production operations are separate work.

Run it locally

Follow the repository README for prerequisites and configuration before running:

npm ci
npm run demo
Read the setup instructions

WORKING ON A SIMILAR PROBLEM?

Let’s talk through it.

Discuss your project
NEXT PROJECTMCP Sentinel