Client Webhooks
Real-time invoice lifecycle events for your integrations.
Invoice lifecycle events
In the order they typically arrive- invoiceCreatedNew invoice issued
Fires when a new invoice is created. Invoice state: unpaid.
- invoicePendingPayment detected — earning confirmations
Fires when funds are detected on-chain and on every subsequent confirmation until the chain's required depth is reached. Use confirmations / requiredConfirmations on the payload to render progress. Invoice state: pending.
- invoicePaidChain-confirmed — CoinPayments received funds
Fires when the invoice has all required confirmations and CoinPayments has the funds. Invoice state: paid.
- invoiceCompletedCredited to merchant balance
Fires when funds are reflected in the merchant's balance — the safe trigger to release goods or fulfil orders. Invoice state: completed.
- invoiceCancelledCancelled by the merchant
Fires when the merchant cancels an invoice. Invoice state: cancelled.
- invoiceTimedOutInvoice expired
Fires when the invoice's payment window expires. Invoice state: timedOut. Triggers the automatic refund flow if applicable.
Payment address events
When the underlying payment address moves- invoicePaymentCreatedPayment address assigned
The temporary payment address for an invoice has been created and is now accepting funds.
- invoicePaymentTimedOutPayment address released
The temporary payment address is no longer available — funds sent after this point will not be credited to this invoice.
invoicePending fires once per confirmation
Expect invoicePending to arrive repeatedly — once when the payment is first detected and again for each new confirmation, until the chain's required depth is reached. The payload includes both confirmations (current) and requiredConfirmations (target), so you can render live progress to your customer without an extra API call. Don't credit on these events — wait for invoiceCompleted.
Subscribe in camelCase, receive in PascalCase
You subscribe to these events using their camelCase names (e.g. invoicePaid), but the delivered payload's type field — and the invoice state inside it — arrive in PascalCase (e.g. InvoicePaid). Compare both case-insensitively so your handler matches regardless of casing.
Where to next?
Pick the most useful next step.
