Payment lifecycle
Know when a payment is observed, accepted, fulfilled, refunded, or reversed.
A resource status describes the business operation. A webhook reports a fact that happened to it. Events can arrive out of order, and a blockchain reversal can invalidate an earlier completion.
Invoice lifecycle#
| Stage | Status or event | What your application does |
|---|---|---|
| Invoice created | pending, invoice.created | Save invoice/order mapping; no funds accepted yet |
| Checkout activated | pending, no activation event | Address, crypto amount, and deadline become available |
| Transfer first seen | invoice.detected | Show payment detected; wait for acceptance |
| Partial payment accepted | confirming, invoice.confirming | Update accepted-payment progress; do not fulfill yet |
| Confirmed payment still being processed | pending or confirming, no event | Wait; do not fulfill, and do not ask the customer to pay again |
| Threshold reached | paid or overpaid | Fetch the invoice and fulfill once |
| Invoice closes with accepted partial funds | underpaid, invoice.underpaid | Apply your incomplete-payment policy; reconcile amount_paid from the invoice |
| Window ends without accepted funds | expired, invoice.expired | Close the unpaid order; still handle later events |
| Unaccepted observation disappears | invalid, invoice.invalid | Do not treat the observation as a credit |
| Payment cannot be accepted and nothing was accepted | rejected, invoice.rejected | Do not fulfill; the invoice is closed and keeps rejected even if money is accepted later |
| Payment accepted late | invoice.late_payment | Fetch current state; it may also produce a paid/overpaid event |
| Accepted payment reversed | invoice.payment_reversed | Reconcile the reduced accepted amount and current status; review fulfilled orders |
A paid invoice may meet a configured underpayment tolerance. Overpayment classification uses a tolerance above the requested amount; do not infer fulfillment using your own approximate amount comparison.
Payments that take longer#
A confirmed payment can take longer to be accepted. While it is being processed, the invoice keeps its current status: pending if nothing has been accepted yet, or confirming if part of the amount was. No separate status or event marks this wait, and no action is needed. Do not fulfill the order or ask the customer to pay again; fulfill only when the invoice is paid or overpaid.
The invoice does not expire while such a payment is in progress. The payment keeps the time it was first observed, so the extra processing time never makes it late. amount_paid counts only accepted payments; if other accepted payments reach the paid threshold first, the invoice becomes paid or overpaid as usual. A payment first observed on or after the deadline does not keep the invoice open; if it is accepted later, it is a late payment.
When processing ends, the payment is either accepted like any other timely payment, with invoice.confirming, invoice.paid, or invoice.overpaid, or it cannot be accepted:
| Accepted on the invoice before | Invoice closes as | Event |
|---|---|---|
| Nothing | rejected | invoice.rejected |
| Part of the amount | underpaid | invoice.underpaid |
If other timely payments for the invoice are still in progress, the invoice waits for them before it closes. When the last of them is accepted as the invoice closes underpaid, invoice.underpaid is the only event for that acceptance, so reconcile from the invoice. No reason is published.
rejected is final. A payment accepted on a rejected invoice later arrives as invoice.late_payment, and the status stays rejected even with automatic late completion enabled.
The invoice status set grows additively. rejected was added on 2026-10-08, together with the invoice.rejected event; see the changelog. A strict enum parser for invoice status, including the status inside webhook payloads, must accept it. Never fulfill an order on a status your integration does not recognize; GET the invoice and keep the order open.
Late payments and reversals#
With automatic completion enabled, a late payment can move an expired or invalid invoice to paid or overpaid and produce another event with a different ID. The two events can describe the same financial acceptance. A rejected invoice keeps its status.
A payment is late when it is first reliably observed on or after the deadline, or accepted against an already closed invoice. Confirmation delay alone does not make a timely observed payment late.
The first valid late payment uses a fresh pricing snapshot. The original invoice denomination stays unchanged, while the required crypto amount can change. The first accepted payment freezes pricing for the invoice; later parts inherit it. With automatic late completion enabled, the accepted total determines underpaid, paid, or overpaid. With it disabled, a closed invoice keeps expired, invalid, or underpaid, even though the funds are credited. Read amount_paid and payments[] and handle invoice.late_payment. The setting never triggers an automatic refund.
invoice.late_payment has late_payment_amount and per-payment gross/fee/net fields, but no cumulative amount_paid. Retrieve the invoice to obtain that total.
An accepted-payment reversal recalculates amount_paid and can change the invoice's status. The reversed amount is gross in the specified pair; it is not a complete net-ledger adjustment. If an order has already been fulfilled, handle the reversal as a separate business exception rather than silently fulfilling again.
Payout lifecycle#
Payouts progress through queued, processing, and confirming to completed or failed. A completed payout can later become reversed. Funds remain reserved while execution is unresolved. processing is not permission to resend with a new key.
Only terminal payout events are published: completed, failed, and reversed. The enum's cancelled value is retained for compatibility but is not produced for individual payouts.
Refund lifecycle#
Refund REST responses use pending, processing, confirming, completed, failed, and reversed. Internal review states remain processing in this API; the dashboard shows Needs review for unresolved returns. Creating one reserves funds; completion sends the refund; failure releases the reservation. Refunds are independent objects linked to a closed invoice with accepted funds, including expired, invalid, or underpaid after late acceptance. A completed refund that loses chain confirmation emits refund.reversed: the terminal accounting is mirrored and the reserve released, while delivery requires reconciliation. Never automatically replace a reversed or uncertain return. The dashboard also supports a manually confirmed full refund of all remaining invoice payments; see refunds.
Two kinds of deduplication#
Deduplicate deliveries by event id. Separately make fulfillment idempotent by invoice/order ID. Different event IDs do not necessarily mean different financial credits, and a duplicate delivery must not fulfill an order twice.
Use business-process examples to wire these decisions into your receiver.
Standalone manual conversion#
Live-only conversions move from pending_execution (with submitted during execution) to settled, failed, or source_restored. stuck requires review. A failed conversion remains recoverable: it may later settle or restore source. Avoid creating a replacement while its outcome is unresolved.
conversion.completed, conversion.failed, and conversion.source_restored describe committed conversion outcomes. Read conversions for booked amounts, refusal before debit, and the distinction between conversion IDs and financial operation IDs.