What Are Block Confirmations? When Is a Crypto Payment Final?
What are block confirmations and when is a crypto payment final? How TRON reaches finality in about a minute, and when to safely fulfil an order.

When a customer says "I've sent it," is the money actually yours? With crypto, the answer comes down to block confirmations. This article explains what block confirmations are, when a payment becomes final, and why MercanPay credits a payment after 20 confirmations, usually about a minute.
What are block confirmations?
A blockchain is a ledger made of blocks chained one after another. When a transaction is sent, it first spreads to nodes on the network and then gets included in a block. Once that block is on the chain, the transaction has 1 confirmation, and every block added on top of it adds one more.
The more confirmations a transaction has, the harder it is to reverse. Undoing it would mean rewriting that block and every block after it, which gets harder with each new block. In short:
- 0 confirmations: the network has seen the transaction, but it isn't in a block yet.
- 1 confirmation: it's in a block. It's probably permanent, but not yet certain.
- Enough confirmations: it's treated as irreversible, and you can act on it safely.
Why isn't one confirmation enough?
Networks occasionally see short-lived forks or reorganizations. If two blocks are produced at the same moment, the network settles on one of them shortly afterwards, and transactions on the losing branch can drop out. A merchant who ships after a single confirmation takes on a small but real risk that the payment disappears.
Digital goods are usually delivered instantly and can't be taken back, so that risk matters. That's why payment gateways set a confirmation threshold and only mark a payment as paid once it's crossed.
How finality works on TRON
TRON uses delegated proof of stake: elected block producers, called Super Representatives, take turns producing blocks roughly every 3 seconds. A block counts as solidified (final) once enough blocks have been built on top of it, implicitly endorsed by a large majority of producers.
MercanPay builds on this and credits a payment after 20 block confirmations. With 3-second blocks, that's usually about one minute, which is safe and still short enough that the customer isn't left waiting.
Confirmation times compared
| Network | Average block time | In practice |
|---|---|---|
| Bitcoin | About 10 minutes | Waiting for a few confirmations can take tens of minutes or more |
| TRON | About 3 seconds | 20 confirmations usually take about 1 minute |
These are averages and vary with network conditions, but the gap is clear. On TRON, safe finality takes seconds, not tens of minutes, which makes TRC20 a practical option for online checkout. For more on networks, see USDT on TRC20 vs ERC20 vs BEP20.
What the customer sees
The MercanPay payment page is built so customers always know where things stand:
- Awaiting payment: a QR code, address, amount and countdown.
- Payment detected · confirming: shown as soon as the transfer appears on-chain, so the customer knows it arrived and doesn't send it again.
- Paid: once 20 confirmations are in, the invoice is paid, and if you set a
success_url, the customer is redirected back to your store.
That in-between state does a lot for conversion. "I sent it and nothing happened" is a major source of support tickets and duplicate payments. More tips in crypto checkout conversion tips.
When should the merchant fulfil the order?
The rule is simple: fulfil the order from the signed webhook sent after the confirmation threshold. Once 20 confirmations are complete, MercanPay sends invoice.paid to your server, or invoice.overpaid if the customer paid more. Don't ship when a payment is merely detected. And don't rely on the customer's browser landing on your success_url, because redirects can be faked.
from mercanpay import verify_webhook
@app.post("/mercanpay/webhook")
def webhook():
body = request.get_data()
if not verify_webhook(WEBHOOK_SECRET, body, request.headers.get("X-MercanPay-Signature", "")):
abort(401)
event = request.get_json()
if event["type"] in ("invoice.paid", "invoice.overpaid"):
# 20 confirmations done: safe to deliver
fulfil(event["data"]["invoice"]["order_id"])
return "", 200
See verifying webhook signatures for the details, and the Python integration guide for the full setup.
To look up a transaction yourself, GET /v1/chain/transactions/{txid} returns its status. In the Python library that's zp.transaction_status(txid), and in PHP it's $zp->transactionStatus($txid).
Compared with card payments
Card payments make the contrast clear. A card "approval" is really an authorization: the money can take days to settle, and the customer can open a chargeback months later. Crypto works the other way round: there's a short wait, but once the threshold is crossed the payment is final and can't be reversed unilaterally.
| Card payment | TRC20 crypto payment | |
|---|---|---|
| First signal | Instant authorization | "Payment detected" within seconds |
| Finality | Days; chargeback risk lasts months | 20 confirmations, usually about 1 minute |
| Reversible? | Yes, via chargeback | Not unilaterally |
A short confirmation wait buys much more predictable cash flow. For the bigger picture, see what a crypto payment gateway is.
Edge cases during confirmation
- The customer sent too little: the invoice moves to
partial, the payment page shows the remainder, and the invoice gets at least 30 more minutes. - The payment confirmed after the invoice expired: late payments are still credited to your balance, and
data.payment.latein the webhook flags them. - The customer used the wrong network: the transfer isn't on TRON, so it never shows up at the payment address. See crypto sent to the wrong network.
All of these are covered in underpayments, overpayments and late payments.
FAQ
Why does confirmation take about a minute rather than being instant?
For safety. A payment is only treated as irreversible after 20 block confirmations, which on TRON usually takes about a minute.
Can I ship as soon as I see "payment detected"?
It's not recommended. A detected payment isn't final yet. Wait for the invoice.paid webhook.
Can I change the number of confirmations?
The threshold is 20 blocks platform-wide and isn't configurable per merchant.
Can a confirmed payment be reversed?
A final blockchain transfer can't be reversed unilaterally. There is no chargeback mechanism in crypto the way there is with cards.
Get started with MercanPay
Accept USDT and TRX payments that are final in about a minute and visible to the customer the moment they're detected. Apply and create your first invoice: open a merchant account. Technical details are in the documentation.


