A checkout interface wants two answers: paid or unpaid. A distributed network does not provide such a clean binary. A transaction can be signed but never included, included but reverted, visible in a block that is later reorganized, or technically final while still mismatched with the order and the merchant ledger. A reliable payment product separates technical observation, risk acceptance, accounting credit and financial reconciliation.
The thesis in brief
- A transaction hash is an observation identifier, not commercial approval.
- Finality policy should vary by network, value and fulfilment type.
- Provisional credit is a measurable credit decision, not an engineering shortcut.
- Reconciliation joins the intent, chain evidence, ledger and treasury balances.
1. Separate four kinds of truth
The payment intent describes the commercial obligation: payer, amount, asset, network, expiry and order. The transaction describes an attempted execution. The receipt and logs describe what the network executed. The internal ledger describes who the business owes. These objects are linked, but none can replace another.
Dor Arad’s product rule is that every decision should disclose which truth supports it. A success screen may acknowledge broadcast without promising settlement. A webhook may report observed without making funds withdrawable. Giving each state exactly one meaning removes ambiguity from support, risk and finance.
2. Build a replayable state machine
A useful path includes created, quoted, submitted, observed, confirming, accepted, settled, exception and refunded. Every transition is appended with a timestamp, policy version and reason. Idempotency keys ensure that replaying an observation never credits a merchant twice.
Moving from submitted to observed requires more than finding a hash. Validate chain ID, approved token contract, successful receipt, relevant transfer or application event, destination and amount. With smart accounts, routers and batches, the outer from and to fields are not enough; the economic effect must be decoded.
- Store block number and block hash.
- Bind each observation to one payment intent.
- Route underpayment, overpayment and wrong assets to exceptions.
- Emit webhooks from the state machine, not directly from RPC callbacks.
3. Finality is policy, not a magic number
One confirmation does not carry the same assurance everywhere. Proof-of-stake systems distinguish inclusion, confirmations and protocol finality. L2 systems may add sequencer health and the path by which data or proofs reach L1. A supported-network registry therefore needs a finality adapter, not merely an RPC URL.
Policy should consider value, asset, network and whether fulfilment is reversible. Low-value digital access may be granted at accepted, while expensive goods or outbound withdrawals wait for settled. Store the policy version on the payment so later configuration changes do not erase the reason two similar payments were treated differently.
4. Provisional credit is a credit product
When a merchant can spend funds before finality, the platform temporarily bears the risk. That can be a sound choice, but it should be named accurately: credit against an unsettled payment. Define limits, eligible merchants, permitted assets and networks, and real-time exposure.
Separate pending, available and reserved balances. If a reorganization or final failure occurs, do not delete history. Post a reversal and route the payment to an exception workflow. The merchant and finance team then see an intelligible sequence instead of a status that simply disappears.
5. The internal ledger remains the business source of truth
A blockchain proves asset movements; it does not know the order price, promised fee, gas allocation, merchant ownership or refund obligation. A double-entry ledger translates network events into rights and liabilities. Every posting must balance, identify its currency and asset, and link to evidence.
Do not confuse an on-chain balance with a customer balance. One custody address may represent thousands of payment intents, while a deposit address can receive several transfers. Allocation is the result of attribution rules, not balanceOf alone. This is where a wallet interface becomes a financial system.
6. Reconciliation is the control loop
Reconciliation compares four layers: expected intents, decoded chain events, ledger postings and actual custody balances. Run it continuously and at each reporting close. Missing value, an unsupported token, a posting without evidence or a treasury mismatch becomes an owned exception with an SLA.
Restarting an indexer is not enough. A rebuild from the same block height should produce the same result, and the system should detect forks or decoder changes. Daily snapshots, checkpoints and decoder versions make the result reproducible. Ageing reports prevent pending money from becoming invisible operational debt.
7. Multichain design needs one contract and different adapters
A common API can expose observed, accepted and settled across networks, while each adapter handles chain identifiers, token allowlists, decoding, finality signals, reorganizations and health. A policy layer above the adapters decides when value may be released.
Before enabling a network, test both the happy path and disruption: lagging RPC, replaced blocks, temporarily missing receipts, lookalike tokens, incorrect decimals and duplicate webhook delivery. Network support is complete only when finance can reconcile it and support can explain it.
8. Metrics that join product, risk and money
Measure submit-to-observed time, observed-to-settled time, exception rate, reorganizations, pending value by age, reconciliation breaks and outstanding provisional credit. Pair them with conversion and abandonment so safety does not become unexplained friction.
The goal is not to show a green check as quickly as possible. It is to make the correct promise at each moment. When status, ledger and money advance through the same state machine, the product can add networks without losing the ability to explain every balance and decision.
Sources and further reading
This article relies on primary protocol and developer documentation. Finality timings and service policies change and must be verified before implementation.
- Ethereum — Proof-of-stake and finalityProtocol documentation
- Circle — Block confirmation and finalityDeveloper documentation
- EIP-20 — ERC-20 Token Standard19 November 2015
- OpenZeppelin — Relayer documentationDeveloper documentation
A stablecoin payment is a chain of decisions, not one event. Define those decisions explicitly and the product can feel fast, keep accurate books and expand without turning every exception into a manual crisis.
