STANDARDwalkthrough
Payment State Machine
Every payment flows through exactly 5 states: pending, authorized, captured, settled, failed. No backward transitions.
Because a status field allows illegal transitions: a developer could accidentally set a 'settled' transaction back to 'pending', creating an accounting nightmare. The state machine enforces valid transitions in application code: pending can only move to authorized or failed, authorized can only move to captured or failed (void), captured can only move to settled.
“Why a state machine instead of a simple status field?”
Each transition is recorded as an event in the ledger_entries table with a timestamp, so we have a complete audit trail. Stripe processes 250M API requests/day through this exact pattern.
The transition from authorized to captured must happen within 7 days (card network rule). A background job scans for authorized transactions older than 6 days and sends merchant warnings.
At day 7, it auto-voids the authorization. Why not combine authorize and capture into one step?
Because hotels, car rentals, and e-commerce pre-authorize at checkout and capture at fulfillment. Two-phase capture separates the guarantee from the money movement.
Trade-off: the state machine adds complexity to the codebase, but prevents invalid financial states that would require manual reconciliation.