> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ca.cryptoprocessing.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Callbacks

A callback is an automatic notification sent by CryptoProcessing to your system about status changes for deposits, withdrawals, exchange transactions, and payment requests.

> [!TIP]
>
> Some callbacks are optional, and you can enable or disable them in [Configure callbacks](https://docs.ca.cryptoprocessing.com/merchant-administration/configure-callbacks.md). Callbacks for deposits below the minimum amount and cross-currency deposits are enabled by default. Callbacks for transactions initiated in the portal, including [deposits to portal-created addresses](https://docs.ca.cryptoprocessing.com/deposits/create-a-deposit-address.md), [portal-initiated withdrawals](https://docs.ca.cryptoprocessing.com/withdrawals/create-a-withdrawal.md), and individual withdrawals from a [mass payout](https://docs.ca.cryptoprocessing.com/mass-payouts.md), are disabled by default.

## Callback types

| Callback | Sent when |
| - | - |
| [Deposit callbacks](https://docs.ca.cryptoprocessing.com/api-reference/callbacks/deposit-callbacks.md) | The status of a deposit changes. |
| [Withdrawal callbacks](https://docs.ca.cryptoprocessing.com/api-reference/callbacks/withdrawal-callbacks.md) | The status of a withdrawal changes. |
| [Payment request callbacks](https://docs.ca.cryptoprocessing.com/api-reference/callbacks/payment-request-callbacks.md) | The status of a payment request created with [/payments/v1/requests](https://docs.ca.cryptoprocessing.com/api-reference/endpoints/payments.md) changes. Payment requests created in the portal don't send callbacks. |
| [Exchange callbacks](https://docs.ca.cryptoprocessing.com/api-reference/callbacks/exchange-callbacks.md) | The status of an exchange made with [/v2/exchange/fixed](https://docs.ca.cryptoprocessing.com/api-reference/endpoints/exchange-fixed.md) or [/v2/exchange/now](https://docs.ca.cryptoprocessing.com/api-reference/endpoints/exchange-now.md) changes. |

Invoices have their own [invoice callbacks](https://docs.ca.cryptoprocessing.com/api-reference/callbacks/invoice-payment-callbacks). For new integrations, consider [payment requests](https://docs.ca.cryptoprocessing.com/payment-requests.md) instead.

## Processing callbacks

Set up an HTTPS webhook endpoint where CryptoProcessing can send callbacks. Your webhook URL must use HTTPS, use a domain name, and be considered safe by VirusTotal and similar scanners.

After you create the endpoint, register it in CryptoProcessing — see [Set up callback URL](https://docs.ca.cryptoprocessing.com/merchant-administration/set-up-callback-url.md).

When CryptoProcessing sends a callback to your endpoint, your system should:

**1. Validate the callback**

Read the Master API key from the `X-Processing-Key` header. Generate an HMAC-SHA512 signature for the exact callback request body using the secret key of that Master key, then compare it with the value in the `X-Processing-Signature` header.

**2. Process the event**

Check whether the callback is a duplicate by verifying that its transaction ID has not already been processed. If it has not, process the event, for example by updating the customer’s balance in your system.

**3. Return HTTP 200 OK**

No response body is required.

Only the active Master key is used to sign callbacks. After you activate a different Master key, verify subsequent callbacks with the new key's secret. Custom keys are never used to sign callbacks.

> [!NOTE]
>
> For additional security, you can whitelist the CryptoProcessing IP addresses used for callback delivery. Contact Support for the current list of IP addresses.

## Retry schedule

If your system does not respond with **HTTP 200 OK** to a callback, CryptoProcessing keeps the callback in the sending queue and retries delivery 12 times after the initial attempt.

Each retry is scheduled relative to the previous attempt: +1 minute, then +5, +15, +30, +60, +90, +120, +180, +240, +240, +240, +240 minutes.

The retry schedule is not configurable.

## Avoiding duplicate processing

The system may resend callbacks in certain cases, so your integration should be able to recognize and ignore duplicates:

* If you receive a callback with `status: "not_confirmed"`, ignore any repeated callback with the same status and the same `txid`.
* If you receive a callback with `status: "confirmed"`, apply the same logic to avoid processing it twice.

Exchange callbacks have no `txid`, so recognize a repeated exchange callback by the exchange `id` and `status`. A second invoice or payment request callback with the same `status` isn't always a repeat: invoices send `pending` again for each partial payment, and payment requests send `processing` again for each detected transaction, with updated amounts and `transactions`. Compare the `txid` values in `transactions`: a callback with a `txid` you haven't processed yet reports a new payment, while one that lists only transactions you've already processed is a repeat, even if other details have been added since.

If you receive two successful callbacks for the same event, respond to the second one with HTTP code `201` to stop further retries. Otherwise, CryptoProcessing continues to expect an HTTP `200` response and keeps resending the callback.

> [!TIP]
>
> Make sure your integration responds with `200` or `201` immediately upon receiving a callback.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.