# Invoice statuses

> Invoice statuses describe where an invoice is in the payment flow, from creation to final settlement.

<table><thead><tr><th width="210">status</th><th width="226">description</th><th>allowed transitions</th></tr></thead><tbody><tr><td><code>created</code></td><td>The invoice has been created. This covers both "no payment currency selected yet" and "a currency was selected and deposit details were generated; waiting for an on-chain transaction" - both are surfaced to merchants as `created`.</td><td><code>processing</code>, <code>expired</code>, <code>cancelled</code></td></tr><tr><td><code>processing</code></td><td>An on-chain transaction was detected and is being checked. This may include confirmation checks, amount validation, and compliance screening.</td><td><code>paid</code>, <code>partially_paid</code>, <code>overpaid</code>, <code>suspended</code></td></tr><tr><td><code>suspended</code></td><td>The transaction requires manual or automated review, usually because a compliance check did not pass immediately.</td><td><code>paid</code>, <code>partially_paid</code>, <code>overpaid</code>, <code>failed</code></td></tr><tr><td><code>paid</code></td><td>The received amount is within the accepted tolerance of the expected crypto amount.</td><td><em>Final status</em></td></tr><tr><td><code>partially_paid</code></td><td>The received amount is above the minimum deposit amount but below the expected amount minus tolerance.</td><td><em>Final status</em></td></tr><tr><td><code>overpaid</code></td><td>The received amount is higher than the expected amount.</td><td><em>Final status</em></td></tr><tr><td><code>expired</code></td><td>The invoice expired before a valid payment was detected. If the customer had already selected a currency and a payment still arrives at that deposit address within <strong>4 hours</strong> after the deposit expired, the invoice is processed normally.</td><td><code>processing</code> (late payment within 4 hours); otherwise final</td></tr><tr><td><code>cancelled</code></td><td>The invoice was cancelled by the organization or client before completion.</td><td><em>Final status</em></td></tr><tr><td><code>failed</code></td><td>The payment could not be completed, for example because of a network issue or failed compliance check.</td><td><em>Final status</em></td></tr></tbody></table>

## Integration notes

Treat `paid`, `partially_paid`, and `overpaid` as payment-received statuses. Your business logic should decide whether `partially_paid` or `overpaid` are acceptable for fulfilment.

Treat `cancelled` and `failed` as unsuccessful final statuses. Treat `expired` as unsuccessful, but don't assume it is final until the late-payment window has passed (see below).

## Late payments

Each payment attempt on an invoice gets its own deposit address, so a payment that arrives late can still be matched to the invoice:

* **After expiry.** If a payment reaches the invoice's deposit address within **4 hours** after that deposit expired, the invoice moves `expired` → `processing` and then to `paid`, `partially_paid`, `overpaid`, or `suspended` through the normal flow. An `invoice.statusChanged` webhook is sent for each transition, as usual.
* **After a currency switch.** If the customer switched to another currency on the payment page but still paid the address shown for the first currency within **4 hours**, that payment settles the invoice. The amount is evaluated against the amount locked for that first currency. If the deposit for the newer currency hasn't been paid yet, it is cancelled.
* **Not credited automatically:** payments after the 4-hour window, payments to an invoice that is already `processing` or settled by another payment, and payments to a `cancelled` invoice. Contact **support@cryptonly.net** with the invoice ID and transaction hash.

Your fulfilment logic should react to `paid`, `partially_paid`, and `overpaid` even if it has already received an `expired` webhook for the same invoice.

## Merchant return URLs

Optional `returnUrl`, `successUrl`, and `failedUrl` on invoice creation control a browser **"Return to merchant"** CTA on the hosted payment pages (invoice and linked deposit). These are not webhooks and not automatic redirects.

| Field | Shown when invoice status is |
|---|---|
| `returnUrl` | `cancelled`, `expired` |
| `successUrl` | `paid`, `overpaid` |
| `failedUrl` | `failed`, `suspended`, `partially_paid` |

No CTA is shown while the invoice is `created` or `processing`. The CTA always follows the current status: if an `expired` invoice receives a late payment, the `returnUrl` CTA is replaced by the one for the new status.

Note: `partially_paid` is still a payment-received status for fulfilment logic (see above), but the hosted CTA uses `failedUrl` so merchants can send payers to a recovery or contact flow.

Default invoice expiry is **24 hours** from creation unless you pass `expiresInMinutes` on `POST /invoice`.

An invoice stays `created` even after the customer selects a payment currency (and if they change their mind and pick a different currency); it only moves on once an on-chain transaction is detected. You will not receive repeated `created` webhooks for this.

### If an invoice is `suspended`

`suspended` means the on-chain transaction is held for compliance review — this is not a final outcome. While the review is open, the funds stay on the invoice's deposit address. There is no merchant-facing action to speed this up or check review progress; Cryptonly's compliance team resolves the review, after which the invoice automatically moves on to `paid`, `partially_paid`, `overpaid`, or `failed`, each firing a normal `invoice.statusChanged` webhook. Review time varies with case complexity — don't assume a fixed SLA. Contact **support@cryptonly.net** if a review appears stuck. While `suspended`, the hosted payment page may show the `failedUrl` CTA if you provided one.

Always use webhooks as the source of truth for status changes. Polling can be used as a fallback.

## Related pages

- [Processing lifecycle](https://docs.cryptonly.net/guides/invoices/processing-lifecycle.md): How an invoice moves through these statuses
- [Invoices](https://docs.cryptonly.net/guides/invoices.md): Creating a fiat-priced payment
- [Webhooks](https://docs.cryptonly.net/api-reference/webhooks.md): invoice.statusChanged is the source of truth
- [Deposit statuses](https://docs.cryptonly.net/guides/deposits/statuses.md): Invoice-linked deposits follow the invoice instead
