Skip to content

For developers

Why "detected" is not "paid": block reorganisations explained

What a blockchain reorg is, why a detected crypto payment is not paid yet, and what CryptoLike does when its block is dropped: statuses, ledger and webhooks.

Key takeaways

  • A reorg replaces the newest blocks of a chain, so a transfer you have already seen can vanish or move to another block.
  • CryptoLike keeps a detected transfer in your pending balance and credits it only at the asset's confirmation threshold; a reorg below the threshold never touches your available balance.
  • A transfer dropped before the threshold sends the payment back to its previous status without an invoice webhook; a confirmed transfer that is dropped is reversed in the ledger and announced with invoice.reverted or deposit.reverted.
  • Ship on paid, stop on reverted, and apply each webhook once by event_id. A transfer that is mined again brings invoice.paid while the invoice is open, or invoice.late_payment once it has expired.

A block reorganisation, or reorg, happens when a blockchain replaces its newest blocks with a different branch. A transfer you have already seen in a block can then disappear or land in another block. That is why CryptoLike calls a payment pending when the transfer is detected and paid only after the asset's confirmations. This article explains the mechanics, what CryptoLike does when a block with your payment is dropped before or after that point, and how to write an integration that stays correct when it happens.

What is a blockchain reorg?

A reorg is the network switching from the branch it was following to a competing one and dropping one or more of the newest blocks. A transfer from a dropped block may be included again in the new branch, often at another height, or never, for example when the new branch holds a conflicting transaction that spends the same coins.

Competing branches exist because blocks come from many independent participants. On Bitcoin and Litecoin two miners can find a block at almost the same moment, and nodes follow the one they saw first until one branch grows longer. Ethereum and TRON produce blocks on a schedule, but their newest blocks can also be replaced until the network treats them as final. On every network, the deeper a block sits, the less likely it is to be replaced. The short definition is in the glossary entry on the reorg.

Why is "detected" not "paid"?

"Detected" means CryptoLike has seen the transfer in a block. "Paid" means the transfer reached the asset's confirmation threshold and the funds are on your balance. Between the two, a reorg can still remove the transfer, so CryptoLike keeps the stages apart everywhere you look.

Stage Payment status The payer sees Webhook Your balance
Transfer seen in a block pending "Payment detected. Waiting for confirmation." invoice.pending or deposit.pending Full amount in pending; it cannot be paid out
Threshold reached paid (or underpaid if the amount is short) "Payment confirmed." invoice.paid or deposit.confirmed Amount minus the platform fee in available
A confirmed transfer was dropped Recomputed: paid, underpaid, pending or new The page updates by itself invoice.reverted or deposit.reverted Credit and fee reversed

CryptoLike does not read transfers waiting outside blocks, so pending already means "in a block". The checkout page also shows detected_amount, the sum of transfers seen but not yet confirmed, and the API docs state it plainly: it is not credited, and a reorg may drop it. How many confirmations each asset needs, and why the numbers differ between networks, is covered in how many confirmations a crypto payment needs; the current values are in GET /v1/currencies and on the coins pages, for example Bitcoin.

How does CryptoLike notice a reorg?

CryptoLike reads every network block by block and checks that each new block points to the hash of the block it read before. When the parent hash does not match, the chain it was following has been replaced, and CryptoLike walks back to the last block both branches share.

From there the steps are fixed:

  1. Every transfer to your addresses in the blocks above the common block is marked as orphaned, and an event about it is published for the ledger.
  2. CryptoLike reads the new branch from the common block onwards, one block at a time.
  3. A transfer that appears again in the new branch is detected anew and counts its confirmations from its new block; recipient and amount are taken from the new block.
  4. Records that look confirmed are checked against the stored chain of block headers before they are counted, so a confirmation from a replaced block is not trusted.

There is a limit to what is handled automatically. CryptoLike keeps a window of recent blocks on each network: twice the strictest confirmation threshold among its assets, and at least 8 blocks. A reorg deeper than that window stops processing on that network until CryptoLike's team checks it: nothing is credited or reversed from a branch that cannot be verified. Payments on that network wait meanwhile; those whose time to pay runs out are closed as expired, as usual.

What happens to a payment when its block is dropped?

What CryptoLike does depends on how far the payment got before the block was dropped. The rule is the same on all four networks — Bitcoin, Litecoin, Ethereum and TRON; only the confirmation threshold differs per asset.

Situation Status Ledger Webhook
Invoice, transfer still below the threshold Back to new, or stays pending if another transfer to the address is still waiting Amount removed from pending None; the payment history in the cabinet records it
Invoice that was paid or underpaid, confirmed transfer dropped Recomputed from what is still confirmed: paid, underpaid, pending or new Confirmation, fee and credit reversed invoice.reverted with the new paid_amount and remaining_amount
Static address, any stage The transfer shows as Reverted in Transactions Whatever was posted is reversed deposit.reverted; confirmed_reversed: true if the amount had already been available
Transfer included again in the new branch Open invoice: pending, then paid at the threshold. If the invoice's time runs out first, it closes as expired and stays there Credited again Open invoice: invoice.paid; expired invoice: invoice.late_payment; static address: deposit.confirmed. Each with a new event_id
Confirmed amount already paid out Invoice status unchanged until reviewed No automatic reversal; your balance is never pushed below zero None; CryptoLike's team reviews the case

