Finality per chain
When a payment on each chain is final enough to credit, and what happens if a chain reorganises.
A transfer that has just appeared in a block can still disappear: blocks get reorganised. An invoice is
only paid once its payment reaches the finality level its chain and amount require. Until then it is
detected or confirming. A pending (mempool) transfer never credits anything.
The levels
| Level | Meaning |
|---|---|
pending | Seen, not yet in a block. Never credits. |
included | In a block at the chain's head. |
safe | In a block the network considers very unlikely to be reorganised (the node's safe tag on EVM chains; 3 confirmations on Bitcoin). |
final | Cannot be reverted without breaking the chain's own rules (TRON solidified blocks, EVM finalized, 6 Bitcoin confirmations). |
What each chain needs
| Chain | Credited at | Typically |
|---|---|---|
| TRON (mainnet, Nile) | final (solidified) | about a minute (19 blocks) |
| BNB Smart Chain (mainnet, testnet) | final | seconds (fast finality) |
| Ethereum (mainnet, Sepolia) | safe under US$1,000, final from US$1,000 | about 6 min / 13–15 min |
| Base, Arbitrum One (and their Sepolia testnets) | safe under US$1,000, final from US$1,000 | Base: under a minute / about 16 min; Arbitrum: about 10 min / about 17 min |
| Polygon PoS (mainnet, Amoy) | final (milestones) | seconds |
| Solana (mainnet, devnet) | final (finalized) | about 13 seconds |
| Bitcoin | 1 confirmation under US$1,000, 3 under US$25,000, 6 from US$25,000 | 10 / 30 / 60 minutes |
A single payment worth US$250,000 or more is also held for a person to approve after it is final (see reviews).
The confirmations field
confirmations on an invoice is {"current": n, "required": m}. On Bitcoin these are real block
confirmations. On every other chain they count finality levels: 1 is included, 2 is safe, 3 is
final. Show it as progress ("confirming 1 of 3"), not as a block count.
Reorganisations
If a block holding a credited payment is reorganised away, the credit is reversed: you get
invoice.payment_reversed (with the payment, status: "reversed") and the invoice's status steps back,
followed by its status webhook. Waiting for invoice.paid (which is only sent at the required finality)
before you ship makes this very unlikely to matter. If a payment that was reported final is ever
retracted, the invoice is put under review rather than silently changed.