StableOps
FAQ

A payment was confirmed but then reverted

Why a detected or confirmed order can roll back to reverted, and why you should fulfill on payment.finalized.

A payment can move backwards. An order that reached detected or confirmed can still roll back to reverted and emit a payment.reverted webhook. This is expected behavior, not a bug. It's the whole reason the state machine separates confirmed from finalized.

Why an order reverts

StableOps marks an order reverted when the transfer it matched is no longer valid:

  • Reorg: a competing chain became canonical and the block that contained the transfer was dropped. StableOps detects this by comparing the live receipt's block hash against the block hash stored when the event was first ingested; if they no longer match, the event is invalid.
  • Failed receipt: the transaction's receipt reports failure (for example a reverted contract call), so the transfer never actually moved funds.

Why confirmed is not safe to fulfill on

The stages mean different things:

  • detected: seen on-chain at 0 confirmations. Do not fulfill.
  • confirmed: enough confirmations that reversal is unlikely, but the chain's finality guarantee has not been reached. There is still residual reorg risk.
  • finalized: finality reached; the transfer cannot be reverted. This is the recommended point to release goods.

Fulfill on payment.finalized unless your product has explicitly accepted the remaining reorg risk of acting on payment.confirmed.

Handling payment.reverted

Treat it as the inverse of any optimistic handling you did earlier:

  • If you only updated UI on payment.detected / payment.confirmed, revert that UI and ask the customer to pay again or wait for re-confirmation.
  • If you released anything of value before finalized, this is the event that tells you to claw it back.
  • Process the event idempotently. A delivery may be retried, so applying it twice must be safe.

How is this guide?

Last updated

On this page