Personal project · SimulatedSole engineer2026
Cascade
A payments backend built around the failure cases. A timeout is not a decline.

The problem
Most payment bugs aren't in the happy path. They're in the timeout, the duplicate webhook and the retry that charges twice. Cascade is a rehearsal of a Laravel to .NET payments migration, built around exactly those cases.
What I built
- 01
A payment state machine (charges, partial and full refunds) with provider adapters behind one interface, including Stripe in test mode.
- 02
A provider timeout moves a payment to requires-verification instead of declining it. Each attempt is saved before the call and its id is the idempotency key, so a retry or reroute can't double-charge.
- 03
Shopify webhooks acknowledged inside Shopify's 5-second limit: HMAC-SHA256 checked over the raw body, deduplicated, and drained from a transactional inbox with FOR UPDATE SKIP LOCKED.
- 04
A scheduled GraphQL Admin API fetch recovers webhooks that never arrived.
- 05
Idempotency enforced by unique indexes, optimistic concurrency on Postgres xmin, and CHECK constraints that make over-refunds impossible even if application code is bypassed.
- 06
45 xUnit tests, including integration tests on a real PostgreSQL started by Testcontainers. Design choices recorded as Architecture Decision Records.
Honest limits
- A personal project on simulated data, not a client system.
- Still in progress: Adyen adapter with soft-decline routing, a double-entry ledger, a React dashboard, and shadow traffic against the legacy system.
Next project
VehicleWatch
Fleet fault detection with no labelled data. It learns what normal looks like.
Have something to build?
Tell me what you're working on. You'll hear back from me, not a sales team.
Asad Amad Sheikh
Full Stack Engineer · Islamabad, Pakistan
Available for new projects