TigerBeetle Two-Phase Reservation
Authorize now, capture later, auto-void on expiry, built on TigerBeetle's pending transfers. The payer account carries AccountFlags.debits_must_not_exceed_credits, so the cluster refuses an overdraw with exceeds_credits instead of the application losing the gap between if (balance >= amount) and the write, and because the invariant counts debits_pending a hold is unspendable rather than a row someone has to remember to subtract. Transfer.timeout releases a forgotten hold with no sweeper cron and no compensating refund, and the classifiers fold a retried capture (exists, or pending_transfer_already_posted from a fresh id) into already-applied so the retry that follows a network timeout does not refund a customer who was correctly charged. Pinned to tigerbeetle-node 0.17.9.
npx shadcn@latest add https://ui.aryank.space/r/tigerbeetle-two-phase-reservation.jsonInstalls from ui.aryank.space. To add it by hand, copy the files in Files below, or register the @compronents namespace via the docs.
Two checkouts for $60.00 arrive against a $100.00 wallet. Both read the balance, both see enough, and both write. The application checked, so nobody is at fault, and the wallet lands at -$20.00. Watch the odometer flash red: that second debit should never have landed.