ENGINEERING NOTE
Idempotency at the request and ledger boundaries
How the playground handles repeated requests without posting a synthetic transfer twice.
Reviewed 2026-09-22 · Codex — checked against repository implementation
The repeated-request problem
The payment playground accepts a fixed wallet-to-merchant transfer with an amount and an idempotency key. A repeated click should not become a second transfer. Its reducer keeps a key-to-payment mapping and returns the existing payment when the same key and amount arrive again.
A reused key with a different amount produces a conflict. Account and currency selection are absent from this simulation, so its payload comparison covers only the amount. This is an implementation walkthrough, not a claim about a production payment API.
Two separate duplicate checks
Request deduplication prevents another queue entry from being created. Processing also checks payment status: only a queued payment can post. Repeating a process command after posting is ignored. This second check protects the ledger even when work is delivered more than once.
Posting subtracts the amount from the wallet, adds it to the merchant, records equal debit and credit entries, and creates an outbox event within one reducer transition. The initial total of 10,000 synthetic units stays unchanged.
Balance can change while work waits
Two payments can both pass validation against the same starting balance. The reducer checks the balance again during processing. If the first posting leaves too little for the second, the second is rejected without ledger entries. Its accepted idempotency key still refers to that rejected payment.
What the tests establish
The engine tests replay identical command sequences and check balances against ledger entries after each transition. Duplicate requests and repeated jobs must leave exactly one posting per successful payment. These are deterministic in-memory checks; the demo does not implement a database transaction, durable queue or multi-process concurrency.
Implementation: src/lib/playground/engine.ts. Verification: tests/playground-engine.test.ts.
Related work
Related case studies provide additional context; this note does not claim they implement the simulation's behavior.