Two details are worth knowing. If only a surplus is dropped and the invoice stays paid, no invoice.reverted is sent: nothing you acted on has changed. And on a closed invoice — expired or cancelled — a dropped late payment that had been confirmed still produces invoice.reverted, while the status stays where it was.

What does the ledger record?

The ledger never edits or deletes an entry; a reorg is booked as new reversal entries that mirror the original ones. CryptoLike reverses in the opposite order of crediting: first the confirmation (available back to pending, the platform fee returned), then the credit itself (pending back to outside the platform).

This keeps the books provable. Every posting balances, the credit and its reversal stay side by side with a reference to the same transfer, and the account still satisfies "credited − reversed − paid out − balance = 0". If the transfer is included again, it is credited under the next generation of the same key, so a repeated old event cannot credit it twice.

The one case the ledger refuses to handle on its own is a reversal of money that is no longer there because it was paid out. CryptoLike does not create a negative balance or a hidden debt; the transfer is marked as dropped and CryptoLike's team settles the case by hand.

How should your integration handle reorgs?

Treat every webhook as a statement of the current state, not as a one-way step. When a dropped transfer is included again, an invoice that is still open goes paid → reverted → paid. Often its time is over by then: the confirmations start again from the new block, and the default invoice lifetime is 30 minutes. The invoice then closes as expired, and the returning money is credited and announced as invoice.late_payment. Your code should follow both paths without manual help.

  • Fulfil on paid, not on pending. invoice.pending is a progress signal. If the transfer is dropped before the threshold, no further invoice webhook says so — the payment may simply return to new and later expire.
  • Handle invoice.reverted. If the order has not shipped, keep it waiting. If it has, mark it for review. The CMS plugins do exactly this: a reverted paid order moves to a review status. If invoice.late_payment follows, the money is on your balance again while the status stays expired: ship the order or refund the customer.
  • Apply each event once by event_id. Deliveries are at least once and in no fixed order; store the event_id, skip repeats, and compare created_at rather than arrival order. The idempotency article shows the pattern in code.
  • Verify the signature first. A forged invoice.paid is worse than a reorg; see how to verify crypto payment webhooks.
  • Trust the amounts in the event, not your own sums. Every invoice event carries the whole payment with paid_amount and remaining_amount as they are now. On Ethereum the position of a token transfer inside a block can change when it is mined again, so a key you build from txid and output_index may not match the new sighting.
  • When in doubt, ask the API. GET /v1/invoices/{id} returns the current status and amounts.

If you are still comparing providers, how a gateway handles reorgs is a fair question to ask — it is one of the points in how to choose a crypto payment gateway.

How to build reorg handling into your integration

Reorg handling needs no separate setup in CryptoLike: the statuses and webhooks above come with every payment and static address. Your part is the webhook handler.

  1. In the cabinet, open Webhooks, add an endpoint and subscribe to invoice.paid, invoice.reverted, invoice.late_payment, deposit.confirmed and deposit.reverted, or to all events (*).
  2. Make the handler verify the signature, store event_id, and map invoice.paid to "ready to ship" and invoice.reverted to "hold".
  3. Check the flow on test networks with a test key — the guide to testing crypto payments lists the steps — and keep the event list from the webhooks reference at hand.

FAQ

What is a reorg in a blockchain?

A reorg is the network replacing its newest blocks with a competing branch. Transfers in the dropped blocks can disappear or be included again in a later block. The deeper a block is, the less likely it is to be replaced, which is why payments wait for a number of confirmations before they count.

Can a paid crypto payment be reversed?

On the network's side, only when a reorg drops the block of a confirmed transfer. CryptoLike then reverses the credit in the ledger, recomputes the payment and sends invoice.reverted (or deposit.reverted for a static address). If the transfer is included again while the invoice is open, a new invoice.paid follows; if the invoice has expired meanwhile, its status stays expired and you receive invoice.late_payment instead. Stop fulfilment on reverted and decide again on whichever of the two arrives.

Do I get a webhook if a pending payment disappears?

For an invoice, no. A transfer dropped before the threshold was never credited, so the payment quietly returns to new (or stays pending if another transfer is waiting) and the event is recorded in its history. For a static address you receive deposit.reverted at any stage.

What if I already paid out the money from a reverted payment?

The ledger does not push your balance below zero or create a debt on its own. The transfer is marked as dropped and the case goes to CryptoLike's team, who settle it with you. It takes a reorg deeper than the asset's threshold, and the threshold is set so that such a reorg is not a practical risk.

Does CryptoLike handle reorgs the same way on every network?

Yes. Bitcoin, Litecoin, Ethereum and TRON use the same block-by-block check and the same statuses, ledger reversals and webhooks. What differs is the confirmation threshold of each asset, published in GET /v1/currencies, because networks differ in block interval and in how blocks become final.

Terms used here

Read next

Start with a test payment

Create an account, ask support for the test environment and see a payment go from pending to paid on a test network.