A transaction is a unit of work. A payment is a workflow. The distinction changes everything about how systems must be designed.
Most teams building payment systems treat them as transactions. Submit a request, execute atomically, return success or failure. This model works fine when everything is synchronous and local. It breaks completely in distributed systems where latency is measured in minutes or longer.
A payment exists in multiple states, each with different operational semantics. Pending state occurs when a request has arrived but settlement has not begun. Confirmed state occurs when settlement has been submitted to the blockchain or settlement network. Settled state occurs when the transaction is included in a block and has achieved consensus. Final state occurs when sufficient confirmations are reached to make reversal economically irrational. Each state allows different actions. Each has different rollback semantics and recovery options. The system must track these states precisely or silent failures and ghost balances emerge.
Payment State Transitions
A payment begins in Pending state. A request has arrived, but settlement has not begun. The payment can be cancelled or resubmitted with different parameters. The money has not moved.
From Pending, the payment transitions to Confirmed. The settlement has been submitted to the blockchain or settlement network. The transaction is in flight. At this point, the payment cannot be resubmitted but can potentially be accelerated or cancelled (if the protocol supports replacement).
From Confirmed, the payment transitions to Settled. The transaction is included in a block. The state change is visible on the blockchain. The transaction has consensus backing.
From Settled, the payment transitions to Final. The transaction has accumulated enough block confirmations or economic finality to make reversal economically irrational. On Ethereum, this is typically 12 to 15 blocks. On Bitcoin, it is 6 blocks.
Each transition is irreversible. Once Settled, a payment should never return to Confirmed.
Rollback Semantics and Race Conditions
In Pending state, the payment has no external effects. Rollback is instantaneous. Set the payment status to Cancelled and return.
In Confirmed state, rollback depends on the underlying protocol. On blockchains that support transaction replacement (Ethereum, Bitcoin with RBF), a higher-fee transaction can be broadcast to replace the original.
In Settled state, the transaction is permanent on the ledger. Rollback requires a reverse transaction. If the original payment transferred 100 USDC from A to B, rollback requires a second transaction transferring 100 USDC from B back to A. This is no longer a simple rollback but a separate operation with its own settlement risk.
In Final state, rollback is not available at the smart contract level. Reversal requires governance intervention or legal action.
When the system is unclear about which state a payment is in, ghost balances appear. A client submits a payment. The settlement engine confirms the request and returns a transaction ID. The network fails before the client receives the response. The client retries. The settlement engine executes the payment a second time. The client is now uncertain whether one or two payments were executed.
This is why idempotent keys matter at the state level. Each state transition must be idempotent.
Event-Sourced Architecture
Payment systems that are not explicit about state machines experience undefined behavior at state boundaries. One common bug occurs when a payment times out in Confirmed state and is retried. The original transaction eventually settles. The retry also settles. The payment appears twice in the settled payment list.
These bugs are not logic errors in transaction processing. They are state machine errors. The code is correct for each state individually but wrong about which states can transition to which.
Explicit state machines prevent these bugs. A payment can only be in one state at a time. The transitions between states are defined in code. Any attempt to transition illegally is caught by the state machine.
In an event-sourced system, the source of truth is not the payment record itself but the sequence of events that created it. Each payment operation is an event (PaymentRequested, PaymentConfirmed, PaymentSettled, PaymentFinalized). Events are immutable.
A payment that succeeds follows this sequence through multiple events. PaymentRequested records sender, recipient, amount, and idempotent key. PaymentConfirmed records transaction ID. PaymentSettled records block hash and confirmation count. PaymentFinalized marks completion.
A payment that fails follows this sequence. PaymentRequested occurs first. PaymentConfirmed occurs when the settlement is submitted. PaymentFailed is recorded with reason such as insufficient balance or nonce mismatch.
A payment that is rolled back and retried follows this sequence. PaymentRequested occurs first. PaymentConfirmed is recorded with transaction ID 1. PaymentSettled is recorded with block hash and 5 confirmations. PaymentRolledBack marks the reorganization event. PaymentConfirmed occurs again with transaction ID 2. PaymentSettled is recorded with block hash 2. PaymentFinalized marks completion.
State machines and event sourcing are not new patterns. They are proven approaches in payment systems used by major payment processors and blockchain infrastructure companies. The cost of implementing them is far lower than the cost of debugging state transition bugs in production. A single silent failure that results in incorrect balances can take weeks to investigate, remediate, and reconcile. The operational cost of such failures dwarfs the engineering cost of implementing explicit state machines upfront.