A transaction is a state machine, not one HTTP call
A banking transaction moves through distinct states: captured intent, validation, authorization, posting, external processing when applicable, reconciliation, and final customer-visible outcome. Compressing these into a boolean success flag hides uncertainty and makes retries, approvals, reversals, and incident handling unsafe.
Separate channel status from financial posting status
- Use explicit states with allowed transitions and a reason/code for rejection.
- Authorization is different from posting; approval can succeed before a downstream financial action finishes.
- Pending must describe what the system is waiting for, not act as a catch-all.
- Reversal is a new controlled transaction linked to the original, not deletion of history.
- Every externally visible state change should have audit and correlation evidence.
Lifecycle from intent to finality
The transaction advances only through allowed state transitions; ambiguous external outcomes pause for reconciliation rather than inventing success or failure.
Financial transaction lifecycle
The transaction advances only through allowed state transitions; ambiguous external outcomes pause for reconciliation rather than inventing success or failure.
What “pending” should mean
Lifecycle bugs that confuse customers and operations
Transaction-state checklist
- Draw the state machine and allowed transitions.
- Name the owner of each state transition.
- Separate approval, posting, and settlement states where required.
- Define unknown/reconciliation behavior.
- Keep original, reversal, and return references linked immutably.
