A modular commerce backend that records checkout progress and defines how unfinished work is reversed.
This headless commerce case study covers a backend where checkout reaches across three parts of the system. Those are the order service, the inventory service and an outside provider. We joined them through recorded workflows. A failed step then gets a defined response that can reverse work which already finished.
Store and administration APIs expose the backend, and staff inspect orders and workflow runs in a dashboard. The storefront runs as a separate application.
The challenge
An error response does not release reserved stock by itself. A failed request does not even prove that checkout failed, because another attempt may already have created the order. Recovery therefore reads the current state before it undoes earlier work. Payment calls add one more limit. They cannot share the database transaction that the local records use.
What we built
Cart completion locks the cart and checks its order link first, and when an order is already linked, that order answers the repeated request. If none is linked, the workflow validates the cart and creates the order. It reserves stock, then records promotion usage before authorisation.
A further customer check returns the cart with an error the storefront can handle. Provider notifications can also complete the checkout after the shopper has already left. Delays and retries keep that path in order.
Inventory holds reservations apart from physical quantities. A fulfilment reduces the physical count. Later edits, returns and exchanges keep their order-change records and the earlier versions.
Undo only the work that should be undone
Workflow steps can define compensation actions. When a later step fails, the right compensations run in reverse order to release a reservation, cancel an authorisation or refund a capture.
Before it reverses a captured payment, recovery checks whether another attempt has placed the order. A later success must not be undone just because the earlier attempt failed.
Commit before calling the provider
A capture first locks the payment row, then reloads the previous captures and checks the amount that is still due. It writes a capture record, then commits that record before it calls the provider. The committed record gives repeated calls a stable identity to reuse, and a failed provider call simply removes the capture record it wrote.
This avoids holding the database lock during a network call. Checkout still has to reconcile the authorised amount against the cart total.
Products and payments own their own services and models, and so do orders and inventory. Workflows coordinate the operations that run across them. Several application servers need shared locking, events and workflow runners, such as the Redis-backed options.
Project success
Operators can see how far a checkout got and which reversal actions ran for a failed step. A repeat request can find the order already placed. Reservations and order versions hold the detail that fulfilment and later changes rely on. Recovery becomes part of the checkout workflow, not an error message left for someone to read.
Technology stack
Backend
TypeScript, Node.js, Express
Data access
MikroORM, PostgreSQL
Dependency injection
Awilix
Administration
React, Vite
Shared infrastructure options
Redis-backed workflows, events, cache and locks
Other engagements
Recognize the pattern?
If one of these looks like your situation, the discovery call is where we find out how close.