Invoice statuses
| status | description | allowed transitions |
|---|---|---|
created | 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. | processing, expired, cancelled |
processing | An on-chain transaction was detected and is being checked. This may include confirmation checks, amount validation, and compliance screening. | paid, partially_paid, overpaid, suspended |
suspended | The transaction requires manual or automated review, usually because a compliance check did not pass immediately. | paid, partially_paid, overpaid, failed |
paid | The received amount is within the accepted tolerance of the expected crypto amount. | Final status |
partially_paid | The received amount is above the minimum deposit amount but below the expected amount minus tolerance. | Final status |
overpaid | The received amount is higher than the expected amount. | Final status |
expired | 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 4 hours after the deposit expired, the invoice is processed normally. | processing (late payment within 4 hours); otherwise final |
cancelled | The invoice was cancelled by the organization or client before completion. | Final status |
failed | The payment could not be completed, for example because of a network issue or failed compliance check. | Final status |
Integration notes
Section titled “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
Section titled “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→processingand then topaid,partially_paid,overpaid, orsuspendedthrough the normal flow. Aninvoice.statusChangedwebhook 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
processingor settled by another payment, and payments to acancelledinvoice. Contact [email protected] 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
Section titled “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
Section titled “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 [email protected] 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.