# Authentication Source: https://docs.cryptoprocessing.com/api-reference/authentication Learn how to authenticate API requests and avoid common setup issues. ## Required headers Include the following headers with every request, except for [/v2/ping](/api-reference/endpoints/ping): | Header | Required | Description | | :----------------------- | :------- | :------------------------------------------------------------------------- | | `Content-Type` | Yes | Must be `application/json` | | `X-Processing-Key` | Yes | Your API key | | `X-Processing-Signature` | Yes | HMAC-SHA512 signature of the request body, generated using your secret key | ## How to generate the signature Generate the signature from the exact JSON string sent in the request body: 1. Take the exact request body string that you are going to send. 2. Use your **secret key** as the HMAC key. 3. Compute the HMAC signature using the SHA-512 algorithm and encode the result as a lowercase hexadecimal string. 4. Send that value in the `X-Processing-Signature` header. The signature must be generated from the exact request body sent to the API. If the body changes after signing, the request will be rejected. Make sure that: * The JSON is not reformatted or pretty-printed after signing * Field order does not change * No extra whitespace or line breaks are added * Your HTTP client does not modify the body before sending it ## Verify your implementation Generate a signature for the following JSON body using `AbCdEfG123456` as the secret key: ```json theme={null} {"currency":"BTC","foreign_id":"123456"} ``` Expected result: ```text theme={null} 03c25fcf7cd35e7d995e402cd5d51edd72d48e1471e865907967809a0c189ba55b90815f20e2bb10f82c7a9e9d865546fda58989c2ae9e8e2ff7bc29195fa1ec ``` ## Common pitfalls Most authentication errors are caused by differences between the signed body and the sent body. Check the following: * The JSON used for signing is identical to the JSON sent * Field order has not changed * No additional whitespace or line breaks were introduced * Your HTTP client did not modify the request body * The signature is **hex-encoded** (not Base64) * Header names match exactly: * `X-Processing-Key` * `X-Processing-Signature` # Callbacks overview Source: https://docs.cryptoprocessing.com/api-reference/callbacks/callbacks-overview A callback is an automatic notification sent by CryptoProcessing to your system about status changes for [deposits](/api-reference/callbacks/deposit-callbacks), [withdrawals](/api-reference/callbacks/withdrawal-callbacks), [exchange transactions](/api-reference/callbacks/exchange-callbacks), and [payment requests](/api-reference/callbacks/payment-request-callbacks). ## 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](/merchant-administration/set-up-callback-url). When CryptoProcessing sends a callback to your endpoint, your system should: Generate an HMAC-SHA512 signature for the callback request body using your secret key, then compare it with the value in the `X-Processing-Signature` header. 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. No response body is required. 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. 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. Make sure your integration responds with `200` or `201` immediately upon receiving a callback. # Deposit callbacks Source: https://docs.cryptoprocessing.com/api-reference/callbacks/deposit-callbacks Deposit callbacks are sent whenever funds are received at an address created via the [/v2/addresses/take](/api-reference/endpoints/addresses-take) endpoint. Use the `foreign_id` field to identify which customer made the deposit. This value is the same as the `foreign_id` you provided when calling `/v2/addresses/take`. Amount fields included in the callback: * `currency_sent.amount` — the amount sent by the customer in the deposit currency * `currency_received.amount` — the amount received after processing or conversion * `currency_received.amount_minus_fee` — the amount credited to your merchant balance after fees Sent when a deposit has been successfully confirmed and can be treated as final on your side. At this stage, it is safe to perform business actions such as crediting the customer's balance. If the address is configured with automatic conversion, the deposited amount is received in the address currency and then converted into the `convert_to` currency before being credited to your balance. ```json title="Without conversion" highlight={7,10,16-20,43} theme={null} { "id": 1, "end_user_reference": "user_12345", "type": "deposit", "crypto_address": { "id": 1, "currency": "USDC", "address": "0x9F2E4b7A1C3D5F6E8B0A2C4D6E8F1A3B5C7D9E0F", "tag": null, "foreign_id": "12345" }, "currency_sent": { "currency": "USDC", "amount": "1000.00000000" }, "currency_received": { "currency": "USDC", "amount": "1000.00000000", "amount_minus_fee": "997.00000000" }, "transactions": [ { "id": 1, "currency": "USDC", "transaction_type": "blockchain", "type": "deposit", "address": "0x9F2E4b7A1C3D5F6E8B0A2C4D6E8F1A3B5C7D9E0F", "tag": null, "amount": "1000.00000000", "txid": "0x3c8f1a92e6d4b7c0a5f2e8d1b6c9a4f7e0d3b8c5a1f6e9d2b4c7a0f3e8d5b1c9", "riskscore": "0.5", "confirmations": 3 } ], "fees": [ { "type": "deposit", "currency": "USDC", "amount": "3.00000000" } ], "error": "", "status": "confirmed" } ``` ```json title="With conversion" highlight={7-8,11,17-21,53} theme={null} { "id": 2686510, "end_user_reference": "user_12345", "type": "deposit_exchange", "crypto_address": { "id": 382270, "currency": "USDC", "convert_to": "EUR", "address": "0x1D3F5A7C9E0B2D4F6A8C0E2B4D6F8A1C3E5B7D90", "tag": null, "foreign_id": "12345" }, "currency_sent": { "currency": "USDC", "amount": "1000.00000000" }, "currency_received": { "currency": "EUR", "amount": "920.00000000", "amount_minus_fee": "874.00000000" }, "transactions": [ { "id": 714576, "currency": "USDC", "transaction_type": "blockchain", "type": "deposit", "address": "0x1D3F5A7C9E0B2D4F6A8C0E2B4D6F8A1C3E5B7D90", "tag": null, "amount": "1000.00000000", "txid": "0x6b9d2f4a8c1e3b5d7f9a2c4e6b8d0f3a5c7e9b1d4f6a8c0e2b4d6f8a1c3e5b7d", "riskscore": "0.42", "confirmations": "1" }, { "id": 714577, "currency": "USDC", "currency_to": "EUR", "transaction_type": "exchange", "type": "exchange", "amount": "1000.00000000", "amount_to": "920.00000000" } ], "fees": [ { "type": "exchange", "currency": "EUR", "amount": "46.00000000" } ], "error": "", "status": "confirmed" } ``` Sent when a user deposits a currency different from the one originally assigned to the address. In this case, the callback includes `expected_currency`, and `crypto_address.cross_currency` is set to `true`. This callback may be disabled, see [Configure deposit callbacks](/merchant-administration/configure-deposit-callbacks). ```json highlight={5,11,18-22} theme={null} { "id": 2686510, "end_user_reference": "user_12345", "type": "deposit", "expected_currency": "USDC", "crypto_address": { "id": 382270, "currency": "ETH", "address": "0xd61180ff0cf74dc3ee8e264751f18c47060729b9", "tag": null, "cross_currency": true, "foreign_id": "12345" }, "currency_sent": { "currency": "ETH", "amount": "0.01000000" }, "currency_received": { "currency": "ETH", "amount": "0.01000000", "amount_minus_fee": "0.00900000" }, "transactions": [ { "id": 714576, "currency": "ETH", "transaction_type": "blockchain", "type": "deposit", "address": "0xd61180ff0cf74dc3ee8e264751f18c47060729b9", "tag": null, "amount": "0.01000000", "txid": "3a491da90a1ce5a318d0aeff6867ab98a03219abae29ed68d702291703c3538b", "riskscore": "0.72", "confirmations": "9" } ], "fees": [ { "type": "transfer", "currency": "ETH", "amount": "0.00037336" } ], "error": "", "status": "confirmed" } ``` Sent when the transaction has been detected but is still being processed. You can create the deposit on your side with a “Pending” or “Processing” status, but should wait for a [confirmed](#confirmed) callback before treating it as final. Note that currencies which support instant confirmations may skip this callback entirely and go straight to `confirmed`. See [How deposits are confirmed](/deposits/how-deposits-are-confirmed) for the full confirmation flow, and [Confirmations and limits](/confirmations-and-limits) for the number of confirmations required per currency. If the address is configured with automatic conversion, the conversion has not yet taken place, so `currency_received` and the exchange transaction's `amount_to` are returned as `0`. ```json title="Without conversion" highlight={7,10,16-20,36} theme={null} { "id": 132506113, "end_user_reference": "user_12345", "type": "deposit", "crypto_address": { "id": 3776973, "currency": "USDC", "address": "0x071B2E45e2CD08011555755b93d5C76D2E62C4Cd", "tag": null, "foreign_id": "11" }, "currency_sent": { "currency": "USDC", "amount": "1000.00000000" }, "currency_received": { "currency": "USDC", "amount": "1000.00000000", "amount_minus_fee": "1000.00000000" }, "transactions": [ { "id": 3745588, "currency": "USDC", "transaction_type": "blockchain", "type": "deposit", "address": "0x071B2E45e2CD08011555755b93d5C76D2E62C4Cd", "tag": null, "amount": "1000.00000000", "txid": "0x4c72ffcb2dfcd0b21c4f19c094558865af465abdfa04a2b8c33ee569afa4ef8d", "riskscore": null, "confirmations": "1" } ], "fees": [], "error": "", "status": "not_confirmed" } ``` ```json title="With conversion" highlight={7-8,11,17-21,47} theme={null} { "id": 135225178, "end_user_reference": "user_12345", "type": "deposit_exchange", "crypto_address": { "id": 240717684, "currency": "USDC", "convert_to": "EUR", "address": "0x5c625bB47E51F128E100b00A33f560Cd88272868", "tag": null, "foreign_id": "user_12345" }, "currency_sent": { "currency": "USDC", "amount": "1000.00000000" }, "currency_received": { "currency": "EUR", "amount": "0.00000000", "amount_minus_fee": "0.00000000" }, "transactions": [ { "id": 10248977, "currency": "USDC", "transaction_type": "blockchain", "type": "deposit", "address": "0x5c625bB47E51F128E100b00A33f560Cd88272868", "tag": null, "amount": "1000.00000000", "txid": "0x20f22a1dbbe601d92d174724aed22cd5df88ee36e56e2488ff70fe13d3dbcd89", "riskscore": null, "confirmations": "1" }, { "id": 10248978, "currency": "USDC", "currency_to": "EUR", "transaction_type": "exchange", "type": "exchange", "amount": "1000.00000000", "amount_to": "0.00000000" } ], "fees": [], "error": "", "status": "not_confirmed" } ``` Sent when the deposited amount is lower than the minimum allowed for that currency. Such deposits are not credited, and no fees are charged. This callback may be disabled, see [Configure deposit callbacks](/merchant-administration/configure-deposit-callbacks). ```json highlight={10,26-27} theme={null} { "id": 2686563, "end_user_reference": "user_12345", "type": "deposit", "crypto_address": { "id": 381738, "currency": "USDC", "address": "0xd61180ff0cf74dc3ee8e264751f18c47060729b9", "tag": null, "foreign_id": "12345" }, "transactions": [ { "id": 714657, "currency": "USDC", "transaction_type": "blockchain", "type": "deposit", "address": "0xd61180ff0cf74dc3ee8e264751f18c47060729b9", "tag": null, "amount": "3.00000000", "txid": "0x6b353da88a8ba2df4926c1ccc58991f484a683ba57ec3dde70e812b5c8c7fa1d", "confirmations": "9" } ], "fees": [], "error": "Transaction amount less than minimum deposit", "status": "cancelled" } ``` Sent when a detected deposit is cancelled because of a double-spend event. The `"Double spend"` error means the transaction cannot be credited to your merchant account because the system detected duplicate spending of the same funds in the blockchain — as a result, the transaction also appears as unsuccessful in the blockchain itself. Since the transaction is not considered valid, you should not credit the customer's balance. ```json highlight={10,27-28} theme={null} { "id": 100, "end_user_reference": "user_12345", "type": "deposit", "crypto_address": { "id": 123, "currency": "USDC", "address": "0x4B6A2E8D1C3F5A7E9B0D2C4F6E8A1B3D5C7E9F02", "tag": null, "foreign_id": "12345" }, "transactions": [ { "id": 999, "currency": "USDC", "transaction_type": "blockchain", "type": "deposit", "address": "0x4B6A2E8D1C3F5A7E9B0D2C4F6E8A1B3D5C7E9F02", "tag": null, "amount": "1000.00000000", "txid": "0x7e1a4c9d2f6b8e0a3c5d7f9b1e4a6c8d0f2b4e6a8c1d3f5b7e9a0c2d4f6b8e1a", "riskscore": "0.01", "confirmations": "0" } ], "fees": [], "error": "Double spend", "status": "cancelled" } ``` # Exchange callbacks Source: https://docs.cryptoprocessing.com/api-reference/callbacks/exchange-callbacks Exchange callbacks are sent whenever the status of an exchange created via the [/v2/exchange/fixed](/api-reference/endpoints/exchange-fixed) or [/v2/exchange/now](/api-reference/endpoints/exchange-now) endpoint changes. The callback format is the same for exchanges created with either endpoint. When you receive a callback with `"status": "confirmed"`, the exchange has been successfully completed. At this stage, your balances for the affected currencies have already been updated. You can retrieve your current account balances via the [/v2/accounts/list](/api-reference/endpoints/accounts-list) endpoint. ```json highlight={31} theme={null} { "id": 134782394, "type": "exchange", "currency_sent": { "currency": "BTC", "amount": "0.00010000" }, "currency_received": { "currency": "ETH", "amount": "0.00326418" }, "transactions": [ { "id": 9628634, "currency": "BTC", "currency_to": "ETH", "transaction_type": "exchange", "type": "exchange", "amount": "0.00010000", "amount_to": "0.00326418" } ], "fees": [ { "type": "fee_crypto_exchange_to_crypto", "currency": "BTC", "amount": "0.00000200" } ], "error": "", "status": "confirmed" } ``` # Payment request callbacks Source: https://docs.cryptoprocessing.com/api-reference/callbacks/payment-request-callbacks Payment request callbacks are sent whenever the status of a payment request changes. When you receive a callback with `"status": "paid"`, the payment request has been successfully paid and can be treated as completed on your side. Use `foreign_id` to identify the payment request or order in your system and map it to the user for whom the payment request was created. Sent when the payment request is created with a fixed exchange rate and is waiting for payment. At this stage, no funds have been received yet. ```json highlight={5} theme={null} { "payment_request_id": "019c0ebf-81e5-751d-aa57-fb9e2cba23c2", "foreign_id": "order_12345", "type": "payment_request", "status": "processing", "end_user_email": "test@test.com", "payment_request_address": { "id": "019c0ebf-84a1-7bdc-a09c-8b62294cc75d", "currency": { "iso": "USDC", "network_name": "ethereum" }, "convert_to": { "iso": "EUR" }, "address": "0x30877432D1026706D7E805DA846A32C3BB81E3C2" }, "payment_request_amount": { "currency": { "iso": "EUR" }, "amount": "92.00" }, "currency_sent": { "currency": { "iso": "USDC", "network_name": "ethereum" }, "expected_amount": "100.00000000", "received_amount": "0.00000000", "remaining_amount": "100.00000000" }, "fixed_at": 1769773958, "expires_at": 1769774157, "valid_until": 1769774157 } ``` Sent when a new payment transaction is detected for the payment request. The payment request remains in `processing` status until the full required amount is received. ```json highlight={5} theme={null} { "payment_request_id": "019c0f25-e7db-7ca3-b19f-a7916b5a4905", "foreign_id": "order_34567", "type": "payment_request", "status": "processing", "end_user_email": "example@example.com", "payment_request_address": { "id": "019c0f25-eb0d-70bd-b282-8e58de5d1b7c", "currency": { "iso": "USDC", "network_name": "ethereum" }, "convert_to": { "iso": "USDC", "network_name": "ethereum" }, "address": "0x114da762447ccb464ac29134B2930e0570139F83" }, "payment_request_amount": { "currency": { "iso": "USDC", "network_name": "ethereum" }, "amount": "150.00000000" }, "currency_sent": { "currency": { "iso": "USDC", "network_name": "ethereum" }, "expected_amount": "150.00000000", "received_amount": "75.00000000", "remaining_amount": "75.00000000" }, "transactions": [ { "id": "019c0f26-25fc-7738-bdf1-85708ec6e67c", "currency": { "iso": "USDC", "network_name": "ethereum" }, "address": "0x114da762447ccb464ac29134B2930e0570139F83", "amount": "75.00000000", "txid": "0x12882dbbd810304bd0d9707472dbb40f8c2f7d9a1e6b3c4d5f60718293a4b5c6", "status": "confirmed", "late_payment": false } ], "fixed_at": 1769780669, "expires_at": 1769780868, "valid_until": 1769780868 } ``` Sent when the full required amount has been received and the payment request is successfully completed. ```json highlight={5} theme={null} { "payment_request_id": "019c0f25-e7db-7ca3-b19f-a7916b5a4905", "foreign_id": "order_34567", "type": "payment_request", "status": "paid", "end_user_email": "example@example.com", "payment_request_address": { "id": "019c0f25-eb0d-70bd-b282-8e58de5d1b7c", "currency": { "iso": "USDC", "network_name": "ethereum" }, "convert_to": { "iso": "USDC", "network_name": "ethereum" }, "address": "0x114da762447ccb464ac29134B2930e0570139F83" }, "payment_request_amount": { "currency": { "iso": "USDC", "network_name": "ethereum" }, "amount": "150.00000000" }, "currency_sent": { "currency": { "iso": "USDC", "network_name": "ethereum" }, "expected_amount": "150.00000000", "received_amount": "150.00000000", "remaining_amount": "0.00000000" }, "currency_received": { "currency": { "iso": "USDC", "network_name": "ethereum" }, "amount": "150.00000000" }, "transactions": [ { "id": "019c0f26-25fc-7738-bdf1-85708ec6e67c", "currency": { "iso": "USDC", "network_name": "ethereum" }, "address": "0x114da762447ccb464ac29134B2930e0570139F83", "amount": "75.00000000", "txid": "0xa3f1c9d8427e6b5c1098d7e6f5a4b3c291807f6e5d4c3b2a1908f7e6d5c4b3a2", "status": "confirmed", "late_payment": false }, { "id": "6425cf81-da66-4c60-8a53-6dbdf118ce09", "currency": { "iso": "USDC", "network_name": "ethereum" }, "address": "0x114da762447ccb464ac29134B2930e0570139F83", "amount": "75.00000000", "txid": "0x12882dbbd810304bd0d9707472dbb40f8c2f7d9a1e6b3c4d5f60718293a4b5c6", "status": "confirmed", "late_payment": false } ], "fees": [ { "type": "transfer_fee", "currency": { "iso": "USDC", "network_name": "ethereum" }, "amount": "0.50000000" }, { "type": "fee_payment_request_crypto", "currency": { "iso": "USDC", "network_name": "ethereum" }, "amount": "1.50000000" } ], "fixed_at": 1769780669, "expires_at": 1769780868, "valid_until": 1769780868 } ``` Sent when the payment request is not successfully completed before expiry. Use the transaction details and amounts to understand what was received. ```json highlight={5} theme={null} { "payment_request_id": "019c0de8-4576-7e4f-85c7-43a5cb5e9f2d", "foreign_id": "order_82652.32794293783", "type": "payment_request", "status": "failed", "end_user_email": "test@test.net", "payment_request_address": { "id": "019c0de8-49df-762a-9705-4c304627dfd0", "currency": { "iso": "USDC", "network_name": "ethereum" }, "convert_to": { "iso": "EUR" }, "address": "0x9B62179273C8EB5BB682575EC87A171AC826A6FC" }, "payment_request_amount": { "currency": { "iso": "EUR" }, "amount": "92.00" }, "currency_sent": { "currency": { "iso": "USDC", "network_name": "ethereum" }, "expected_amount": "100.00000000", "received_amount": "90.00000000", "remaining_amount": "10.00000000" }, "transactions": [ { "id": "019c0de8-54a3-7163-b59c-95f38d982a31", "currency": { "iso": "USDC", "network_name": "ethereum" }, "address": "0x9B62179273C8EB5BB682575EC87A171AC826A6FC", "txid": "0x21a278f64f7fd633dbdde131ca3766e4d58e72e310275dff6c15c0c8e9df4696", "amount": "90.00000000", "status": "confirmed", "late_payment": false } ], "fixed_at": 1769759853, "expires_at": 1769760051, "valid_until": 1769760051 } ``` Sent when the payment request expires before payment is received and no fixed exchange rate was locked for the request. ```json highlight={5} theme={null} { "payment_request_id": "019bea8c-7d69-7632-8472-77443ac78a17", "foreign_id": "order_85566.25193543735", "type": "payment_request", "status": "expired", "end_user_email": "ckane@example.com", "payment_request_amount": { "currency": { "iso": "USDC", "network_name": "ethereum" }, "amount": "150.00000000" }, "expires_at": 1769166664 } ``` Sent when the payment request expires after a fixed exchange rate was locked, but no sufficient payment was received before expiry. ```json highlight={5} theme={null} { "payment_request_id": "019c0ebf-81e5-751d-aa57-fb9e2cba23c2", "foreign_id": "order_12345", "type": "payment_request", "status": "expired", "end_user_email": "test@test.com", "payment_request_address": { "id": "019c0ebf-84a1-7bdc-a09c-8b62294cc75d", "currency": { "iso": "USDC", "network_name": "ethereum" }, "convert_to": { "iso": "EUR" }, "address": "0x30877432D1026706D7E805DA846A32C3BB81E3C2" }, "payment_request_amount": { "currency": { "iso": "EUR" }, "amount": "92.00" }, "currency_sent": { "currency": { "iso": "USDC", "network_name": "ethereum" }, "expected_amount": "100.00000000", "received_amount": "0.00000000", "remaining_amount": "100.00000000" }, "fixed_at": 1769773958, "expires_at": 1769774157, "valid_until": 1769774157 } ``` Sent when a payment is received after the payment request has already expired or failed. Such transactions are marked with `late_payment: true`. ```json highlight={5} theme={null} { "payment_request_id": "019c0de8-4576-7e4f-85c7-43a5cb5e9f2d", "foreign_id": "order_82652.32794293783", "type": "payment_request", "status": "failed", "end_user_email": "test@test.net", "payment_request_address": { "id": "019c0de8-49df-762a-9705-4c304627dfd0", "currency": { "iso": "USDC", "network_name": "ethereum" }, "convert_to": { "iso": "EUR" }, "address": "0xE48478DCB74F21345D2CCE8038A39D5E0853964B" }, "payment_request_amount": { "currency": { "iso": "EUR" }, "amount": "92.00" }, "currency_sent": { "currency": { "iso": "USDC", "network_name": "ethereum" }, "expected_amount": "100.00000000", "received_amount": "100.00000000", "remaining_amount": "0.00000000" }, "transactions": [ { "id": "019c0de8-54a3-7163-b59c-95f38d982a31", "currency": { "iso": "USDC", "network_name": "ethereum" }, "address": "0xE48478DCB74F21345D2CCE8038A39D5E0853964B", "txid": "0x11a11f5125227c3712da86a78c49ea20e32684b27b95e909348334896a68f812", "amount": "90.00000000", "status": "confirmed", "late_payment": false }, { "id": "019c0de8-54a3-7163-b59c-95f38d982a32", "currency": { "iso": "USDC", "network_name": "ethereum" }, "address": "0xE48478DCB74F21345D2CCE8038A39D5E0853964B", "txid": "0xd810a485ed03241b4d419b1b673bd4755d05ad7853c1f76eb97706ca828bca03", "amount": "10.00000000", "status": "confirmed", "late_payment": true } ], "fixed_at": 1769759853, "expires_at": 1769760051, "valid_until": 1769760051 } ``` Sent when the payer is not allowed to complete the payment. ```json highlight={5,7} theme={null} { "payment_request_id": "019c0de8-4576-7e4f-85c7-43a5cb5e9f2d", "foreign_id": "order_82652.32794293783", "type": "payment_request", "status": "failed", "end_user_email": "test@test.net", "status_reason": "Service is restricted for the payer. Payments from this payer cannot be processed", "end_user_reference": "account_14578", "payment_request_amount": { "currency": { "iso": "USDC", "network_name": "ethereum" }, "amount": "150.00000000" }, "expires_at": 1769166664 } ``` # Withdrawal callbacks Source: https://docs.cryptoprocessing.com/api-reference/callbacks/withdrawal-callbacks Withdrawal callbacks are sent whenever the status of a withdrawal changes. Use the `status` field to determine if the operation was successful or not. For cancelled or declined operations, use the `error` field to determine the reason. Use the `end_user_reference` field to identify the customer who received the withdrawn funds. Sent when a withdrawal has been successfully completed and can be treated as final on your side. ```json title="Standard withdrawal" highlight={27} theme={null} { "id": 123, "foreign_id": "operation_987", "end_user_reference": "user_12345", "type": "withdrawal", "crypto_address": { "id": 123, "currency": "BTC", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null }, "transactions": [ { "id": 999, "currency": "BTC", "transaction_type": "blockchain", "type": "withdrawal", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null, "amount": "0.01000000", "txid": "bb040d895ef7141ea0b06b04227d8f5dd4ee12d5b890e6e5633f6439393a666b", "confirmations": "0" } ], "fees": [], "error": "", "status": "confirmed" } ``` ```json title="Instant withdrawal" highlight={38} theme={null} { "id": 123, "foreign_id": "operation_987", "end_user_reference": "user_12345", "type": "withdrawal_instant", "crypto_address": { "id": 123, "currency": "BTC", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null }, "transactions": [ { "id": 999, "currency": "BTC", "transaction_type": "blockchain", "type": "withdrawal", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null, "amount": "0.01000000", "txid": "bb040d895ef7141ea0b06b04227d8f5dd4ee12d5b890e6e5633f6439393a666b", "confirmations": "0" } ], "fees": [ { "type": "mining", "currency": "BTC", "amount": "0" }, { "type": "fee_crypto_withdrawal_from_crypto", "currency": "BTC", "amount": "0.00028735" } ], "error": "", "status": "confirmed" } ``` Sent when a withdrawal with conversion has been successfully completed and can be treated as final on your side. ```json title="Standard withdrawal" highlight={44} theme={null} { "id": 123, "foreign_id": "operation_987", "end_user_reference": "user_12345", "type": "withdrawal_exchange", "crypto_address": { "id": 123, "currency": "BTC", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null }, "currency_sent": { "currency": "EUR", "amount": "804.25693204" }, "currency_received": { "currency": "BTC", "amount": "0.01000000" }, "transactions": [ { "id": 999, "currency": "BTC", "transaction_type": "blockchain", "type": "withdrawal", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null, "amount": "0.01000000", "txid": "bb040d895ef7141ea0b06b04227d8f5dd4ee12d5b890e6e5633f6439393a666b", "confirmations": "0" }, { "id": 1000, "currency": "EUR", "currency_to": "BTC", "transaction_type": "exchange", "type": "exchange", "amount": "804.25693204", "amount_to": "0.01000000" } ], "fees": [ { "type": "fee_crypto_withdrawal_from_fiat", "currency": "BTC", "amount": "0.00028735" } ], "error": "", "status": "confirmed" } ``` ```json title="Instant withdrawal" highlight={55} theme={null} { "id": 123, "foreign_id": "operation_987", "end_user_reference": "user_12345", "type": "withdrawal_instant_exchange", "crypto_address": { "id": 123, "currency": "BTC", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null }, "currency_sent": { "currency": "EUR", "amount": "804.25693204" }, "currency_received": { "currency": "BTC", "amount": "0.01000000" }, "transactions": [ { "id": 999, "currency": "BTC", "transaction_type": "blockchain", "type": "withdrawal", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null, "amount": "0.01000000", "txid": "bb040d895ef7141ea0b06b04227d8f5dd4ee12d5b890e6e5633f6439393a666b", "confirmations": "0" }, { "id": 1000, "currency": "EUR", "currency_to": "BTC", "transaction_type": "exchange", "type": "exchange", "amount": "804.25693204", "amount_to": "0.01000000" } ], "fees": [ { "type": "mining", "currency": "BTC", "amount": "0" }, { "type": "fee_crypto_withdrawal_from_fiat", "currency": "BTC", "amount": "0.00028735" } ], "error": "", "status": "confirmed" } ``` Sent when a withdrawal exceeds the configured [withdrawals limits](/merchant-administration/configure-withdrawal-limits) and is awaiting approval from a user with the **Owner** role. ```json title="Standard withdrawal" highlight={21,27} theme={null} { "id": 123, "foreign_id": "operation_987", "end_user_reference": "user_12345", "type": "withdrawal", "crypto_address": { "id": 123, "currency": "BTC", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null }, "transactions": [ { "id": 999, "currency": "BTC", "transaction_type": "blockchain", "type": "withdrawal", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null, "amount": "0.01000000", "txid": null, "confirmations": "0" } ], "fees": [], "error": "", "status": "pending" } ``` ```json title="Instant withdrawal" highlight={21,27} theme={null} { "id": 123, "foreign_id": "operation_987", "end_user_reference": "user_12345", "type": "withdrawal_instant", "crypto_address": { "id": 123, "currency": "BTC", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null }, "transactions": [ { "id": 999, "currency": "BTC", "transaction_type": "blockchain", "type": "withdrawal", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null, "amount": "0.01000000", "txid": null, "confirmations": "0" } ], "fees": [], "error": "", "status": "pending" } ``` Sent when a withdrawal with conversion exceeds the configured [withdrawals limits](/merchant-administration/configure-withdrawal-limits) and is awaiting approval from a user with the **Owner** role. ```json title="Standard withdrawal" theme={null} { "id": 132533108, "foreign_id": "withdrawal_1230203", "end_user_reference": "user_12345", "type": "withdrawal_exchange", "crypto_address": { "id": 3776985, "currency": "BTC", "address": "tb1qj0d4rsczat6dx3yy065g98rrz5hewkrdcrz7je", "tag": null }, "transactions": [ { "id": 3779034, "currency": "BTC", "transaction_type": "blockchain", "type": "withdrawal", "address": "tb1qj0d4rsczat6dx3yy065g98rrz5hewkrdcrz7je", "tag": null, "amount": "0.00000000", "txid": null, "riskscore": null, "confirmations": "0" }, { "id": 3779035, "currency": "EUR", "currency_to": "BTC", "transaction_type": "exchange", "type": "exchange", "amount": "100.00000000", "amount_to": "0.00000000" } ], "fees": [], "error": "", "status": "pending" } ``` ```json title="Instant withdrawal" theme={null} { "id": 132533109, "foreign_id": "withdrawal_123", "end_user_reference": "user_12345", "type": "withdrawal_instant_exchange", "crypto_address": { "id": 3776985, "currency": "BTC", "address": "tb1qj0d4rsczat6dx3yy065g98rrz5hewkrdcrz7je", "tag": null }, "transactions": [ { "id": 3779036, "currency": "BTC", "transaction_type": "blockchain", "type": "withdrawal", "address": "tb1qj0d4rsczat6dx3yy065g98rrz5hewkrdcrz7je", "tag": null, "amount": "0.00000000", "txid": null, "riskscore": null, "confirmations": "0" }, { "id": 3779037, "currency": "EUR", "currency_to": "BTC", "transaction_type": "exchange", "type": "exchange", "amount": "100.00000000", "amount_to": "0.00000000" } ], "fees": [], "error": "", "status": "pending" } ``` Sent when a user with the **Owner** role declines a withdrawal that exceeds the configured [withdrawals limits](/merchant-administration/configure-withdrawal-limits). ```json title="Standard withdrawal" highlight={21,26-27} theme={null} { "id": 123, "foreign_id": "operation_987", "end_user_reference": "user_12345", "type": "withdrawal", "crypto_address": { "id": 123, "currency": "BTC", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null }, "transactions": [ { "id": 999, "currency": "BTC", "transaction_type": "blockchain", "type": "withdrawal", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null, "amount": "0.01000000", "txid": null, "confirmations": "0" } ], "fees": [], "error": "Declined by user ID:777", "status": "declined" } ``` ```json title="Instant withdrawal" highlight={21,26-27} theme={null} { "id": 123, "foreign_id": "operation_987", "end_user_reference": "user_12345", "type": "withdrawal_instant", "crypto_address": { "id": 123, "currency": "BTC", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null }, "transactions": [ { "id": 999, "currency": "BTC", "transaction_type": "blockchain", "type": "withdrawal", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null, "amount": "0.01000000", "txid": null, "confirmations": "0" } ], "fees": [], "error": "Declined by user ID:777", "status": "declined" } ``` Sent when a withdrawal is cancelled and will not be completed. Use the `error` field to determine the reason, for example: There is a mistake in the specified address, and it does not match the format required for the specific currency. At the time of initiating the withdrawal, you did not have enough funds in the balance of the specific currency being withdrawn. Top up the balance and reinitiate the withdrawal. The system requires the balance to be available in the exact currency being withdrawn, because automatic conversion is not possible for security reasons. You must convert the funds manually. The total negative balances across all currencies exceed 20 EUR. Top up your balance and reinitiate the withdrawal. The destination address requires a tag (also called a memo or destination tag) to correctly credit the recipient, but none was provided in the withdrawal request. Specify the required tag and reinitiate the withdrawal. ```json title="Standard withdrawal" highlight={21,26-27} theme={null} { "id": 123, "foreign_id": "operation_987", "end_user_reference": "user_12345", "type": "withdrawal", "crypto_address": { "id": 123, "currency": "BTC", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null }, "transactions": [ { "id": 999, "currency": "BTC", "transaction_type": "blockchain", "type": "withdrawal", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null, "amount": "0.01000000", "txid": null, "confirmations": "0" } ], "fees": [], "error": "Not enough money on balance", "status": "cancelled" } ``` ```json title="Instant withdrawal" highlight={21,26-27} theme={null} { "id": 123, "foreign_id": "operation_987", "end_user_reference": "user_12345", "type": "withdrawal_instant", "crypto_address": { "id": 123, "currency": "BTC", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null }, "transactions": [ { "id": 999, "currency": "BTC", "transaction_type": "blockchain", "type": "withdrawal", "address": "tb1qurv0m4ufsj8xqejvmn0y43kqew33kvqrrxswgm", "tag": null, "amount": "0.01000000", "txid": null, "confirmations": "0" } ], "fees": [], "error": "Not enough money on balance", "status": "cancelled" } ``` # API currency codes Source: https://docs.cryptoprocessing.com/api-reference/currency-codes Use these codes in your API requests | API code | Cryptocurrency | Name | Network | | :------- | :-------------- | :------------- | :-------------- | | ADA | ADA | Cardano | Cardano | | BCH | BCH | Bitcoin Cash | Bitcoin Cash | | BNB | BNB-BSC | BNB | BNB Smart Chain | | BTC | BTC | Bitcoin | Bitcoin | | DOGE | DOGE | Dogecoin | Dogecoin | | ETH | ETH | Ethereum | Ethereum | | ETHA | ETH (Arbitrum) | Ethereum | Arbitrum | | ETHBASE | ETH (Base) | Ethereum | Base | | EURCBASE | EURC (Base) | EUR Stablecoin | Base | | EURCE | EURC (ERC-20) | EUR Stablecoin | Ethereum | | EURCS | EURC (SOL) | EUR Stablecoin | Solana | | EURS | EURS (ERC-20) | STASIS EURS | Ethereum | | LTC | LTC | Litecoin | Litecoin | | POL | POL | Polygon | Polygon | | SOL | SOL | Solana | Solana | | TRX | TRX | Tron | Tron | | USDC | USDC (ERC-20) | USD Coin | Ethereum | | USDCA | USDC (Arbitrum) | USD Coin | Arbitrum | | USDCB | USDC (BEP-20) | USD Coin | BNB Smart Chain | | USDCBASE | USDC (Base) | USD Coin | Base | | USDCP | USDC (Polygon) | USD Coin | Polygon | | USDCS | USDC (SOL) | USD Coin | Solana | | USDGE | USDG (ERC-20) | Global Dollar | Ethereum | | USDGS | USDG (SOL) | Global Dollar | Solana | | WBTC | WBTC | Wrapped BTC | Ethereum | | XED | XED | Exeedme | Ethereum | | XRP | XRP | Ripple | XRP Ledger | For the [/payments/v1/requests](/api-reference/endpoints/payments) endpoint, use the following currency and network names: | Currency ISO | Supported network names | | :----------- | :------------------------------------------------------------- | | `ADA` | `cardano` | | `BCH` | `bitcoin_cash` | | `BNB-BSC` | `binance` | | `BTC` | `bitcoin` | | `DOGE` | `dogecoin` | | `ETH` | `arbitrum`, `base`, `ethereum` | | `EURC` | `base`, `ethereum`, `solana` | | `EURS` | `ethereum` | | `LTC` | `litecoin` | | `POL` | `polygon` | | `SOL` | `solana` | | `TRX` | `tron` | | `USDC` | `arbitrum`, `base`, `binance`, `ethereum`, `polygon`, `solana` | | `USDG` | `ethereum`, `solana` | | `WBTC` | `ethereum` | | `XED` | `ethereum` | | `XRP` | `ripple` | # List balances Source: https://docs.cryptoprocessing.com/api-reference/endpoints/accounts-list POST /v2/accounts/list Get a list of your balances for every currency, both crypto and fiat. # Generate a user deposit address Source: https://docs.cryptoprocessing.com/api-reference/endpoints/addresses-take POST /v2/addresses/take Generate a deposit address for a user. Deposits sent to this address are attributed to the user identified by `foreign_id`. CryptoProcessing is required to collect sender data in compliance with the MiCA regulations. For more details, see [User data collection](/user-data-collection). The `sender_data` and the `end_user_reference` you provide must be associated with the same customer. # Withdraw crypto instantly Source: https://docs.cryptoprocessing.com/api-reference/endpoints/crypto-withdrawal-instant POST /v2/crypto/withdrawal_instant Make an [instant withdrawal](/withdrawals#instant-withdrawals) from a cryptocurrency balance. CryptoProcessing is required to collect sender data in compliance with the MiCA regulations. For more details, see [User data collection](/user-data-collection). The `sender_data` and the `end_user_reference` you provide must be associated with the same customer. # Withdraw crypto instantly with conversion Source: https://docs.cryptoprocessing.com/api-reference/endpoints/crypto-withdrawal-instant-exchange POST /v2/crypto/withdrawal_instant_exchange Make an [instant withdrawal](/withdrawals#instant-withdrawals) from a cryptocurrency or fiat balance with conversion to cryptocurrency. CryptoProcessing is required to collect sender data in compliance with the MiCA regulations. For more details, see [User data collection](/user-data-collection). The `sender_data` and the `end_user_reference` you provide must be associated with the same customer. # List supported currencies Source: https://docs.cryptoprocessing.com/api-reference/endpoints/currencies-list POST /v2/currencies/list Get a list of available currencies, minimum deposit amounts, and deposit and withdrawal fees. The list of supported currencies in the sandbox environment is different from the list in the production environment. # Get exchange rates Source: https://docs.cryptoprocessing.com/api-reference/endpoints/currencies-rates POST /v2/currencies/rates Get available currency pairs and exchange rates. This endpoint returns reference exchange rates only. To get an actual exchange quote, use [/v2/exchange/calculate](/api-reference/endpoints/exchange-calculate). The list of supported currencies in the sandbox environment is different from the list in the production environment. # Get a fixed exchange quote Source: https://docs.cryptoprocessing.com/api-reference/endpoints/exchange-calculate POST /v2/exchange/calculate Get a fixed exchange quote for a specific amount, which can then be used with [/v2/exchange/fixed](/api-reference/endpoints/exchange-fixed). # Exchange at a fixed rate Source: https://docs.cryptoprocessing.com/api-reference/endpoints/exchange-fixed POST /v2/exchange/fixed Execute an exchange using a valid fixed quote from [/v2/exchange/calculate](/api-reference/endpoints/exchange-calculate). Execute a fixed exchange using a valid quote from [/v2/exchange/calculate](/api-reference/endpoints/exchange-calculate). The exchange request must be sent before the quote expires and must use the same amount and price as in the quote. # Exchange at market rate Source: https://docs.cryptoprocessing.com/api-reference/endpoints/exchange-now POST /v2/exchange/now Execute an exchange immediately at the currently available market rate, without requesting a fixed quote. # Create a payment request Source: https://docs.cryptoprocessing.com/api-reference/endpoints/payments POST /payments/v1/requests Create a payment request for the client for a specified amount and a configurable expiration time. Make sure that the URL that you provide in the `url_store` field uses the secure HTTPS protocol, uses domain names (not IP addresses) and is considered clean by VirusTotal and similar scanners. # Check API status Source: https://docs.cryptoprocessing.com/api-reference/endpoints/ping GET /v2/ping Test if your API connection is working. # Get transaction details Source: https://docs.cryptoprocessing.com/api-reference/endpoints/transactions-info GET /v2/transactions/info Get transaction details by `id`, `foreign_id`, or `txid`. Include only one of these parameters in your request. You can only request data for transactions that were authorized using your API and secret key. # Withdraw crypto Source: https://docs.cryptoprocessing.com/api-reference/endpoints/withdrawal-crypto POST /v2/withdrawal/crypto Withdraw in crypto to any address. CryptoProcessing is required to collect sender data in compliance with the MiCA regulations. For more details, see [User data collection](/user-data-collection). The `sender_data` and the `end_user_reference` you provide must be associated with the same customer. # Errors Source: https://docs.cryptoprocessing.com/api-reference/errors CryptoProcessing uses conventional HTTP response codes to indicate the success or failure of an API request: `2xx` for success and `4xx` for errors. The sections below cover the `4xx` codes this API returns. ## 400 Bad Request ### Request body is invalid JSON ```json theme={null} {"error":"Bad content format", "code":"bad_content_format"} ``` This error can occur for the following reasons: * **Malformed or invalid JSON.** The request body could not be parsed. Ensure it is valid JSON. * **Missing Content-Type header.** The `Content-Type` header must be set to `application/json`. ### Other endpoint-specific 400 errors Beyond malformed JSON, several endpoints return `400` for request-level validation failures — missing required fields, invalid field values, or business-rule violations specific to that endpoint (e.g. duplicate `foreign_id`, unsupported currency, amount below the allowed minimum). These use the same `{"error": ..., "code": ...}` shape shown above, with endpoint-specific messages. * The selected currency from is invalid. * The selected currency to is invalid. Endpoint reference: [Get exchange rates](/api-reference/endpoints/currencies-rates) * The currency field is required. * The foreign id field is required. * The selected currency is not enabled for your account. * Invalid currency * Currency is not allowed without conversion * The end user reference must not contain an email address. * The selected sender type is invalid. * The sender data.first name field is required. * The sender data.last name field is required. * Address cannot be issued for that end\_user\_reference Endpoint reference: [Generate a user deposit address](/api-reference/endpoints/addresses-take) * The currency field is required. * Invalid currency * The amount must be a number. * The amount must not have more than X decimal places. * The amount to must be a number. * The amount to must not have more than X decimal places. * The amount field is required when amount to is not present. * The amount field must be greater than 0. * The amount to field is required when amount is not present. * The amount to field must be greater than 0. * The convert to field is required when amount to is present. * The foreign id field is required. * The foreign id has already been taken. * The end user reference must not contain an email address. * The selected sender type is invalid. * The selected receiver type is invalid. * Invalid USDC address * The amount must be 5.00000000 USDC. * The requested amount exceeds the available balance. * Destination tag/memo for currencies that require it. * Unable to exchange the requested amount at the moment. Specify a smaller amount or try again later. Endpoint reference: [Withdraw crypto](/api-reference/endpoints/withdrawal-crypto) * Instant withdrawals are disabled for this merchant. * Instant withdrawals are not supported for the specified sender\_currency. * The foreign id has already been taken. * The sender\_currency field is required. * Invalid USDC address * The amount must be 5.00000000 USDC. * The requested amount exceeds the available balance. * The address field is required. * The sender\_amount must be greater than 0. Endpoint reference: [Withdraw crypto instantly](/api-reference/endpoints/crypto-withdrawal-instant) * Instant withdrawals are disabled for this merchant. * Instant withdrawals are not supported for the specified sender\_currency. * The foreign id has already been taken. * The sender\_currency field is required. * Invalid USDC address * The amount must be 5.00000000 USDC. * The requested amount exceeds the available balance. * Unable to exchange the requested amount at the moment. Specify a smaller amount or try again later. * The address field is required. * The sender\_amount must be greater than 0. Endpoint reference: [Withdraw crypto instantly with conversion](/api-reference/endpoints/crypto-withdrawal-instant-exchange) * The sender currency field is required. * The receiver currency field is required. * The receiver amount field is required when the sender amount field is not presented. * The receiver currency and sender currency must be different. * The selected sender currency is invalid. * The selected receiver currency is invalid. * Invalid amount format * The sender amount must be greater than 0. * The receiver amount must be greater than 0. * The sender\_amount must be at least 2.00000000 ABC * The sender\_amount may not be greater than 7.00000000 ABC * Exchange is unavailable for given currencies * Unable to exchange the requested amount at the moment. Specify a smaller amount or try again later. Endpoint reference: [Get a fixed exchange quote](/api-reference/endpoints/exchange-calculate) * Fix time is up. Exchange price is changed. * Insufficient balance. Available: 50.00000000 USDC * Currency not supported * The amount must be at least 50.00000000 USDC * The foreign\_id field is required Endpoint reference: [Exchange at a fixed rate](/api-reference/endpoints/exchange-fixed) * Exchange rate not available at this time * The requested amount exceeds the available balance. * Currency not supported * The amount must be 5.00000000 USDC * The foreign\_id field is required Endpoint reference: [Exchange at market rate](/api-reference/endpoints/exchange-now) * The foreign id has already been taken. * The selected currency is invalid. * The amount must be a number. * The amount must be 5.00000000 USDC. * The email user must be a valid email address. * The title field is required. * The foreign id field is required. * The currency field is required. * The amount field is required. * The selected type is invalid. * Required features \[invoices\_enabled] not enabled. Endpoint reference: [Create an invoice](/api-reference/endpoints/invoices-create) * Invoice not found. * Invoice cannot be failed in its current state. (invalid\_invoice\_state) * Required features \[invoices\_enabled] not enabled. Endpoint reference: [Cancel an invoice](/api-reference/endpoints/invoices-cancel) * The id field is required when none of foreign id / txid are present. * The foreign id field is required when none of id / txid are present. * The txid field is required when none of id / foreign id are present. * The id must be an integer. Endpoint reference: [Get transaction details](/api-reference/endpoints/transactions-info) * Payment request with this foreign\_id already exists. * user\_fee\_percent must be 0 or 100. Endpoint reference: [Create a payment request](/api-reference/endpoints/payments) ## 403 Forbidden ### Signature header does not match the request body ```json theme={null} {"error":"Bad signature header", "code":"bad_header_signature"} ``` The value in `X-Processing-Signature` did not match the request body. See [Authentication](/api-reference/authentication) for how to generate the signature correctly. This can happen for several reasons: * **Signature not converted to string.** The signature is generated from a data array without first converting it to a string. Ensure the signature value is sent as a string. * **Body modified after signing.** The signed body must be identical to the body that is sent — no reformatting, whitespace changes, or field reordering. * **Extra characters or spaces.** A code error introduces unexpected characters or spaces. Review your implementation and verify no extra characters are present. * **Signature built from the full data array.** The signature is created from the entire data array — including the public key and headers — instead of the secret key only. Generate the signature exclusively from the secret key. * **Public key in wrong parameter (PHP).** In some languages such as PHP, the public key may be mistakenly included in `paramsArray` instead of the request body. Pass the public key in the correct location. * **Wrong secret key or environment.** Sandbox and production use separate key pairs. Make sure you are using the correct set for the environment you are targeting. ### Signature header is missing ```json theme={null} {"error":"No signature header", "code":"required_header_signature"} ``` The request does not include the required `X-Processing-Signature` header. Add it with an HMAC-SHA512 signature of the request body. ### API key header does not match your API key ```json theme={null} {"error":"Bad key header", "code":"bad_header_key"} ``` The value in `X-Processing-Key` did not match any known API key. This can happen for several reasons: * **Non-whitelisted IP.** If you have configured an IP whitelist in the Merchant Dashboard, requests from any unlisted IP will be rejected. Add the IP to the whitelist, use an already-whitelisted IP, or remove the whitelist entirely. * **Wrong environment.** Production keys will not work against the sandbox endpoint, and vice versa. Check that the base URL matches the environment your keys belong to. * **Incorrect or malformed public key.** Verify you are using the correct key. It contains both upper and lower case characters and must be sent exactly as provided — avoid any case transformation in your code. * **Secret key used instead of public key.** The `X-Processing-Key` header must contain your public key only. The secret key is used exclusively to generate and verify signatures. Refer to [Get your API key](/merchant-administration/generate-and-activate-api-keys) for details. ### API key header is missing ```json theme={null} {"error":"No key header", "code":"required_header_key"} ``` This error can occur for the following reasons: * **Missing X-Processing-Key header.** Add the `X-Processing-Key` header with your public API key. * **Invalid request URL.** Verify the endpoint URL is correct. ### Other endpoint-specific 403 errors Beyond the header problems above, a few endpoints return `403` for other authorization-related reasons — for example, a feature being disabled for your account. * Withdrawal functionality is currently unavailable (withdrawal\_functionality\_unavailable) — see [Enable withdrawals again](/merchant-administration/disable-withdrawals#enable-withdrawals-again) Endpoint reference: [Withdraw crypto](/api-reference/endpoints/withdrawal-crypto) * Withdrawal functionality is currently unavailable (withdrawal\_functionality\_unavailable) — see [Enable withdrawals again](/merchant-administration/disable-withdrawals#enable-withdrawals-again) Endpoint reference: [Withdraw crypto instantly](/api-reference/endpoints/crypto-withdrawal-instant) * Withdrawal functionality is currently unavailable (withdrawal\_functionality\_unavailable) — see [Enable withdrawals again](/merchant-administration/disable-withdrawals#enable-withdrawals-again) Endpoint reference: [Withdraw crypto instantly with conversion](/api-reference/endpoints/crypto-withdrawal-instant-exchange) * Merchant is disabled. Endpoint reference: [Create a payment request](/api-reference/endpoints/payments) ## 404 Not Found `404` is returned when a request references something that doesn't exist — a transaction that can't be found, or a currency that isn't recognized. * No transaction found. Endpoint reference: [Get transaction details](/api-reference/endpoints/transactions-info) * The currency.iso is incorrect. * payment\_currency.iso is incorrect. Endpoint reference: [Create a payment request](/api-reference/endpoints/payments) ## 422 Unprocessable Entity `422` covers requests that are well-formed and pass basic validation but fail during processing — an internal error while handling the request, a blockchain/infrastructure issue while issuing an address, or (for payment requests) a broader set of business-rule and field-validation checks. * Internal error (internal\_error) * Something went wrong. Please try later. (internal\_error) * Something went wrong. (internal\_error) Endpoint reference: [Get exchange rates](/api-reference/endpoints/currencies-rates) * Something went wrong, please try again shortly (blockchain\_error) Endpoint reference: [Generate a user deposit address](/api-reference/endpoints/addresses-take) * Internal error (internal\_error) * Something went wrong. Please try later. (internal\_error) * Something went wrong. (internal\_error) Endpoint reference: [Withdraw crypto](/api-reference/endpoints/withdrawal-crypto) * Internal error (internal\_error) * Something went wrong. Please try later. (internal\_error) * Something went wrong. (internal\_error) Endpoint reference: [Get a fixed exchange quote](/api-reference/endpoints/exchange-calculate) * The iso is a mandatory field. * The currency.iso is disabled. * The currency.network\_name field is mandatory for crypto currencies. * The combination of currency and network is not supported. * The amount field is mandatory. * The minimum amount is \ EUR. * The maximum amount is \ EUR. * The amount for \ cannot have more than \ decimal places. * It is obligatory - to fill in life\_time\_date\_time or life\_time\_duration. * Only one of fields life\_time\_date\_time and life\_time\_duration should be field. * The lifespan must be longer than or equal to \ . * The lifespan must be shorter than or equal \ . * The email address is incorrect. * payment\_currency must not be empty if provided. * payment\_currency.iso must be a cryptocurrency. * payment\_currency.iso must not be empty if provided. * payment\_currency.iso is disabled. * Exchange rate is not available between \ and \. * payment\_currency.network\_name must not be empty if provided. * payment\_currency.network\_name cannot be specified without payment\_currency.iso. * The description must be 255 characters or less. * The description must not be empty if provided. * Foreign ID must be 255 characters or less. * The foreign\_id must not be empty if provided. * The url\_store is invalid. * The url\_store must be 255 characters or less. * The url\_success is invalid. * The url\_success must be 255 characters or less. * The url\_failed is invalid. * The url\_failed must be 255 characters or less. * The end\_user\_reference must not be empty if provided. * The end\_user\_reference must be 255 characters or less. * The rate\_mode must be either standard or fixed. * The sender\_type field must be provided when sender\_data is present. * The sender\_type must be either ‘natural’ or ‘legal’. * The sender\_data object must be provided when sender\_type is present. * The sender\_data must be a valid object. * The first\_name must be provided for sender\_type = natural. * The first\_name must be 255 characters or less. * The last\_name must be provided for sender\_type = natural. * The last\_name must be 255 characters or less. * The date\_of\_birth must be in YYYY-MM-DD format. * The legal\_name must be provided for sender\_type = legal. * The legal\_name must be 255 characters or less. * The country\_of\_registration must be provided for sender\_type = legal. * The country\_of\_registration must contain exactly 3 characters. * The country\_of\_registration must be a valid ISO Alpha-3 code. Endpoint reference: [Create a payment request](/api-reference/endpoints/payments) # Introduction Source: https://docs.cryptoprocessing.com/api-reference/introduction This API lets merchants automate key CryptoProcessing operations, such as listing account balances, retrieving supported currencies and exchange rates, generating deposit addresses, making withdrawals, creating payment requests, performing exchanges, and accessing transaction data. It is available at the base URL below, alongside a sandbox environment for testing: ```text Production theme={null} https://app.cryptoprocessing.com/api ``` ```text Sandbox theme={null} https://app.sandbox.cryptoprocessing.com/api ``` Generate the credentials required for authenticated API access. Learn how to authenticate requests with your API key and signature. Register an HTTPS webhook endpoint to receive callbacks about deposits, withdrawals, and other events. Explore and test the API faster with the ready-to-use Postman collection. ## Status page For real-time service availability and incident updates, visit [https://status.cryptoprocessing.com/](https://status.cryptoprocessing.com/). # Postman API Testing Source: https://docs.cryptoprocessing.com/api-reference/postman-collection Postman is a widely used tool for developing and testing APIs. You can use the Postman collection below to test the CryptoProcessing API in the sandbox environment. [Download the Postman collection](/api-reference/SandBox_API_Collection.postman_collection.json) When you click the link, the JSON file opens in a new browser tab rather than downloading automatically. Save it to your computer, then import it into Postman. After importing it, open the **SandBox API Collection** variables and enter: * your API key in the `key-v2` field * your secret key in the `secret-v2` field * your sandbox environment URL in the `url` field Once these values are set, you can start sending requests. The list of supported currencies in the sandbox environment is different from the list in the production environment. # Confirmations and limits Source: https://docs.cryptoprocessing.com/confirmations-and-limits The table below describes **the default values** of operation limits and numbers of required confirmations for the supported currencies. * **Minimum deposit & withdrawal amounts**: see the table below for defaults. Deposits below the configured minimum deposit amount will fail and won’t be credited. No fees will be charged for such deposits. The values can be changed via the Support team. See **Settings → Operation limits** or [/v2/currencies/list](/api-reference/endpoints/currencies-list) for your current limits. * **Confirmation requirements**: see the table below for defaults. Additional confirmations may be required when several blocks are released in a short period of time. * **Minimum exchange amounts**: see [/v2/currencies/rates](/api-reference/endpoints/currencies-rates). | Currency | Confirmations | Minimum deposit | Minimum withdrawal | Explorer | | --------------- | ------------- | --------------- | ------------------ | --------------------------------------------------------------- | | ADA | 15 | 2 | 2 | [cardanoexplorer.com](https://cardanoexplorer.com/) | | BCH | 0\*/2/6\*\* | 0.001 | 0.001 | [explorer.bitcoin.com/bch](https://explorer.bitcoin.com/bch) | | BNB-BSC | 10/25\*\* | 0.01 | 0.01 | [bscscan.com](https://bscscan.com/) | | BTC | 0\*/1 | 0.0001 | 0.0002 | [blockchain.com/explorer](https://www.blockchain.com/explorer) | | DOGE | 3/6\*\* | 1 | 0.01 | [live.blockcypher.com/doge](https://live.blockcypher.com/doge/) | | ETH | 2/10\*\* | 0.002 | 0.002 | [etherscan.io](https://etherscan.io/) | | ETH (Arbitrum) | 12 | 0.002 | 0.002 | [arbiscan.io](https://arbiscan.io/) | | ETH (Base) | 12 | 0.002 | 0.002 | [basescan.org](https://basescan.org/) | | EURC (Base) | 12 | 5 | 5 | [basescan.org](https://basescan.org/) | | EURC (ERC-20) | 2/10\*\* | 5 | 5 | [etherscan.io](https://etherscan.io/) | | EURC (SOL) | 1 | 5 | 5 | [explorer.solana.com](https://explorer.solana.com/) | | EURS (ERC-20) | 2/10\*\* | 0.01 | 0.01 | [etherscan.io](https://etherscan.io/) | | LTC | 2/6\*\* | 0.01 | 0.01 | [live.blockcypher.com/ltc](https://live.blockcypher.com/ltc/) | | POL | 10 | 10 | 10 | [polygonscan.com](https://polygonscan.com/) | | SOL | 1 | 0.05 | 0.05 | [explorer.solana.com](https://explorer.solana.com/) | | TRX | 3/19\*\* | 10 | 10 | [tronscan.org](https://tronscan.org/) | | USDC (ERC-20) | 2/10\*\* | 5 | 5 | [etherscan.io](https://etherscan.io/) | | USDC (Arbitrum) | 12 | 5 | 5 | [arbiscan.io](https://arbiscan.io/) | | USDC (BEP-20) | 10/25\*\* | 5 | 5 | [bscscan.com](https://bscscan.com/) | | USDC (Base) | 12 | 5 | 5 | [basescan.org](https://basescan.org/) | | USDC (POL) | 10 | 5 | 5 | [polygonscan.com](https://polygonscan.com/) | | USDC (SOL) | 1 | 5 | 5 | [explorer.solana.com](https://explorer.solana.com/) | | USDG (ERC-20) | 2/10\*\* | 5 | 5 | [etherscan.io](https://etherscan.io/) | | USDG (SOL) | 1 | 5 | 5 | [explorer.solana.com](https://explorer.solana.com/) | | WBTC (ERC-20) | 2/10\*\* | 0.0001 | 0.01 | [etherscan.io](https://etherscan.io/) | | XED (ERC-20) | 2/10\*\* | 0.01 | 0.01 | [etherscan.io](https://etherscan.io/) | | XRP | 1 | 4 | 0.001 | [xrpscan.com](https://xrpscan.com/) | * Some transactions can be confirmed instantly, see [How deposits are confirmed](/deposits/how-deposits-are-confirmed). * Larger transactions may require additional confirmations before the funds are credited. # Merchant dashboard Source: https://docs.cryptoprocessing.com/dashboard The merchant dashboard is the web interface for viewing and managing your merchant's activity and adjusting various settings. ## Viewing your balances Your balances in different currencies are displayed on the **Balances** tab. For each balance, the tab displays both the actual balance and its equivalent in EUR or USD. Note that the individual balances are shown only for the currencies that are [enabled in the dashboard settings](#currencies). In the top right corner, the total balance is displayed in both the fiat equivalent and BTC equivalent. The total balance is calculated based on both enabled and disabled currencies. Click on a balance to see available operations: [send](/withdrawals) and [receive](/deposits) (for crypto), [withdraw](/fiat/top-up-fiat) and [top up](/fiat/withdraw-fiat) (for fiat), [exchange funds](/exchanges). Balances tab To choose the equivalents currency, click **Account** in the left panel, find the equivalents currency and click **Change**. ## Enabling and disabling currencies You can choose which currencies should be available for manual operations in the merchant dashboard. This will affect the **Balances** tab and all dialogs for creating new addresses, initiating new withdrawals, etc. This will not affect the existing [transactions history](#viewing-transactions-history) or the available currencies in the [CryptoProcessing API](/api-reference). Click on the **Balances** tab or go to the **Settings → Currencies Info** tab where you can manage currencies. * To enable a new currency, click **Add New Currency**, select it and click **Save**. * To disable or enable a previously added currency, use the toggle next to it. Currencies Info tab ## Generating statements On the **Balances** tab, click **Generate statements** to get a PDF statement about your balances and operations. The statements include both enabled and disabled currencies. There are three types of statements available: * The **Balances** statement shows your balances in all currencies at the current time or at the end of a specific day. By default, this statement only shows non-zero balances. Zero balances can be included if you click the corresponding toggle in the statement generation form. * The **Fees** statement shows how much funds was deducted as fees from your balances between two specific dates. The fees are grouped by their type and currency. * The **Cashflow** statement shows how much funds was sent or received to your balances between two specific dates. The operations are grouped by their type and currency. This statement also includes the **Fees** statement for the same period. ## Viewing transactions history There are two main ways to view history in the merchant dashboard. The **Transactions** tab provides a high-level view of merchant activity. Each transaction is displayed as a single record representing the complete operation, regardless of how many balance movements or processing steps were involved. The list of transactions includes [deposits](/deposits), [payment requests](/payment-requests), [withdrawals](/withdrawals) and [exchanges](/exchanges), including the cancelled or pending ones. For each transaction, a side panel displays detailed information, such as the destination address, the fees paid, and the corresponding [API callback](/api-reference/callbacks). Transactions tab The **Payments** tab provides a detailed view of balance movements. It shows each underlying operation separately, allowing merchants to see exactly how a transaction affected their balances. Cancelled or pending actions are not represented on this tab. Fees are displayed as separate entries, as sometimes a fee payment may affect a different balance than the main payment. Payments tab Both the **Transactions** and **Payments** tabs provide filters for finding the entries you need and an **Export** button for downloading the filtered entries as a CSV file. There are also dedicated tabs for [payment requests](/payment-requests) and [mass payouts](/mass-payouts). # Design a crypto payment form Source: https://docs.cryptoprocessing.com/deposits/design-payment-form Here are some tips for creating a convenient payment form for customers on your site. To make it easier for your customers to make deposits, add a **Copy address** button to your payment form. We recommend that you generate a QR code with the crypto address. This way, your customer will be able to scan the QR code with their phone and pay in their wallet app. CryptoProcessing does not generate address QR codes automatically, but you can use any tools you prefer. Deposits under the minimum amount will not be recognised and credited by CryptoProcessing. Make sure your customers can clearly see the minimum deposit amount on the payment form. For more information on minimum deposit amounts, see [Confirmations and limits](/confirmations-and-limits). If your customer sends a deposit in the wrong currency or on the wrong network, their crypto can be lost or difficult to recover. We recommend highlighting the address's currency and network, as well as the minimum deposit amount, on your payment form. For more details on how to handle cross-chain deposits, see [Handle deposits sent in the wrong currency](/deposits/recovery). Crypto Deposit Form # Crypto deposit fees Source: https://docs.cryptoprocessing.com/deposits/fees ## Processing fee For each incoming deposit, a *processing fee* may be subtracted from your account. The fees are listed on the **Fees** tab in your merchant dashboard, under the **Deposit operations** section. The exact fee may depend on the currency and on whether the payment involved a conversion between different currencies. For deposits with conversion, processing fees are typically charged in the target currency. Each fee has a minimum amount that will be subtracted regardless of the transaction amount. The applicable fees are: * **Deposit crypto** * **Deposit crypto exchange to crypto** * **Deposit crypto exchange to fiat** * **Crypto Bankroll top up** (for deposits on [merchant top-up addresses](/deposits#merchant-top-up-addresses)) When a deposit is being processed [off-chain](/deposits#off-chain-deposits), the system uses the fees with "internal" in the name: * **Deposit crypto internal** * **Deposit crypto exchange to crypto internal** * **Deposit crypto exchange to fiat internal** * **Crypto Bankroll top up internal** ## Transfer fee for Ethereum When receiving ETH funds or ERC-20 tokens, a *transfer fee* is subtracted from the merchant’s balance, in addition to the [processing fee](#processing-fee). The transfer fee covers the cost of *gas* in the Ethereum network. The transfer fee amount depends on the current gas price when the deposit is being processed. It is subtracted in the same currency as the deposit itself: for example, the transfer fee for a USDC deposit will be in USDC. You can see this fee as **Fee transfer** in a deposit's details panel. ## Minimum deposit fee CryptoProcessing uses different policies to set minimum deposit fees for different networks, depending on the expected volatility of each network. * For BTC, ETH and all ERC-20 tokens, the minimum deposit fee is updated dynamically, no more than one time per week. Every Monday, we check the [BTC average mining fee](https://www.blockchain.com/explorer/charts/fees-usd-per-transaction) and [ETH average rate](https://coinmarketcap.com/currencies/ethereum/eth/eur/) for the previous week, beginning and ending at 00:00 UTC on Monday. These values determine the new minimum deposit fees, according to a predictable set of rules in your contract with CryptoProcessing. If the new fees differ from the last week's ones, we notify all users about it and switch to the new minimum deposit fees at 10:00 UTC on Wednesday. * For all other currencies, the minimum deposit fee is specified in your contract with CryptoProcessing. # How deposits are confirmed Source: https://docs.cryptoprocessing.com/deposits/how-deposits-are-confirmed Typically, a successful crypto deposit is processed in two main steps (see [Statuses](/deposits/statuses) for more details): 1. When an incoming transaction appears in the blockchain, CryptoProcessing shows it on the **Transactions** tab with the status and sends a [not\_confirmed](/api-reference/callbacks/deposit-callbacks#processing) callback. 2. When the transaction gets the required [number of confirmations](/confirmations-and-limits), CryptoProcessing changes its status to , sends a [confirmed](/api-reference/callbacks/deposit-callbacks#confirmed) callback and adds the funds to the merchant's balance. However, for BTC and BCH, **instant confirmations** are possible. Unlike the standard process, an instant confirmation produces the status and the [confirmed](/api-reference/callbacks/deposit-callbacks#confirmed) callback immediately, without waiting for the actual confirmations in the blockchain. We assume the risk associated with accepting the funds before on-chain confirmation. When you receive the [confirmed](/api-reference/callbacks/deposit-callbacks#confirmed) callback, it is safe to perform business actions such as crediting your customer’s balance on your site, regardless of the number of confirmations in the blockchain. If you get a [not\_confirmed](/api-reference/callbacks/deposit-callbacks#processing) callback, it means that CryptoProcessing cannot accept the deposit instantly and will wait for the confirmations in the blockchain. In this case, do not credit your customer balance until you receive the [confirmed](/api-reference/callbacks/deposit-callbacks#confirmed) callback. We recommend displaying the transaction on your site as “Pending” or “Processing”. # Crypto deposits Source: https://docs.cryptoprocessing.com/deposits/index Deposits are a way for your customers to send you arbitrary amounts of cryptocurrency. Whenever they do so, funds will be added to your balance in CryptoProcessing. Typically, at this point you may want to add the received amount to the customer's balance on your site. To start receiving deposits, create a [deposit address](#types-of-deposit-addresses) and give it to your customer. CryptoProcessing constantly monitors the blockchain for new transactions to all deposit addresses ever created. Your balance is updated as soon as the transaction gets the required number of [confirmations](/confirmations-and-limits). Optionally, CryptoProcessing can perform [automatic conversion](#deposits-with-conversion) of the received funds to another currency. [Fees](/deposits/fees) and [minimal deposit amounts](/confirmations-and-limits) apply. ## Types of deposit addresses CryptoProcessing processes crypto deposits in different ways, based on the way the deposit address was created. System deposit addresses are created and intended to be used as part of an [automated integration](/deposits/integration-guide) with your site. Typically, your site may generate and show an address to each customer, so that they top up their balance on your site. To create such an address, use the [API endpoint](/api-reference/endpoints/addresses-take). Enable [automatic conversion](#deposits-with-conversion) if necessary. Each incoming transaction to the address will trigger an [API callback](/api-reference/callbacks/deposit-callbacks). In the merchant dashboard, these addresses can be found at **Addresses → System Addresses**. Customer deposit addresses are created and managed by you in **Addresses → My Addresses**. You manually provide such address to your customer, so that they top up their balance on your site. Each address can have a name for easier search, e.g., "Deposits from John Doe". To create such an address, go to the **Addresses → My Addresses** tab and click **Create address**. Alternatively, select a cryptocurrency on the **Balances** tab, click **Receive**, then click **Create new address**. Enable [automatic conversion](#deposits-with-conversion) if necessary. CryptoProcessing does not send API callbacks for the transactions to customer deposit addresses. Merchant top-up addresses are generated automatically when you enable a new cryptocurrency in your merchant dashboard. You can use these addresses to top up your balance. These addresses can be found at **Addresses → My Addresses** under the names "BTC deposit address", "ETH deposit address", etc. Alternatively, select a cryptocurrency on the **Balances** tab, click **Receive** and see the default address. Transactions to these addresses may have different [fees](/deposits/fees) than to the other addresses. These addresses are intended for usage by the merchant team only. You must not share the merchant top-up addresses with your customers. CryptoProcessing does not send API callbacks for the transactions to merchant top-up addresses. ## Deposits with conversion When creating a deposit address in one currency, you can enable automatic conversion of all incoming funds. If enabled, the amount of each deposit to this address will be instantly converted to the specified target currency. [Processing fees](/deposits/fees) are typically charged in the target currency. Enabling conversion is possible for system addresses and customer deposit addresses (see [Types of deposit addresses](#types-of-deposit-addresses)). The target currency can be crypto or fiat. Each conversion is made using the current currency rates at the time of processing the transaction. ## Reusing addresses In cryptocurrencies, an address cannot be "deleted" or "closed": once you created it, your customer can send funds to the address at any time. CryptoProcessing constantly monitors the blockchain for new transactions to all deposit addresses ever created. It is good practice to have only one deposit address for one currency per user. This way, the customer can save the address in their wallet app's address book to create new transactions in a more convenient way. However, you can create more than one deposit address per customer. This is useful if you need to use different [conversion](#deposits-with-conversion) configurations or if your customer has two different balances on your site. Reusing the same deposit address between different customers can be a violation of regulation, see [User data collection](/user-data-collection). ## Off-chain deposits If the funds come from an address that happens to be controlled by CryptoProcessing, too, the transaction is being processed *off-chain*. This means that CryptoProcessing registers the transaction internally, even though it was never sent to the blockchain. Just like a standard deposit, an off-chain deposit can be found on the **Transactions** tab. However, an off-chain deposit has an internal **TXID** instead of a public one. You can use this **TXID** to find the internal transaction in the merchant dashboard, but not in a blockchain explorer. In the [API callback](/api-reference/callbacks/deposit-callbacks), an off-chain deposit has the `transaction.transaction_type` property set to `"internal"` instead of `"blockchain"`. The [fee](/deposits/fees) for an off-chain deposit may differ from the standard one. ## Further reading Learn how to integrate the deposit flow into your site Walk through all scenarios to make sure your integration works correctly API endpoint API callbacks # Crypto deposits integration guide Source: https://docs.cryptoprocessing.com/deposits/integration-guide You can receive crypto deposits from your customers with and without automatic conversion. Deposits with conversion are automatically converted to your preferred currency. ## Set up crypto deposits Configure your account and get an API key, see [Initial setup](/initial-setup). Send a request to [/v2/addresses/take](/api-reference/endpoints/addresses-take) and get a crypto deposit address. You can reuse an address if the same customer is making another deposit in the same currency. We recommend using one address for each user. ```json title="Request example" theme={null} { "currency": "BTC", "convert_to": "EUR", "foreign_id": "user_12345", "end_user_reference": "user_12345", "sender_type": "legal", "sender_data": { "legal_name": "Example GmbH", "country_of_registration": "DEU" } } ``` ```json title="Response example" theme={null} { "data": { "id": 240407212, "currency": "BTC", "convert_to": "EUR", "address": "tb1qezlewt2mx36azu5qyx9yff7565z0u9p94vn2ha", "tag": null, "foreign_id": "user_12345", "end_user_reference": "user_12345" } } ``` Your customer will see their deposit address in your [payment form](/deposits/design-payment-form). Once your customer makes the deposit, CryptoProcessing will send you a callback. You will then need to update your customer's balance on your site. # Recover lost deposits Source: https://docs.cryptoprocessing.com/deposits/recovery Some deposits may not show on your balance automatically or might be lost. Some of these cases can be processes automatically by CryptoProcessing or recovered manually by the CryptoProcessing team. ## Deposits that are on the same network Deposits in these currencies will be credited to your balance automatically. For deposit addresses with exchange, deposits in the wrong currency will also not be exchanged. | Network | Currencies that share this network | | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | Ethereum, Polygon and BNB Smart Chain (EVM-compatible chains) | ETH, POL, USDC (ERC-20), USDC (POL), USDG (ERC-20), BRZ (ERC-20), WBTC (ERC-20), VERSE (ERC-20), XED (ERC-20), BNB-BSC | | Solana | SOL, USDC (SOL), USDG (SOL) | These deposits sent without a tag will not be credited to your balance automatically. To recover your deposit, contact our support team at [support@cryptoprocessing.com](mailto:support@cryptoprocessing.com) or using the widget in your merchant dashboard. | Network | Currencies that share this network | | ------- | ---------------------------------- | | Ripple | XRP | If the address is meant for deposits with exchange, deposits in the wrong currency will not be exchanged. For example, if you created an ETH address with conversion to EUR, a USDC ERC-20 deposit sent to this address will not be automatically converted to any currency. You will receive the currency that you or your customer deposited, without conversion. ## Deposits within the same network All deposits sent to your EVM-compatible addresses (starting with `0x`) will be bridged to the correct chain and credited to your balance automatically. However, they will not be automatically exchanged. This applies to Ethereum and Binance Smart Chain. If you received a deposit in the wrong currency on the same network that is supported by CryptoProcessing, it will still appear on your balance. For example, if you generate an Ethereum address for ETH and your customer sends USDC ERC-20 to it, you will still see the USDC deposit on your balance. You can manually convert the customer's deposit to your currency of choice (see [Exchanges](/exchanges)) and credit their balance on your site. To see transactions that were sent in the wrong currency, go to **Transactions** in your merchant dashboard. Click **Filters** to expand the filter section and select **Only cross-currency** from the Cross-currency dropdown list. To find a specific transaction, enter its TXID (the transaction's hash on the blockchain). All cross-currency transactions will have *Cross currency deposit* in the Note field. ## Deposits in unsupported currencies You will not see deposits in unsupported currencies in your merchant dashboard. For example, this applies to all unsupported ERC-20 tokens sent to your Ethereum address, unsupported SPL tokens sent to your Solana address and other similar cases. The deposits will be credited to the address on the blockchain, but you will not see them on your balance in your CryptoProcessing merchant dashboard. To see if your deposit can be recovered, contact our support team at [support@cryptoprocessing.com](mailto:support@cryptoprocessing.com) or using the widget in your merchant dashboard. ## XRP deposits sent without a tag or with the wrong tag XRP deposits sent without a tag or with the wrong tag will not be credited to you automatically. To see if your deposit can be recovered, contact our support team at [support@cryptoprocessing.com](mailto:support@cryptoprocessing.com) or using the widget in your merchant dashboard. ## Deposits across different networks If your customer sent a deposit on the wrong network (for example, BTC to an Ethereum address), you will not be able to access it. The only exceptions are Ethereum and Binance Smart Chain. As these are EVM-compatible networks, deposits can be seamlessly bridged between them. To prevent this in future, always clearly specify the currency name and network when you share the address with your customers. You should also notify customers that deposits sent to the wrong address cannot be recovered, so they should always double-check the currency and the network before they send a transaction. To see if your deposit can be recovered, contact our support team at [support@cryptoprocessing.com](mailto:support@cryptoprocessing.com) or using the widget in your merchant dashboard. # Risk scoring Source: https://docs.cryptoprocessing.com/deposits/risk-scoring When a crypto transaction uses funds that are linked to previous suspicious transactions, it is often possible to see that in the blockchain. CryptoProcessing automatically performs such an analysis for deposits in certain currencies. The results are two informational fields that you can see: * **Risky inflow** — the amount of funds (in USD equivalent) that have originated from transactions that can be considered suspicious. * **Risk score** — the percentage of suspicious inputs or addresses among their total number. Both fields are available: * in each [API callback](/api-reference/callbacks/deposit-callbacks) for types `deposit` and `deposit_exchange`, * in each deposit's details on the **Transactions** tab in the [merchant dashboard](/dashboard). Risk scoring is supported for **BTC, BCH, ETH, and LTC**. It is recommended to manually inspect the transactions with a risk score of about 75% or higher. The risk score is included for informational purposes only. CryptoProcessing does not claim any responsibility for any actions or decisions made based on the provided risk score. # Deposit statuses Source: https://docs.cryptoprocessing.com/deposits/statuses This section describes the statuses displayed in the merchant dashboard for deposits.
Status Description
The deposit is under review. Contact your account manager in case of any questions.
The transaction is waiting for the required [number of confirmations](/confirmations-and-limits).
Once it gets the confirmations, the transaction will become .
The transaction got the required [number of confirmations](/confirmations-and-limits). The funds are credited to the merchant's balance.
The transaction cannot be completed. The specific error is shown in the transaction's details panel on the **Transactions** tab.
One possible error is *"Deposited funds less than the lower limit"*, which refers to the minimum withdrawal limit from [Confirmations and limits](/confirmations-and-limits).
The transaction was cancelled by CryptoProcessing due to some other error. The specific error is shown in the transaction's details panel on the **Transactions** tab.
# Tag field Source: https://docs.cryptoprocessing.com/deposits/tags For most cryptocurrencies, the only field a user needs to specify the recipient is an address. This address can be displayed in your interface directly or encoded as a QR code. But sometimes the address is not enough for a successful payment. For example, Ripple has a concept of “multiuser addresses” which require a tag field to distinguish between recipients. Sometimes this concept is also known as the “memo” field. CryptoProcessing provides the tag field for Ripple addresses both in the merchant dashboard and in the API. In other cryptocurrencies, this field may also be known as “Memo”, “Comment”, “Label”, or “DigitalID”. When using deposits for such a currency, make sure you provide the user with both the address and the tag field. The absence of the tag field may result in the loss of the funds sent by the user. # Crypto deposits integration test cases Source: https://docs.cryptoprocessing.com/deposits/test-cases These are the test cases to help you test your site's integration with CryptoProcessing [crypto deposits](/deposits/integration-guide). For each test case, create a new deposit address via the [/v2/addresses/take](/api-reference/endpoints/addresses-take) endpoint and then process the relevant [callback](/api-reference/callbacks/deposit-callbacks). You can test deposits in the sandbox environment by withdrawing funds from your merchant account instead of sending an external payment. Generate a deposit address, then [withdraw funds](/withdrawals/create-a-withdrawal) to that address.
Procedure Expected results
**Successful deposit**
1. Create a deposit address without exchange. 2. Copy the address into a wallet on your device. 3. Place a payment. Make sure its amount is equal or higher than the [minimum deposit](/confirmations-and-limits). * The site gets two `deposit` callbacks. * The callback status is first `not_confirmed`, then `confirmed`. * `currency_sent` describes the amount you sent (minus the network fee). * `currency_received` describes the amount you received on your balance.
**Cross-currency deposit**
1. Go to **Settings → Callbacks** and make sure the **Cross-currency deposits** callback is enabled. 2. Create a deposit address for one currency, e.g., USDC on the Ethereum network. 3. Copy the address into a wallet on your device. 4. Place a payment in a different currency on the same network, e.g., ETH. Make sure its amount is equal or higher than the [minimum deposit](/confirmations-and-limits). * The site gets two `deposit` callbacks. * The callback status is first `not_confirmed`, then `confirmed`. * `crypto_address.cross_currency` is true. * `currency_received.currency` is different from `expected_currency`.
**Deposit below minimum amount**
1. Go to **Settings → Callbacks** and make sure the **Deposits less than minimum amount** callback is enabled. 2. Create a deposit address. 3. Copy the address into a wallet on your device. 4. Place a payment lower than the [minimum deposit](/confirmations-and-limits). * The site gets two `deposit` callbacks. * The callback status is `cancelled`. * The error is `Transaction amount less than minimum deposit`.
# Create an exchange Source: https://docs.cryptoprocessing.com/exchanges/create-an-exchange You can exchange funds between supported currencies — crypto to crypto, crypto to fiat, or fiat to crypto — directly from your merchant dashboard. Enter an amount in the **Spend** field to specify how much of your selected currency to exchange, or in the **Get** field to specify how much of the target currency you want to receive. Review the exchange rate, fee, and final amount before proceeding. The exchange rate is fixed for one minute. If you accept before the timer expires, you receive the exact amount shown. If the timer runs out, a new rate is calculated and fixed for another minute. Click **Cancel** to cancel the exchange. # Exchange fees Source: https://docs.cryptoprocessing.com/exchanges/fees For each exchange, a fee will be subtracted from your account. The fees are listed on the **Fees** tab in your merchant dashboard, under the **Exchange** section. Each fee has a minimum amount that will be subtracted regardless of the transaction amount. The applicable fees are: * **Exchange buy crypto for fiat** * **Exchange sell crypto for fiat** * **Exchange crypto to crypto** # Exchanges Source: https://docs.cryptoprocessing.com/exchanges/index You can exchange different currencies, both crypto and fiat, within your merchant's account. This operation can be performed both [via the merchant dashboard](#exchanges-via-the-merchant-dashboard) and [via the API](#exchanges-via-the-api). To learn which currencies can be exchanged to which currencies, see [Supported trading pairs](/supported-trading-pairs). Each trading pair is bidirectional. [Fees](/exchanges/fees) and minimal amounts apply. To learn the minimal amounts, see [/v2/currencies/pairs](/api-reference/endpoints/currencies-pairs). ## Exchanges via the merchant dashboard In the merchant dashboard, an exchange can be performed on the **Balances** tab by selecting a balance and clicking **Exchange** on the right panel. In a dialog that appears, select the two currencies and specify the amount in either one of them. The other amount will be calculated automatically using the current exchange rate. Click **Exchange** to fix the rate, then click **Accept** within 60 seconds to perform the exchange. Exchange ## Exchanges via the API The fastest way to perform an exchange using the CryptoProcessing API is by calling [/v2/exchange/now](/api-reference/endpoints/exchange-now). This will immediately subtract funds from one balance and add to the other, using the current exchange rate. You will find the information about the used rate both in the API response and in the [callback](/api-reference/callbacks/exchange-callbacks). Another way is a two-step operation: find an exchange rate using [/v2/exchange/calculate](/api-reference/endpoints/exchange-calculate) and, if you agree with it, use it in parameters for [/v2/exchange/fixed](/api-reference/endpoints/exchange-fixed). The second call must be done within 60 seconds after the first one. You will also receive the [callback](/api-reference/callbacks/exchange-callbacks). # Add a bank account Source: https://docs.cryptoprocessing.com/fiat/add-a-bank-account Before you can make withdrawals from your fiat balances, you need to add a bank account. You will be prompted for your bank account details. Once submitted, CryptoProcessing will review your bank account details. This usually takes **24 to 48 hours**. If necessary, our compliance team may request additional documents through your account manager. When your account is verified, you can use it to withdraw fiat funds from your merchant account. # Fiat operation fees Source: https://docs.cryptoprocessing.com/fiat/fees For each fiat operation, a fee will be subtracted from your account. Each fee has a minimum amount that will be subtracted regardless of the transaction amount. For fiat deposits and withdrawals without exchange, the fee depends on the payment method that you use. Applicable fees are listed on the **Fees → Fiat** tab as: * **Top up fiat ‹method›** * **Withdrawal fiat ‹method›** Fiat top-ups via crypto are processed the same way as [deposits with conversion](/deposits#deposits-with-conversion). Applicable fees are listed on the **Fees → Crypto** tab as: * **Deposit crypto exchange to fiat** * **Deposit crypto exchange to fiat internal** (for [off-chain deposits](/deposits#off-chain-deposits)) # Top up your fiat balance Source: https://docs.cryptoprocessing.com/fiat/top-up-fiat Before sending a bank transfer, you must first create a top-up order in CryptoProcessing and specify the amount. Once the order is created, retrieve the generated transaction ID (TXID) and include it in the transfer details when sending from your bank. When you top up with crypto, all crypto payments are automatically converted to the fiat currency you selected. * For a **bank transfer** — you will see the bank details to send a transfer to in your bank app of choice. * For **crypto** — you will see the wallet address to send the transaction to. You can track pending crypto transactions on the **Transactions** in the merchant dashboard. # Withdraw from your fiat balance Source: https://docs.cryptoprocessing.com/fiat/withdraw-fiat If you have not previously provided a BRL (bank reference letter), it will need to be submitted before your first withdrawal can be processed. Your account manager will reach out with more information. # Important notice Source: https://docs.cryptoprocessing.com/important-notice Dream Finance OÜ’s application for authorisation as a Crypto-Asset Service Provider (CASP) under Regulation (EU) 2023/1114 (MiCA) remains under review by the Estonian Financial Supervision and Resolution Authority (EFSA), and no final decision has been issued. Following the end of the transitional period for virtual asset service providers in Estonia, and reflecting the approach published by the Estonian Financial Supervision and Resolution Authority and the Money Laundering Data Bureau, Dream Finance OÜ has restricted its active activities pending the outcome of its authorisation application. Accordingly, the Company does not onboard new clients, open new accounts, enter into new client agreements, or expand the scope of services provided to existing clients. Existing clients may continue to use the services provided under their existing contractual arrangements and may request the withdrawal or transfer of their assets, or terminate their contractual relationship with the Company at any time, subject to applicable legal and regulatory requirements. The Company continues to maintain appropriate operational, compliance, risk management, security, and safeguarding arrangements. Client assets remain segregated from the Company’s own assets in accordance with applicable safeguarding requirements. Any information available on this website is provided for informational purposes only and shall not be construed as an offer, solicitation, invitation, or indication that regulated services are available to new clients or to persons other than existing clients under their existing contractual arrangements. # CryptoProcessing Documentation Source: https://docs.cryptoprocessing.com/index This is the documentation for CryptoProcessing by Coinspaid. It covers the merchant dashboard — the web interface where you manage your account, balances, and settings — and the API, which you can use to integrate deposits, payment links, withdrawals, mass payouts, and exchanges directly into your own systems. See the full list of supported cryptocurrencies, networks, and fiat. Required confirmations and minimum deposit & withdrawal amounts per currency. ## Common use cases
Via the API or in the dashboard. Show it to your customer as an address and QR code. They can pay to the same address any number of times; we pick up the transaction right away. Your balance updates once the required confirmations are reached on-chain. Learn more about crypto deposits →
Deposit flow: the merchant requests a deposit address, the customer sends funds to it, and the balance is credited once the required confirmations are reached
Set the amount, the currency you want, and the lifespan. They complete it on a hosted page showing the payment details and available options. Once confirmed, the rate is locked and conversion is handled for you. Learn more about payment requests →
Payment request flow: the merchant creates a payment link, the customer pays on the hosted page, and the payment is confirmed by callback
They enter a destination address in your withdrawal form. One API call moves funds from your balance to that address on-chain. Once confirmed, show the transaction ID (TXID) to your customer. Learn more about crypto withdrawals →
Withdrawal flow: the customer initiates a withdrawal, the merchant sends it via the API, and a callback returns the transaction ID
## More features Swap between crypto and fiat currencies within your merchant account, via the dashboard or API. Disburse crypto to many recipients at once. Supports multiple currencies and amounts in a single batch. Fund your fiat balance via bank transfer or crypto. Create a top-up order first, then send the transfer from your bank. Withdraw funds from your fiat balance to a verified bank account directly from the merchant dashboard. ## Merchant account setup Add or remove users, assign roles, and set up login and 2FA. Withdrawal limits, balance notifications, and other safeguards. Generate an API key and register a callback URL. ## Compliance What customer data you need to collect and why. # Initial setup Source: https://docs.cryptoprocessing.com/initial-setup Complete these steps before you start your integration. Before you can send your first API request, you need to activate your account, secure it, and configure a few settings in your merchant dashboard. Activate your account using the invitation email and set up two-factor authentication with an authenticator app. Set withdrawal limits, configure balance notifications, and automate transfers to cold addresses to protect your funds. Generate and activate your API key and secret key. You'll need these to authenticate every API request. Register an HTTPS webhook endpoint where CryptoProcessing will send event callbacks for deposits, withdrawals, and payments. Learn how to sign requests using your API key and secret key, and avoid common authentication errors. Use the List supported currencies endpoint to verify your API key is working and explore what's available in your environment. # Create a mass payout Source: https://docs.cryptoprocessing.com/mass-payouts/create-a-mass-payout Mass payouts let you initiate multiple outgoing crypto transactions at once by uploading a CSV file. Each row in the file creates a separate transaction. Before you begin, prepare your CSV file according to the [required format](/mass-payouts/file-format). Choose **In cryptocurrency** for a standard payout, or **With conversion** to convert funds from one currency to another before sending. If CryptoProcessing detects an error in a row, an exclamation mark appears next to it. Hover over it to see the error message. Fix any errors in your file and click **Reupload file** to upload it again. This shows the total withdrawal amount and a subtotal for each currency, as well as the equivalent in EUR or USD. Note that the fiat equivalent amounts are informational — actual costs may vary once fees are applied. You can track the [status](/mass-payouts/statuses) of your mass payout on the **Mass Payouts** tab. If any transactions fail, see [Retrying failed mass payouts](/mass-payouts/retrying). # Mass payouts file format Source: https://docs.cryptoprocessing.com/mass-payouts/file-format To make a mass payout, you need to prepare a CSV file describing all the transactions you want to make. The file must contain no more than **500 data rows**, and its size must not exceed **1 MB**. The file must start with a header row that lists these columns in the specified order. Each data row must contain five values, separated by either commas or semicolons. * **Address** — the recipient's address. * **Tag** — the recipient's [Tag field](/deposits/tags). Leave empty for currencies that do not require a Tag field. * **Currency** — the ISO code of the currency to send. * **Amount** — the amount of funds to send. * **Note** — a note to save in the [transaction history](/dashboard#viewing-transactions-history). Leave empty to skip adding a note for the transaction. ```csv sample.csv theme={null} Address,Tag,Currency,Amount,Note bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq,,BTC,0.0025,Salary for Alice 0x59E497D1AEf6B696B66F503D85d9b29A0e2930E8,,USDC,120.20,Salary for Bob r9NEXKYNyfxhzw7VzJp9et8t3onbam98G,2422386,XRP,400,Salary for Charlie ``` * **From Currency** — the currency you want to convert from. * **Amount to Send** — the amount of funds to send. Fill in either this field or the Amount to Receive. * **Address** — the recipient's address. * **Tag** — the recipient's [Tag field](/deposits/tags). Leave empty for currencies that do not require a Tag field. * **To Currency** — the currency you want to convert to. * **Amount to Receive** — the amount the recipient will receive. Fill in either this field or the **Amount to Send**. * **Note** — a note to save in the [transaction history](/dashboard#viewing-transactions-history). Leave empty to skip adding a note for the transaction. ```csv sample_with_conversion.csv theme={null} From Currency,Amount to Send,Address,Tag,To Currency,Amount to Receive,Note EUR,100,bc1q5ek0zq6dn4delgxnu5va0ttmlmgkgx3r04xare,,BTC,,Salary for Alice EUR,,0x7382FD00Ed0EF743044977D81673D7B87b87082C,,USDC,200,Salary for Bob ETH,1,rPpGnDVzyfqJhjn2bybATLQxsDx1QfdU6c,1278637,XRP,,Salary for Charlie ``` Only fill in either the **Amount to Receive** or the **Amount to Send**. CryptoProcessing will calculate the other value automatically. If you include both fields, you will get an error message. # Mass payouts Source: https://docs.cryptoprocessing.com/mass-payouts/index The **Mass Payouts** tab provides an interface for initiating multiple outgoing crypto transactions at a time. This can include transactions of different amounts made in different cryptocurrencies. Initiating a mass payout involves processing a special CSV file and creating a transaction based on each data row. Each transaction will then be processed in accordance with the general transaction flow, with the mass payout getting its status based on all the transactions' statuses. Mass Payouts Being an alternative interface to [withdrawals](/withdrawals), this feature works within the same limitations as they do. For example, each individual transaction in a mass payout may be a subject to your merchant's [interface withdrawal limits](/merchant-administration/configure-withdrawal-limits). ## Mass payouts with and without conversion There are two types of mass payouts available, with and without currency conversion. If you have crypto on your balance and want to simply transfer it to the recipient, choose standard mass payouts. If you have fiat (for example, EUR) and the recipient prefers crypto, you can make a fiat transfer and have it converted to the recipient's cryptocurrency of choice automatically. # Retrying failed mass payouts Source: https://docs.cryptoprocessing.com/mass-payouts/retrying For a mass payout with at least one failed item in it (either a failure in creating a transaction or an unsuccessful transaction), the panel in the merchant dashboard contains the **Export unsuccessful transactions** button. Click the button to download a modified version of the original CSV file, with all successful transactions removed. The button for downloading the file appears as soon as at least one failure occurs during the mass payout. The file may change after that if more transactions will be unsuccessful. Unsuccessful Mass Payouts Besides the original data, the file contains additional columns: * **Status** — either the status of an unsuccessful transaction (, , ) or if CryptoProcessing failed to create a transaction based on this data row. * **Error** — an error message explaining why the transaction was unsuccessful. If you believe that the cause of the errors is fixed (you added more funds to your balances, you added a missing Tag field, etc.), you can remove the **Status** and **Error columns** from the CSV file and use it for initiating a new mass payout. # Mass payout statuses Source: https://docs.cryptoprocessing.com/mass-payouts/statuses This section describes the statuses displayed in the merchant dashboard for mass payouts.
Status Description
Some or all transactions are and require manual moderation by the merchant team.
Some or all transactions are still .
All transactions are .
Some or all transactions failed. See [Retrying failed mass payouts](/mass-payouts/retrying).
# Add a user Source: https://docs.cryptoprocessing.com/merchant-administration/add-a-user Add users to your merchant account and assign roles that match their responsibilities. This page explains how to choose the right role, invite a new user, and request **Owner** access when needed. ## Determine which role to use User roles define what each user can see and do in the merchant dashboard. Roles marked **By request only** cannot be assigned directly from the dashboard. Contact your account manager to assign them. For users who need read access to account activity, with a limited set of transactional actions. * View account balance, account information, fees, cold addresses, transactions, payments, invoices, payment requests, mass payouts, withdrawal and operation limits, team members, and contacts * Manage deposit addresses * Resend transaction callbacks * Create payment requests and invoices For users who need to convert funds between currency balances. * All **View** permissions * Exchange funds For users who configure withdrawal thresholds and cold wallet transfer rules. * All **View** permissions * Manage keep-on-hot limits * Manage the minimum transaction amount for automatic transfers to cold wallets For users who initiate crypto withdrawals and payouts but should not be able to approve them. For the **Submitter** role to function as intended, withdrawal limits must be configured. If no limits are configured, or if a withdrawal amount does not exceed the configured limit, withdrawals created by a **Submitter** will be processed immediately without requiring approval. * All **View** permissions * Create crypto withdrawals * Create mass payouts For users who approve withdrawals but should not be able to initiate them. * All **View** permissions * Approve or decline withdrawals that require manual approval For users who manage fiat operations and bank accounts. * All **View** permissions * Create fiat withdrawals * Create fiat top-ups * View and add bank accounts For users who manage both crypto and fiat operations. For the **Accounts Payable** role to function as intended, withdrawal limits must be configured. If no limits are configured, or if a withdrawal amount does not exceed the configured limit, withdrawals created by an **Accounts Payable** user will be processed immediately without requiring approval. * All **View** permissions * Create fiat withdrawals * Create fiat top-ups * View and add bank accounts * Create crypto withdrawals * Create mass payouts * Exchange funds Full access to the merchant account and all dashboard sections. * Includes permissions from all other roles * Add and remove users, and update user roles * Manage API keys * Configure callbacks, notifications, and withdrawal limits * Manage cold addresses * Manage active currencies (shown on the **Balances** tab) * Withdraw funds * Create fiat top-up orders * Configure withdrawal limits * Approve withdrawals that exceed the withdrawal limit * Create mass payouts No access to the merchant dashboard. Can contact the Support team and create tickets. ## Add a new user Follow these steps to add a new user: The user will receive an invitation email at this address with instructions on how to activate their account. Refer to the section above for information about user roles. The **Owner**, **Submitter**, **Approver**, and **Accounts Payable** roles can only be assigned by contacting your account manager. To create a user with one of these roles, first create the user with the **View** role, then contact your account manager and provide the user's email address. The user will receive an email with their login and temporary password. For instructions on initial account setup, refer to [Log in and configure 2FA](/merchant-administration/log-in-and-configure-2-fa). ## FAQ ### How do I add a user with the Owner, Submitter, Approver, or Accounts Payable role? First, create a new user with the **View** role. Then, contact your account manager to assign the role to this user. For the **Owner** role, you will be asked to complete a special authorization form before the role is granted. ### Why can't a Restricted user access the merchant dashboard? Users with the **Restricted** role do not have access to the merchant dashboard and are logged out immediately after entering their credentials. Users with the **Restricted** role only have access to the help center. # API configuration Source: https://docs.cryptoprocessing.com/merchant-administration/api-configuration Before you can start using the CryptoProcessing API, you need to generate an API key and register a callback URL for receiving webhook notifications. Optionally, you can restrict API access to trusted IP addresses. For details on authenticating your requests, refer to the [API reference](/api-reference/introduction). # Change a user role Source: https://docs.cryptoprocessing.com/merchant-administration/change-a-user-role Update a user’s account access when their responsibilities change. This page explains how to choose the right role, change an existing user’s role, and request **Owner** access when needed. ## Determine which role to use User roles define what each user can see and do in the merchant dashboard. Roles marked **By request only** cannot be assigned directly from the dashboard. Contact your account manager to assign them. For users who need read access to account activity, with a limited set of transactional actions. * View account balance, account information, fees, cold addresses, transactions, payments, invoices, payment requests, mass payouts, withdrawal and operation limits, team members, and contacts * Manage deposit addresses * Resend transaction callbacks * Create payment requests and invoices For users who need to convert funds between currency balances. * All **View** permissions * Exchange funds For users who configure withdrawal thresholds and cold wallet transfer rules. * All **View** permissions * Manage keep-on-hot limits * Manage the minimum transaction amount for automatic transfers to cold wallets For users who initiate crypto withdrawals and payouts but should not be able to approve them. For the **Submitter** role to function as intended, withdrawal limits must be configured. If no limits are configured, or if a withdrawal amount does not exceed the configured limit, withdrawals created by a **Submitter** will be processed immediately without requiring approval. * All **View** permissions * Create crypto withdrawals * Create mass payouts For users who approve withdrawals but should not be able to initiate them. * All **View** permissions * Approve or decline withdrawals that require manual approval For users who manage fiat operations and bank accounts. * All **View** permissions * Create fiat withdrawals * Create fiat top-ups * View and add bank accounts For users who manage both crypto and fiat operations. For the **Accounts Payable** role to function as intended, withdrawal limits must be configured. If no limits are configured, or if a withdrawal amount does not exceed the configured limit, withdrawals created by an **Accounts Payable** user will be processed immediately without requiring approval. * All **View** permissions * Create fiat withdrawals * Create fiat top-ups * View and add bank accounts * Create crypto withdrawals * Create mass payouts * Exchange funds Full access to the merchant account and all dashboard sections. * Includes permissions from all other roles * Add and remove users, and update user roles * Manage API keys * Configure callbacks, notifications, and withdrawal limits * Manage cold addresses * Manage active currencies (shown on the **Balances** tab) * Withdraw funds * Create fiat top-up orders * Configure withdrawal limits * Approve withdrawals that exceed the withdrawal limit * Create mass payouts No access to the merchant dashboard. Can contact the Support team and create tickets. ## Change a user role ## FAQ ### How do I assign the Owner, Submitter, Approver, or Accounts Payable role to a user? Only your account manager can assign the **Owner**, **Submitter**, **Approver**, and **Accounts Payable** roles. To assign one of these roles, contact your account manager. ### How do I change the role of a user with the Owner role? To change the role of an **Owner** user, contact your account manager. # Configure automatic withdrawals to cold addresses Source: https://docs.cryptoprocessing.com/merchant-administration/configure-automatic-withdrawals-to-cold-addresses Automatic withdrawals send funds to an external cold address once the balance for a given currency reaches a certain level. To enable this flow, you must configure balance limits and a cold address for each currency. ## Configure balance limits Balance limits define when an automatic withdrawal is triggered and how much remains on the balance afterward. Configure the following: * **Keep on Hot** — the amount that remains on the balance after an automatic withdrawal. This is effectively the maximum balance for the selected currency. * **Min Transaction Amount** — the threshold at which an automatic withdrawal is triggered. Once the balance reaches or exceeds this value, the excess funds are swept to the cold address and the remaining balance is reduced to the Keep on Hot amount. ## Configure a cold addresses The cold address is the external address that funds are automatically withdrawn to. Editing a cold address is disabled by default. To modify an existing address, contact the support team to request access — once granted, editing is available for 24 hours. This ensures that only a user with the Owner role, following an official request, can update cold addresses. # Configure balance amount notifications Source: https://docs.cryptoprocessing.com/merchant-administration/configure-balance-amount-notifications You can monitor minimum balance thresholds for specific currencies without logging into the merchant dashboard. At a configured interval, the system checks your balances and sends a report to the specified email address listing any currencies that have dropped below their threshold. Enter the email address, input your 2FA code, and click **Confirm**. In the pop-up, select the currency, set the minimum balance threshold, enter your 2FA code, and click **Confirm**. Click **Edit** in the **Rules** section, select the desired interval in hours, enter your 2FA code, and click **Submit**. # Configure deposit callbacks Source: https://docs.cryptoprocessing.com/merchant-administration/configure-deposit-callbacks By default, CryptoProcessing sends callbacks for these two deposit events: [deposits below the minimum allowed amount](/api-reference/callbacks/deposit-callbacks#below-minimum-amount), and [deposits received in a currency different from the one assigned to the crypto address](/api-reference/callbacks/deposit-callbacks#cross-currency-deposit). You can enable or disable either of these at any time. # Configure withdrawal limits Source: https://docs.cryptoprocessing.com/merchant-administration/configure-withdrawal-limits Withdrawal limits can be configured by users with the Owner role to send outgoing transactions for manual approval when they exceed a configured threshold. Limits are configured separately for **interface withdrawals** (created in the merchant dashboard) and **API withdrawals** (created via the API). When an interface withdrawal exceeds a configured limit, it must be approved by a **different** user with the Owner role — the user who created the withdrawal cannot approve it themselves. For API withdrawals, any user with Owner permissions can approve or decline the transaction. There are two types of limits: * **Default limit** — set in your account's main fiat currency (typically EUR) and applies to all currencies. Withdrawals in other currencies are checked against their EUR equivalent. For example, a default limit of 1,000 EUR means any USDC withdrawal over 1,166.70 USDC (≈ 1,000 EUR) will require approval. * **Custom limit** — set for a specific currency and overrides the default limit. For example, if you set a custom USDC limit of 10,000 USDC, a 1,166.70 USDC withdrawal will no longer require approval, even if it exceeds the default EUR threshold. Withdrawal limits do not apply to fiat withdrawals to bank accounts. ## Configure the default withdrawal limit The default limit is defined in your account's main fiat currency (typically EUR) and applies to all currencies. Withdrawals in other currencies are evaluated based on their EUR equivalent — for example, with a default limit of 1,000 EUR, a USDC withdrawal over 1,166.70 USDC (the equivalent of 1,000 EUR) would require approval. To set a different threshold for a specific currency, configure a custom limit for that currency instead. Select the **Interface withdrawals** tab to set limits for withdrawals created in the merchant dashboard, or the **API withdrawals** tab for withdrawals created via the API. In the pop-up, configure any of the following options: * **All withdrawals will be passed through manual moderation** — enable this checkbox to require approval for all withdrawals regardless of amount. * **One operation limit** — maximum amount per single withdrawal. * **Per hour limit** — maximum total amount within one hour. * **Per day limit** — maximum total amount within one day. ## Configure custom withdrawal limits Custom limits apply to a specific currency and take priority over the default limit. Use custom limits when you need different thresholds for individual fiat or crypto currencies. Select the **Interface withdrawals** tab to set limits for withdrawals created in the merchant dashboard, or the **API withdrawals** tab for withdrawals created via the API. In the pop-up, configure the following: * **Currency** — select the fiat or crypto currency for this limit. * **All withdrawals will be passed through manual moderation** — enable this checkbox to require approval for all withdrawals in this currency regardless of amount. * **One operation limit** — maximum amount per single withdrawal. * **Per hour limit** — maximum total amount within one hour. * **Per day limit** — maximum total amount within one day. ## Configure notifications for pending approvals You can configure email notifications to alert you when a withdrawal is sent for manual moderation. Click **Email** and enter the email address where you want to receive notifications. To add multiple addresses, click **Add** after each entry. To remove an address, click the bin icon next to it. Click **Test email** to send a test notification to all configured addresses and confirm delivery. ## FAQ ### Can I require approval for all withdrawals regardless of amount? Yes. When editing the default limit, enable the **All withdrawals will be passed through manual moderation** checkbox. Every withdrawal will then be sent for approval regardless of amount. Note that this setting is configured independently for interface withdrawals and API withdrawals — if you want it to apply to both, enable it in each tab. ### Can I require approval for all withdrawals in a specific currency? Yes. Add or edit a custom limit for that currency and enable the **All withdrawals will be passed through manual moderation** checkbox. This overrides the default limit behavior for that currency and sends every withdrawal in it for approval regardless of amount. Note that this setting is configured independently for interface withdrawals and API withdrawals — if you want it to apply to both, enable it in each tab. ### Why does a withdrawal have the Pending status? A withdrawal receives the status when it is sent for manual moderation because a withdrawal limit was triggered. To continue processing the withdrawal, an Owner must open the transaction in the merchant dashboard and either approve or decline it. ## Related topics * [Approve a withdrawal](/withdrawals/approve-a-withdrawal) # Deactivate an API key Source: https://docs.cryptoprocessing.com/merchant-administration/deactivate-an-api-key You may need to deactivate your API key if you want to create a new one, if you lost your secret key, or if you think your secret key was compromised. If you suspect that your secret key was compromised, **deactivate it immediately** and contact our Support team. ## Deactivate an API key # Disable withdrawals Source: https://docs.cryptoprocessing.com/merchant-administration/disable-withdrawals If you need to stop all outgoing transactions for your merchant account — for example, while investigating suspicious activity — you can disable withdrawals from the merchant dashboard. Once disabled, withdrawals can only be turned back on by contacting our Support team. Once withdrawals are disabled, a message is shown on the **Balances** tab of the merchant dashboard that withdrawal functionality is currently unavailable for this merchant, and no new withdrawal requests can be created. This affects the following transaction types: * Withdrawals (with or without automatic conversion) * Withdrawals to cold addresses * Instant withdrawals (with or without automatic conversion) * Payment request manual refunds * Mass payouts Withdrawals that were already underway when withdrawals were disabled aren't stopped mid-flight — they still fail, just not immediately: * If a withdrawal had already reached , it fails there. * If a withdrawal was still , it first moves to , then fails. ## Disable withdrawals In your merchant dashboard, go to **Settings** and open the **Withdrawal limit** tab. Switch to the **Withdrawals settings** tab and click **Disable withdrawals**. Optionally, add a note describing why withdrawals are being disabled. Enter your 2FA code and click **Confirm**. ## Enable withdrawals again Withdrawals cannot be re-enabled from the merchant dashboard. To turn withdrawals back on, contact our Support team. Before requesting that Support re-enable withdrawals, review the following: * **[Configured cold addresses](/merchant-administration/configure-automatic-withdrawals-to-cold-addresses#configure-a-cold-addresses)** — once withdrawals are turned back on, automatic withdrawal rules are evaluated again. If a currency's balance has reached or exceeded its configured **Min Transaction Amount** threshold while withdrawals were disabled, the system will immediately trigger an automatic withdrawal to the cold address configured for that currency. Carefully review the configured cold addresses before re-enabling withdrawals. * **[Pending withdrawals awaiting approval](/withdrawals/approve-a-withdrawal)** — withdrawals that were already when withdrawals were disabled couldn't be approved while disabled, and may still be sitting in the status. Review pending withdrawals carefully. # Generate and activate API keys Source: https://docs.cryptoprocessing.com/merchant-administration/generate-and-activate-api-keys You need to generate an API key and a secret key before you can start making API requests: * **API key** - Specified in the `X-Processing-Key` header in API requests. You can view it in the **API keys** section of your merchant dashboard. * **Secret key** - Used to generate an HMAC-SHA512 signature of the request body. The signature is specified in the `X-Processing-Signature` header in API requests. You can view the secret key only once, after activating the API key for the first time. API keys are not tied to a specific user. They are tied to your merchant account. Only one API key and secret key pair can be active for a merchant at a time. ## Generate an API key and activate it The list of **Generated API keys** will be updated. Only one API key can be active at a time. If another key is already active, disable it first, then return to this step. Your secret key will be displayed after you click **Activate**. Make sure no one can see or record your screen. Specify the public IP addresses from which you will make requests to the API. Use either IPv4 or IPv6 format, and separate multiple IP addresses with commas. If you leave this blank, requests from any IP address will be accepted. Your secret key is displayed only once. Toggle **Secret key QR code** to display the secret key as a QR code. If you think your secret key may have been compromised, [deactivate it](/merchant-administration/deactivate-an-api-key) immediately and contact our Support team. ## FAQ ### How can I view my secret key if I lost it? If you don't have your secret key, you need to [deactivate](/merchant-administration/deactivate-an-api-key) the corresponding API key, and then generate a new API key and secret key. ### What should I do if someone else got access to my secret key? If you suspect that your secret key was compromised, [deactivate it](/merchant-administration/deactivate-an-api-key) immediately and contact our Support team. # Log in and configure 2FA Source: https://docs.cryptoprocessing.com/merchant-administration/log-in-and-configure-2-fa **Available to all roles** ## First login Scan the QR code with your authenticator app. Enter your email address, temporary password, and the 2FA code generated by your authenticator app. Enter your temporary password, then create and confirm your new password. ## FAQ ### How can I reset my password? If you forgot your password, please contact the Support team. If you remember your password and want to change it, go to the **Account** section in the merchant dashboard and click **Change** next to the **Password** field. ### I don't have access to my 2FA device If you've lost access to the device configured for 2FA and don't have a backup, please contact the Support team for assistance. ### How do I change my 2FA device? You can move your existing 2FA configuration to a new device or application. Refer to your 2FA application's documentation for instructions. ### Why do I get logged out after entering my credentials? Users with the **Restricted** role do not have access to the merchant dashboard and are logged out immediately after entering their credentials. They only have access to the help center. # Manage allowed IP addresses for API requests Source: https://docs.cryptoprocessing.com/merchant-administration/manage-allowed-ip-addresses-for-api-requests Follow the instructions on this page to update the public IP addresses from which you will make requests to the API. ## Manage allowed IP addresses Use either IPv4 or IPv6 format, and separate multiple IP addresses with commas. # Merchant security Source: https://docs.cryptoprocessing.com/merchant-administration/merchant-security This section covers merchant account settings that help you control fund movements and stay informed about your balances. You can set withdrawal limits to require manual approval for large or suspicious transactions, configure balance notifications to alert you when funds drop below a threshold, automate withdrawals to cold addresses once balances reach a defined level, and disable withdrawals entirely if you need to stop outgoing transactions altogether. # Remove a user Source: https://docs.cryptoprocessing.com/merchant-administration/remove-a-user Remove users from your merchant account when they no longer need access to the merchant dashboard. This page explains how to remove an existing user and what to do when you need to remove or disable an **Owner** user. ## Remove a user ## FAQ ### Can I remove a user with the Owner role? To remove a user with the **Owner** role, contact your account manager. ### Can I deactivate a user's account without deleting it? To temporarily restrict a user's access to the merchant dashboard without deleting their account, contact our Support team and request to disable the user's account. # Repeat and export callbacks Source: https://docs.cryptoprocessing.com/merchant-administration/repeat-and-export-callbacks **Available to all roles except** If your webhook endpoint missed a callback, or you need the full callback history for a transaction, you can resend the latest callback or export all callbacks for that transaction directly from the merchant dashboard — for example, for debugging your integration or reconciling your records. ## Repeat a callback A side panel with the transaction details opens. CryptoProcessing resends the latest callback for this transaction to your registered [callback URL](/merchant-administration/set-up-callback-url). ## Export all callbacks for a transaction A side panel with the transaction details opens. A CSV file containing all callbacks sent for this transaction is downloaded. ## FAQ ### Why am I not getting a callback for a deposit? CryptoProcessing only sends [deposit callbacks](/api-reference/callbacks/deposit-callbacks) for transactions to [system deposit addresses](/deposits#system-deposit-addresses) — addresses created via the [/v2/addresses/take](/api-reference/endpoints/addresses-take) API endpoint. Deposits to customer deposit addresses or merchant top-up addresses created manually in the dashboard do not trigger callbacks. If you were expecting a callback for a system deposit address but did not receive one, first check that your [callback URL](/merchant-administration/set-up-callback-url) is set up correctly and reachable, then use [Repeat a callback](#repeat-a-callback) to resend it. # Set up callback URL Source: https://docs.cryptoprocessing.com/merchant-administration/set-up-callback-url As part of the integration process, you need to set up an HTTPS webhook endpoint where CryptoProcessing can send [callbacks](/api-reference/callbacks/callbacks-overview). After you create the endpoint, register it in CryptoProcessing. You can only add one callback URL per merchant account. Setting up a new URL replaces the existing one. ## Set up callback URL Your webhook URL must use HTTPS, use a domain name, and be considered safe by VirusTotal and similar scanners. For additional security, you can whitelist the CryptoProcessing IP addresses used for callback delivery. Contact Support for the current list of IP addresses. # User management Source: https://docs.cryptoprocessing.com/merchant-administration/user-management Access, secure, and maintain user accounts in the merchant dashboard. Use these articles to set up login credentials, configure 2FA, understand role-based access, and resolve common authentication issues. # Payment request backlinks Source: https://docs.cryptoprocessing.com/payment-requests/backlinks The CryptoProcessing payment request webpage may include a **Return to merchant** link with a URL that you provide. It is good practice to use these webpages to inform the customer about the successful purchase or let them retry a failed one. This customization is only available when creating a payment request via the [API endpoint](/api-reference/endpoints/payments). You can provide different webpages for different states of the process via the [url\_store](#url-store), [url\_success](#url-success) and [url\_failed](#url-failed) parameters. url_store url_success url_failed It is not guaranteed that the customer will click the link. Instead, they may immediately close the tab with the CryptoProcessing interface after sending the transaction. The only reliable way to get notified about the payment request status is to process [API callbacks](/api-reference/callbacks/payment-request-callbacks). ## url\_store The `url_store` link will be shown under the payment request form while it is still processing (neither successful nor cancelled). This URL is also used as the default value for `url_success` and `url_failed` in case you don't specify them. ## url\_success The `url_success` link will be used for the button on the final screen of the payment request interface. A customer only sees this button when they successfully completed the payment request. Your site will have already received the [Payment request paid](/api-reference/callbacks/payment-request-callbacks#payment-request-paid) callback. ## url\_failed The `url_failed` link will be used for the button on the ‘Payment request expired’ screen. A customer only sees this button when they failed to fulfill the requested amount within the [lifespan](/payment-requests#lifespan). Your site will have already received the [Payment request failed](/api-reference/callbacks/payment-request-callbacks#payment-request-failed) callback. # Create a payment refund Source: https://docs.cryptoprocessing.com/payment-requests/create-a-payment-refund You can refund all or part of a completed payment request at any time. The refund is always sent in the same cryptocurrency and network the customer used to pay, and the amount is deducted from your balance. For an overview of how refunds work, see [Payment request refunds](/payment-requests/refunds). You can refund the full amount or a partial amount. The maximum refundable amount is shown below the amount field. Review the fee and final amount deducted from your balance before proceeding. Once the refund is created, the amount is deducted from your balance and your customer receives an email with a secure link to claim their refund. You can track the refund status in the refunds section of the payment request. See [Payment request statuses](/payment-requests/statuses) for details. # Create a payment request Source: https://docs.cryptoprocessing.com/payment-requests/create-a-payment-request **Available to all roles except** A payment request generates a unique payment link and QR code you can share with a customer to collect a one-time crypto payment. For an overview of how payment requests work, see [Payment requests](/payment-requests). Select the currency and the amount you want to receive. If the customer [selects another currency](/payment-requests#currency-selection) to pay in, CryptoProcessing will automatically convert the funds into the currency you selected. Choose how long the payment link remains valid. Set this as a duration (minutes, hours, or weeks) or as a specific date and time in your local time zone. Make sure your customer will have enough time to place the payment. We recommend setting the lifespan to at least 15 minutes. If your customers can pay in currencies on networks with higher confirmation times (such as BTC), consider setting the lifespan to at least an hour. * **Customer pays the processing fee** — whether the requested amount should be automatically increased to compensate the processing fee for the merchant. * **Description** — a short description of the product or service. This will be shown to the customer on the payment page. * **Customer email** — the customer's email address, used to send them a receipt and any [refund](/payment-requests/refunds) instructions if needed. Once the request is created, a unique link and QR code are generated. Share either with your customer to complete the payment. # Payment request fees Source: https://docs.cryptoprocessing.com/payment-requests/fees ## Processing fee When your customer fulfills a payment request and you receive the funds, a *processing fee* will be subtracted from your account. The fee is the same as a [deposit fee](/deposits/fees) for the same amount. Just like for a deposit, the fee may depend on the currency and on whether the payment involved a conversion between different currencies. Each fee has a minimum amount that will be subtracted regardless of the transaction amount. The fees are listed on the **Fees** tab in your merchant dashboard, under the **Deposit operations** section. The applicable fees are: * **Deposit crypto** * **Deposit crypto exchange to crypto** * **Deposit crypto exchange to fiat** ### Passing the processing fee to your customer By default, the processing fee is covered by the merchant. If you prefer, you can pass this fee on to your customer. In this case, after the customer selects the [payment currency](/payment-requests#currency-selection), CryptoProcessing adds the corresponding processing fee to the total payment amount which the customer needs to pay. To enable this, check the **Customer pays the processing fee** option when creating a payment request via the dashboard or use the [user\_fee\_percent](/api-reference/endpoints/payments#body-user-fee-percent) parameter when creating it via the API. This parameter does not affect the [transfer fee](#transfer-fee-for-ethereum) which may be subtracted for ETH payments. ## Transfer fee for Ethereum When receiving ETH funds or ERC-20 tokens, a *transfer fee* is subtracted from the merchant’s balance, in addition to the [processing fee](#processing-fee). The transfer fee covers the cost of *gas* in the Ethereum network. The transfer fee amount depends on the current gas price when the payment is being processed. It is subtracted in the same currency as the payment itself: for example, the transfer fee for a USDC payment will be in USDC. Unlike the [processing fee](#processing-fee), the transfer fee cannot be paid by the customer. You can see this fee as **Fee transfer** in a payment request's details panel. ## Refund fee If an [automatic or manual refund](/payment-requests/refunds) is initiated, a fixed *refund fee* will be subtracted from its amount. The customer will be shown both the fee amount and the result amount they receive when they fill in the refund form. The fee may depend on the currency in which the refund will be sent, which is the same currency the customer paid. If the refund itself is smaller than the fee, the customer will not be able to receive it. # Fixed payment requests Source: https://docs.cryptoprocessing.com/payment-requests/fixed-payment-requests When a [payment request](/payment-requests) is created in *fixed mode*, the payment currency and network are provided via the API. The customer skips currency selection on the CryptoProcessing payment page, while the exchange rate is locked and the payment timer starts immediately upon creation. The API immediately returns the fixed payment details, which can be used to redirect the customer directly to the payment page or within your own payment experience. This is an advanced integration guide. This guide is intended for merchants who already provide currency selection within their own checkout. **For most merchants, we recommend following the standard [integration guide](/payment-requests/integration-guide)**, where customers select the payment currency and network on the CryptoProcessing payment page. This requires less implementation effort and automatically supports newly added currencies and networks. Configure your account and get an API key, see [Initial setup](/initial-setup). When the customer wants to make a new purchase, show them a screen for selecting the cryptocurrency and the network. The list of currencies and networks accepted by CryptoProcessing depends on the target currency that you want to receive on your balance. We recommend getting the list of currencies from [/v2/currencies/rates](/api-reference/endpoints/currencies-rates). Specify the target currency in `currency_to`, then iterate through the results with the `"crypto"` type. Once the customer selected the cryptocurrency, send a request to [/payments/v1/requests](/api-reference/endpoints/payments). Specify the [currency](/api-reference/endpoints/payments#body-currency) and [amount](/api-reference/endpoints/payments#body-amount) you want to receive on your balance, as well as the [payment\_currency](/api-reference/endpoints/payments#body-payment-currency) according to the customer's choice on the previous step. Set [rate\_mode](/api-reference/endpoints/payments#body-rate-mode) to `"fixed"` to skip the currency selection step on the CryptoProcessing side. Note that the effective [lifespan](/payment-requests#lifespan) in the fixed rate mode will be no longer than 1 hour, as the payment timer will start immediately. ```json title="Request example" theme={null} { "amount": "100", "currency": { "iso": "EUR" }, "payment_currency": { "iso": "USDC", "network_name": "ethereum" }, "rate_mode": "fixed", "life_time_duration": 3600, "end_user_email": "customer@example.com", "description": "Order 0511", "sender_type": "legal", "sender_data": { "legal_name": "Example GmbH", "country_of_registration": "DEU" } } ``` ```json title="Response example" theme={null} { "data": { "id": "019d511c-9fd2-7e71-b534-74e8abd855f1", "amount": "100", "currency": { "iso": "EUR" }, "status": "processing", "life_time": 1785842432, "end_user_email": "customer@example.com", "description": "Order 0511", "payment_link": "https://payments.cryptoprocessing.com/payment/lLXLZ6Q8lCwFFRbyW0C1ET", "payment_currency": { "iso": "USDC", "network_name": "ethereum" }, "user_fee_percent": 0, "rate_mode": "fixed", "valid_until": 1785842432, "payment_details": { "address": { "value": "0x9F2E4b7A1C3D5F6E8B0A2C4D6E8F1A3B5C7D9E0F" }, "expected_amount": "115.69", "expected_currency": { "iso": "USDC", "network_name": "ethereum" }, "exchange_rate": { "from": { "iso": "USDC", "network_name": "ethereum" }, "to": { "iso": "EUR" }, "rate": "0.86" } } } } ``` The URL of the interface is provided in the [data.payment\_link](/api-reference/endpoints/payments#response-data-payment-link) field of the API response. Depending on your payment flow, you can: * navigate the customer to the payment request link in a new tab, * generate a QR code based on the payment request link and display it to your customer, * embed the payment link as an iFrame for quick on-page checkout. For the customer's convenience, we recommend providing a link to the pending payment request somewhere on your site, too. This way, if the customer accidentally closes the payment request tab before finishing the payment, they will use the link to continue the process. When you get the [payment\_request](/api-reference/callbacks/payment-request-callbacks) callback, update the purchase status on your site. Make sure to cover all possible statuses of the callback. For a failed payment request, consider showing a 'Retry' button that initiates a purchase of the same product again. # Payment requests Source: https://docs.cryptoprocessing.com/payment-requests/index With payment requests, you can let your customers make one-time payments in the cryptocurrency of their choice. * **Your customer** sees a convenient webpage that guides them through the payment process. * **You** receive funds in the currency you requested, regardless of the customer's payment currency. * **CryptoProcessing** takes care of conversion and issues automatic refunds for underpayments and overpayments. Payment request step 1 Payment request step 2 Payment request step 3 When creating a payment request, you control its behavior by choosing the [currency](#currency-selection) and the [lifespan](#lifespan). The funds received via a payment request may be sent back via a [refund](/payment-requests/refunds), initiated either automatically or manually by you. ## Currency selection When creating a payment request, you specify the **expected currency** — the fiat or cryptocurrency you want to receive. Your customer chooses the **payment currency** at checkout, or you can set it explicitly via the `payment_currency` parameter on the [/payments](/api-reference/endpoints/payments) API endpoint. If the customer pays in a currency that's different from the expected currency (for example, you want to receive EUR, but the customer pays in USDC), CryptoProcessing converts the funds automatically, so you still receive the exact amount and currency you requested. To do this, CryptoProcessing locks the exchange rate for up to 1 hour once the customer clicks **Proceed to payment** on the payment request page. The total amount to pay never changes after the rate lock. It may include the processing fee for the selected currency if you [pass the processing fee to the customer](/payment-requests/fees#passing-the-processing-fee-to-your-customer). [Refunds](/payment-requests/refunds) are issued in the same currency the customer used to pay the request. Currency selection ## Lifespan The **lifespan** is the time limit you set for a payment request. The customer's transaction must be both created and confirmed within this lifespan, or the payment request expires and its status changes to . If the payment currency differs from the expected currency, a rate lock also applies — for 1 hour, or for the remaining lifespan if that's shorter. For example, if the customer starts the payment process with only 30 minutes left on the lifespan, the rate lock only lasts those 30 minutes and doesn't extend the lifespan. But if the customer starts paying with, say, 10 hours left, a 1 hour rate lock applies and shortens their window: their transaction must now be both created and confirmed within that 1 hour, not the full 10 hours. When the payment request has less than 1 hour left before expiration, the customer sees a countdown timer on the webpage. Countdown timer ## Further reading Learn how to integrate the payment requests flow into your site Walk through all scenarios to make sure your integration works correctly API endpoint API callback # Payment requests integration guide Source: https://docs.cryptoprocessing.com/payment-requests/integration-guide Let your customers pay crypto via a convenient [payment request](/payment-requests) interface with rate lock, currency conversion, and easy refunds. Configure your account and get an API key, see [Initial setup](/initial-setup). When the customer wants to make a new purchase, send a request to [/payments/v1/requests](/api-reference/endpoints/payments). Specify the required amount, [currency](/payment-requests#currency-selection) and [lifespan](/payment-requests#lifespan) for the payment request. ```json title="Request example" theme={null} { "amount": "100", "currency": { "iso": "EUR" }, "life_time_duration": 360000, "end_user_email": "customer@example.com", "description": "Order 0511" } ``` ```json title="Response example" theme={null} { "data": { "id": "019d511c-9fd2-7e71-b534-74e8abd855f1", "amount": "100", "currency": { "iso": "EUR" }, "status": "created", "life_time": 1775542323, "end_user_email": "customer@example.com", "description": "Order 0511", "payment_link": "https://payments.cryptoprocessing.com/payment/lLXLZ6Q8lCwFFRbyW0C1ET" } } ``` The URL of the interface is provided in the [data.payment\_link](/api-reference/endpoints/payments#response-data-payment-link) field of the API response. Depending on your payment flow, you can: * navigate the customer to the payment request link in a new tab, * generate a QR code based on the payment request link and display it to your customer, * embed the payment link as an iFrame for quick on-page checkout. For the customer's convenience, we recommend providing a link to the pending payment request somewhere on your site, too. This way, if the customer accidentally closes the payment request tab before finishing the payment, they will use the link to continue the process. When you get the [payment\_request](/api-reference/callbacks/payment-request-callbacks) callback, update the purchase status on your site. Make sure to cover all possible statuses of the callback. For a failed payment request, consider showing a 'Retry' button that initiates a purchase of the same product again. # Payment request refunds Source: https://docs.cryptoprocessing.com/payment-requests/refunds CryptoProcessing provides a mechanism to send funds back to the customer. This involves emailing the customer a link to a special form, where the customer enters a crypto address for receiving the refund. The mechanism can be initiated [automatically](#automatic-refunds) or [manually](#manual-refunds). ## Automatic refunds The mechanism is initiated automatically in the following scenarios: **Late payment or underpayment** The customer sent some funds but failed to fulfill the request conditions. All funds (minus a fee) must be sent back to the customer via a **full refund**. **Overpayment** The customer sent more funds than needed for this request. The extra funds (minus a fee) must be sent back to the customer via a **partial refund**. ## Manual refunds Additionally, you can always initiate a **manual refund** to sent back any part of the payment (up to the whole payment amount) back to the customer for arbitrary reasons. The refund is always sent in the same cryptocurrency and on the same network as the payment done by the customer, regardless of the originally expected cryptocurrency. You decided that some or all funds should be sent back to the customer. The reasons here are completely up to you. For example, if the customer canceled a subscription on your website in the middle of a month, you may want to return half of the payment to them. To initiate a manual refund, click **Actions → Create refund** on the payment request's details page. In a form that appears, you can specify the amount of funds to send back (not higher than the amount received). ## How it works The customer receives a link to the refund form via the email address they provided before the payment. Email about a refund In the refund form, the customer enters a crypto address for receiving the refund. For for receiving a refund CryptoProcessing sends funds to the address. The refund process uses the same cryptocurrency and network as the actual payment. For example, if the original payment was in BTC with conversion to USDC, CryptoProcessing will convert USDC back to BTC for the refund. # Payment request and refund statuses Source: https://docs.cryptoprocessing.com/payment-requests/statuses This section describes the statuses displayed in the merchant dashboard for payment requests and refunds. ## Payment request statuses
Status Description
The payment request was created, but the crypto address is not yet generated for it. Depending on the payment request's parameters, at this point the customer can [select the currency](/payment-requests#currency-selection) in which they are going to pay.
When the customer agrees to the terms and clicks **Proceed to payment**, the address will be generated, and the status will change to . If they fail to do so during the [lifespan or rate lock period](/payment-requests#lifespan), the status will change to .
The crypto address was generated, but incoming transactions aren't created, aren't confirmed or don't cover the requested amount yet.
As soon as incoming transactions for the requested total amount will get the required [number of confirmations](/confirmations-and-limits), the status will change to .
If transactions are created but aren't confirmed during the [lifespan or rate lock period](/payment-requests#lifespan), or if the total confirmed amount is less than requested, the status will change to .
If no transactions are created during the [lifespan or rate lock period](/payment-requests#lifespan), the status will change to .
Incoming transactions for the requested total amount were confirmed. The funds are credited to the merchant's balance.
In case of a late payment or an overpayment, CryptoProcessing will initiate an [automatic refund](/payment-requests/refunds#automatic-refunds), unless the overpaid amount is smaller than the [minimum withdrawal limit](/confirmations-and-limits) + [refund fee](/payment-requests/fees).
The customer created one or more transactions to the address, but they did not get the required [number of confirmations](/confirmations-and-limits) or their total amount did not reach the requested amount during the [lifespan or rate lock period](/payment-requests#lifespan).
CryptoProcessing will initiate an [automatic refund](/payment-requests/refunds#automatic-refunds), unless the total received amount is smaller than the [minimum withdrawal limit](/confirmations-and-limits) + [refund fee](/payment-requests/fees).
The customer hasn't created any transactions during the [lifespan or rate lock period](/payment-requests#lifespan).
## Refund statuses
Status Description
The refund is being created, and the funds are being subtracted from the merchant's balance. If this step is successful, the status will change to . If the merchant does not have enough funds, the status will change to .
CryptoProcessing sent the customer an email with a link to claim their refund.
The customer opened the email, clicked the link and entered their details. The refund is being processed.
The refund has been successfully completed.
The refund request couldn't be created. Double-check the details and make sure you have enough funds on your balance to issue the refund.
The refund couldn't be completed. If you encounter this error, contact CryptoProcessing support.
# Payment requests integration test cases Source: https://docs.cryptoprocessing.com/payment-requests/test-cases These are the test cases to help you test your site's integration with CryptoProcessing [payment requests](/payment-requests/integration-guide). For each test case, create a new payment request via the [/payments/v1/requests](/api-reference/endpoints/payments) endpoint and then process the [payment\_request](/api-reference/callbacks/payment-request-callbacks) callback. For some test cases, you will need to check that your customer receives an email from CryptoProcessing and can click a link in it. Make sure to enter a specify email address when creating payment requests for such test cases. You can test payment requests in the sandbox environment by withdrawing funds from your merchant account instead of sending an external payment. Create a payment request, open the link, and choose a payment currency to get an address, then [withdraw funds](/withdrawals/create-a-withdrawal) to that address.
Procedure Expected results
**Successfully completed payment**
1. Create a payment request. 2. Open the payment request link on your device. 3. Place a payment for the exact amount requested. * The site gets a `payment_request` callback. * The callback status is `paid`. * The customer is redirected to `url_success`. * The customer receives an email about the successful payment.
**Overpayment**
1. Create a payment request. 2. Open the payment request link on your device. 3. Place a payment for an amount larger tha requested (add at least the [minimum deposit amount](/confirmations-and-limits)). * The site gets a `payment_request` callback. * The callback status is `paid`. * The customer is redirected to `url_success`. * The customer receives an email with a link to a **partial refund**.
**Underpayment**
1. Create a payment request. 2. Open the payment request link on your device. 3. Place a payment for an amount less than requested. * The site gets a `payment_request` callback. * The callback status is `failed`. * The customer is redirected to `url_failed`. * The customer receives an email with a link to a **full refund**.
**Payment requests with a late payment**
1. Create a payment request with a short lifespan (for example, 5 minutes). 2. Open the payment request link on your device. 3. Choose a payment currency and click **Proceed to payment**. 4. Copy the address or scan the QR code with your device. Do not place the payment yet. 5. Wait till the payment request expires. 6. Place a payment for the requested amount. * The site gets a `payment_request` callback. * The callback status is `failed`. * The customer is redirected to `url_failed`. * The customer receives an email with a link to a **full refund**.
**Payment request expired before the currency selection**
1. Create a payment request with a short lifespan (for example, 5 minutes). 2. Wait till the payment request expires. * The site gets a `payment_request` callback. * The callback status is `failed`. * The customer is redirected to `url_failed`. * The customer does not receive any email.
**Payment request expired after the currency selection**
1. Create a payment request with a short lifespan (for example, 5 minutes). 2. Open the payment request link on your device. 3. Choose a payment currency and click **Proceed to payment**. Do not place the payment. 4. Wait till the payment request expires. * The site gets a `payment_request` callback. * The callback status is `failed`. * The callback contains the information about the selected currency in the `currency_sent` field. * The customer is redirected to `url_failed`. * The customer does not receive any email.
# Drupal Source: https://docs.cryptoprocessing.com/plugin-integrations/drupal **Note**: You’ll need an active merchant account to start accepting crypto payments. If you don’t have one yet, please reach out to our Sales team at [sales@cryptoprocessing.com](mailto:sales@cryptoprocessing.com) to set up your merchant account. ## Step 1. Install the plugin 1. Log in to your Drupal admin panel. 2. Download the module from the [extension page](https://www.drupal.org/project/coinspaid). 3. Go to **Manage** > **Extend** and select the **CryptoProcessing by Coinspaid for Drupal – Cryptocurrency Payment Gateway**. Check the box next to it and click **Install**. ## Step 2. Get your API keys To accept payments through CryptoProcessing, you need to set up your API credentials. See [Generate and activate API keys](/merchant-administration/generate-and-activate-api-keys) for more details. Once you activate your API keys, [set up the callback URL](/merchant-administration/set-up-callback-url). The callback URL should match the URL in your Drupal plugin settings. ## Step 3. Configure the plugin 1. In your Drupal admin panel, go to the **Manage** tab. Select **Commerce** > **Configuration** > **Payment** > **Payment gateways** and click **Add payment gateway**. 2. Name the plugin. For example, you can use 'CryptoProcessing by Coinspaid'. Save the **Machine** name somewhere (it will be generated automatically). 3. Under Plugins, select **CoinsPaid (Redirect to payment page)**. Toggle the **Mode** field to **Live**. 4. Paste your API Key into the **Public Key** field. Paste your secret key into the **Secret Key** field. 5. Under **Invoice Mode**, select **Invoice with time restriction** or **Invoices without restriction of payment type**. Change the status to **Enable** to activate the plugin and click **Save**. # Joomla Source: https://docs.cryptoprocessing.com/plugin-integrations/joomla **Note**: You’ll need an active merchant account to start accepting crypto payments. If you don’t have one yet, please reach out to our Sales team at [sales@cryptoprocessing.com](mailto:sales@cryptoprocessing.com) to set up your merchant account. ## Step 1. Install the plugin 1. Download the **Pay With CoinsPaid for Virtuemart** plugin from the [Joomla marketplace](https://extensions.joomla.org/extension/pay-with-coinspaid-for-joomla-cryptocurrency-payment-gateway/). 2. In your Joomla admin panel, click **System** on the left-hand sidebar. Select **Extensions** under **Install**. 3. Click **Upload Package File** and upload the plugin. ## Step 2. Get your API keys To accept payments through CryptoProcessing, you need to set up your API credentials. See [Generate and activate API keys](/merchant-administration/generate-and-activate-api-keys) for more details. Once you activate your API keys, [set up the callback URL](/merchant-administration/set-up-callback-url). The callback URL should match the URL on your Joomla site. ## Step 3. Configure the plugin 1. In your Joomla dashboard, go to **Components** > **VirtueMart** > **Payment Method**. 2. Click **New** to create a new payment method for your shop. Fill out the form and click **Save**. 3. Set: 1. Payment name to CryptoProcessing by Coinspaid 2. Self-alias to cryptoprocessing-by-coinspaid 3. Published to **Yes**. 4. Go to the **Configuration** tab. Paste your secret key into the **Coinspaid secret key** field and your API Key into the **Coinspaid public key** field. 5. Select **Yes** under **Use sandbox**, **Enable payment time restriction** and **Enable debug**. 6. Click **Save & Close**. # Magento Source: https://docs.cryptoprocessing.com/plugin-integrations/magento You’ll need an active merchant account to start accepting crypto payments. If you don’t have one yet, please reach out to our Sales team at [sales@cryptoprocessing.com](mailto:sales@cryptoprocessing.com) to set up your merchant account. ## Get your Magento keys 1. In the Marketplace, go to **My Profile**. Select **Access Keys** in My Products. 2. Save your public and private keys. ## Install the Magento plugin ### From the marketplace Make sure you have the composer installed. 1. Open the Cryptoprocessing by CoinsPaid extension on the marketplace. In **My Purchase**, click **Technical Details**. 2. Go to your Magento project directory and update your `composer.json` file: `composer require : `You can find the component-name and version values in the `composer.json` file in the archive (under `name` and `version`). 3. Run: `php bin/magento setup:upgrade` 4. Run: `php bin/magento setup:static-content:deploy`. 5. Clear cache. ### From the archive 1. Unzip the plugin file. 2. Create another directory called `app/code/VENDOR/MODULENAME/` where `MODULENAME` must be replaced by the module's internal identifier. You can find it in the file in the extension ZIP file. For example, `app/code/ConnectPay/Payment`. Upload the extension zip file to this directory. 3. Upload the directory `app/code/VENDOR/MODULENAME/` into the root directory of your Magento installation. All directories should match the existing directory structure. 4. Go to Magento 2 root directory. Run `php bin/magento setup:upgrade`. 5. Run `php bin/magento setup:static-content:deploy`. 6. Clear cache. # OpenCart Source: https://docs.cryptoprocessing.com/plugin-integrations/opencart You’ll need an active merchant account to start accepting crypto payments. If you don’t have one yet, please reach out to our Sales team at [sales@cryptoprocessing.com](mailto:sales@cryptoprocessing.com) to set up your merchant account. ## Step 1. Install the plugin 1. Contact our support team at [support@cryptoprocessing.com](mailto:support@cryptoprocessing.com) to get the archive with the extension. 2. In your OpenCart admin panel, select **Extensions** > **Installer** on the left-hand sidebar. 3. Click the **Upload** button in the top-right corner and upload the archive. ## Step 2. Get your API keys To accept payments through CryptoProcessing, you need to set up your API credentials. See [Generate and activate API keys](/merchant-administration/generate-and-activate-api-keys) for more details. Once you activate your API keys, [set up the callback URL](/merchant-administration/set-up-callback-url). The callback URL should match the URL in your OpenCart plugin settings. ## Step 3. Configure the plugin 1. In your OpenCart admin panel, select **Extensions** on the left-hand sidebar. 2. Select **Pay by Crypto** and click the pencil icon to configure the plugin. 3. Paste your secret key into the **Private key** field. Paste your API key into the **Public key** field. 4. Set Status to **Enabled**, Environment to **Production**, Time restriction to **Enabled** and Debug logging to **Disabled**. 5. Click **Save changes** in the top-right corner. # PrestaShop Source: https://docs.cryptoprocessing.com/plugin-integrations/prestashop You’ll need an active merchant account to start accepting crypto payments. If you don’t have one yet, please reach out to our Sales team at [sales@cryptoprocessing.com](mailto:sales@cryptoprocessing.com) to set up your merchant account. ## Step 1. Install the module 1. Contact our support team at [support@cryptoprocessing.com](mailto:support@cryptoprocessing.com) to get the module archive. 2. Go to your PrestaShop admin panel and select **Modules** > **Module Manager** on the left-hand sidebar. 3. Click **Upload a module** and select the module archive on your computer. ## Step 2. Get your API keys To accept payments through CryptoProcessing, you need to set up your API credentials. See [Generate and activate API keys](/merchant-administration/generate-and-activate-api-keys) for more details. Once you activate your API keys, [set up the callback URL](/merchant-administration/set-up-callback-url). The callback URL should match the URL in your PrestaShop module settings. ## Step 3. Configure the module 1. In your PrestaShop admin panel, select **Modules** > **Module Manager** on the left-hand sidebar. 2. Select the **Payments** category and click **Configure** next to the **Cryptoprocessing by CoinsPaid – Cryptocurrency Payment Gateway** module. 3. Paste your API key into the **Public key** field. Paste your secret key into the **Private key** field. 4. Toggle off **Enable Sandbox mode**. Toggle on **Enable logged mode** and **Enable time restriction mode**. Click **Save**. # WordPress Source: https://docs.cryptoprocessing.com/plugin-integrations/wordpress You will need an active merchant account to start accepting crypto payments. If you don’t have one yet, please reach out to our Sales team at [sales@cryptoprocessing.com](mailto:sales@cryptoprocessing.com) to set up your merchant account. ## Step 1. Install the plugin 1. Go to your WordPress admin panel and select **Plugins** on the left-hand sidebar. 2. Click **Add new** and search for the **Pay With CoinsPaid for Woocommerce – Cryptocurrency Payment Gateway** plugin. 3. Click **Install Now**. 4. In your **Plugins** list, find the CoinsPaid plugin and click **Activate**. ## Step 2. Get your API keys To accept payments through CryptoProcessing, you need to set up your API credentials. See [Generate and activate API keys](/merchant-administration/generate-and-activate-api-keys) for more details. Once you activate your API keys, [set up the callback URL](/merchant-administration/set-up-callback-url). The callback URL should match the URL in your WooCommerce plugin settings. ## Step 3. Configure the module 1. In your WordPress admin panel, select **WooCommerce** > **Settings** on the left-hand sidebar. Select **Payments** from the top menu. 2. Find the **Pay With CoinsPaid for Woocommerce – Cryptocurrency Payment Gateway** in the list of available providers and toggle to **Enable it**. Click **Finish Set Up**. 3. Paste your API key into the **Public key** field. Paste your secret key into the **Secret key** field. Click **Save changes**. # Reference letter Source: https://docs.cryptoprocessing.com/reference-letter If you need to confirm that you're using CryptoProcessing's services — for a bank, auditor, or other third party — you can request a reference letter from your account manager. Email your account manager at [accounts@cryptoprocessing.com](mailto:accounts@cryptoprocessing.com) with the details of what you need the letter to cover. Besides confirming that you're a client, a reference letter can also include: * Confirmation of specific deposit or withdrawal addresses * Transaction details You can also request a signed balance statement from your account manager. Let your account manager know exactly what you need included so they can prepare it for you. # Supported currencies Source: https://docs.cryptoprocessing.com/supported-currencies ## Supported crypto | Cryptocurrency | Name | Network | | :-------------- | :------------- | :-------------- | | ADA | Cardano | Cardano | | BCH | Bitcoin Cash | Bitcoin Cash | | BNB-BSC | BNB | BNB Smart Chain | | BTC | Bitcoin | Bitcoin | | DOGE | Dogecoin | Dogecoin | | ETH | Ethereum | Ethereum | | ETH (Arbitrum) | Ethereum | Arbitrum | | ETH (Base) | Ethereum | Base | | EURC (Base) | EUR Stablecoin | Base | | EURC (ERC-20) | EUR Stablecoin | Ethereum | | EURC (SOL) | EUR Stablecoin | Solana | | EURS (ERC-20) | STASIS EURS | Ethereum | | LTC | Litecoin | Litecoin | | POL | Polygon | Polygon | | SOL | Solana | Solana | | TRX | Tron | Tron | | USDC (ERC-20) | USD Coin | Ethereum | | USDC (Arbitrum) | USD Coin | Arbitrum | | USDC (BEP-20) | USD Coin | BNB Smart Chain | | USDC (Base) | USD Coin | Base | | USDC (POL) | USD Coin | Polygon | | USDC (SOL) | USD Coin | Solana | | USDG (ERC-20) | Global Dollar | Ethereum | | USDG (SOL) | Global Dollar | Solana | | WBTC (ERC-20) | Wrapped BTC | Ethereum | | XED (ERC-20) | Exeedme | Ethereum | | XRP | Ripple | XRP Ledger | * **ERC-20** means that a token is based on the Ethereum network. * **BEP-20** means that a token is based on the BNB Smart Chain network. Some currencies are available on multiple blockchains. In API requests, use the currency's API code to specify the correct blockchain version. For the list of API currency codes, see [API currency codes](/api-reference/currency-codes). Additional tokens on supported networks can be added by request. ## Supported fiat | Currency code | Currency name | | :------------ | :------------ | | EUR | Euro | ### Other fiat currencies These currencies can't be withdrawn directly to a bank account. You can hold a balance in these currencies in your [merchant account](/dashboard#viewing-your-balances), or [exchange](/exchanges) it to a cryptocurrency. The Company does not offer these currencies as part of its services. Any reference to or availability of these currencies within the internal settings is provided solely for administrative and convenience purposes and shall not be construed as an offer, support, or provision of services in relation to such currencies by the Company. | Currency code | Currency name | | :------------ | :----------------- | | USD | US dollar | | GBP | British pound | | ARS | Argentine peso | | AUD | Australian dollar | | AZN | Azerbaijani manat | | BDT | Bangladeshi taka | | BRL | Brazilian real | | CAD | Canadian dollar | | CHF | Swiss franc | | CLP | Chilean peso | | CNY | Chinese yuan | | CZK | Czech koruna | | GEL | Georgian lari | | HUF | Hungarian forint | | IDR | Indonesian rupiah | | ILS | Israeli new shekel | | INR | Indian rupee | | JPY | Japanese yen | | KGS | Kyrgyzstani som | | KRW | South Korean won | | LKR | Sri Lankan rupee | | MDL | Moldovan leu | | MXN | Mexican peso | | MYR | Malaysian ringgit | | NGN | Nigerian naira | | NOK | Norwegian krone | | NPR | Nepalese rupee | | NZD | New Zealand dollar | | PEN | Peruvian sol | | PHP | Philippine peso | | PLN | Polish złoty | | SEK | Swedish krona | | THB | Thai baht | | TJS | Tajikistani somoni | | TRY | Turkish lira | | VND | Vietnamese dong | | ZAR | South African rand | # Supported trading pairs Source: https://docs.cryptoprocessing.com/supported-trading-pairs To retrieve the complete and up-to-date list of supported exchange pairs, use the [/v2/currencies/rates](/api-reference/endpoints/currencies-rates) API endpoint. ## Quick lookup Enter any supported crypto or fiat currency to see what it can be exchanged for.

Click the field to browse all supported currencies, or start typing to search.

Convert to crypto

Convert to fiat

"" isn't a recognized currency code. Check the spelling, or browse the full list below.

## Full list | Convert from | Convert to Crypto | Convert to Fiat | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ADA | BTC, EURC (ERC-20), SOL, USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL) | ARS, AUD, AZN, BDT, BRL, CAD, CHF, CLP, CNY, CZK, EUR, GBP, GEL, HUF, IDR, ILS, INR, JPY, KGS, KRW, LKR, MDL, MXN, MYR, NGN, NOK, NPR, NZD, PEN, PLN, SEK, THB, TJS, TRY, USD, VND, ZAR | | BCH | BNB-BSC, BTC, ETH (Ethereum / Arbitrum / Base), SOL, USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL) | ARS, AUD, AZN, BDT, BRL, CAD, CHF, CLP, CNY, CZK, EUR, GBP, GEL, HUF, IDR, ILS, INR, JPY, KGS, KRW, LKR, MDL, MXN, MYR, NGN, NOK, NPR, NZD, PEN, PLN, SEK, THB, TJS, TRY, USD, VND, ZAR | | BNB-BSC | BCH, BTC, ETH (Ethereum / Arbitrum / Base), LTC, SOL, USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL), POL | AUD, CAD, CHF, EUR, GBP, HUF, INR, NOK, NZD, PLN, TRY, USD | | BTC | ADA, BCH, BNB-BSC, DOGE, ETH (Ethereum / Arbitrum / Base), EURC (ERC-20), LTC, SOL, TRX, USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL), XRP, POL | ARS, AUD, AZN, BDT, BRL, CAD, CHF, CLP, CNY, CZK, EUR, GBP, GEL, HUF, ILS, INR, JPY, KGS, KRW, LKR, MDL, MXN, MYR, NGN, NOK, NPR, NZD, PEN, PHP, PLN, SEK, THB, TJS, TRY, USD, VND, ZAR | | DOGE | BTC, SOL, EURC (ERC-20), USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL) | ARS, AUD, BRL, CAD, CHF, CLP, CNY, CZK, EUR, GBP, HUF, IDR, INR, JPY, KRW, MXN, MYR, NOK, NZD, PEN, PLN, SEK, THB, USD, VND, ZAR | | ETH | BTC, BCH, BNB-BSC, ETH (Arbitrum / Base), EURC (ERC-20), LTC, SOL, USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL), POL | ARS, AUD, AZN, BDT, BRL, CAD, CHF, CLP, CNY, CZK, EUR, GBP, GEL, HUF, IDR, ILS, INR, JPY, KGS, KRW, LKR, MDL, MXN, MYR, NGN, NOK, NPR, NZD, PEN, PHP, PLN, SEK, THB, TJS, TRY, USD, VND, ZAR | | ETH (Arbitrum) | BTC, BCH, BNB-BSC, ETH (Ethereum / Base), LTC, SOL, USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL), POL | EUR, USD, AUD, GBP, CAD, SEK, NOK, CHF, CNY, JPY, NZD, MXN, ARS, BRL, INR, KRW, MYR, THB, IDR, VND, PEN, CLP, CZK, PLN, ZAR, TJS, AZN, KGS, NGN, MDL, TRY, ILS, GEL, HUF, BDT, NPR, LKR, PHP | | ETH (Base) | BTC, BCH, BNB-BSC, ETH (Ethereum / Arbitrum), LTC, SOL, USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL), POL | EUR, USD, AUD, GBP, CAD, SEK, NOK, CHF, CNY, JPY, NZD, MXN, ARS, BRL, INR, KRW, MYR, THB, IDR, VND, PEN, CLP, CZK, PLN, ZAR, TJS, AZN, KGS, NGN, MDL, TRY, ILS, GEL, HUF, BDT, NPR, LKR, PHP | | EURC (ERC-20) | BTC, ADA, DOGE, ETH (Ethereum), LTC, USDC (ERC-20), SOL, TRX, XRP | EUR, USD | | LTC | BNB-BSC, BTC, ETH (Ethereum / Arbitrum / Base), EURC (ERC-20), SOL, USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL) | ARS, AUD, AZN, BDT, BRL, CAD, CHF, CLP, CNY, CZK, EUR, GBP, GEL, HUF, IDR, ILS, INR, JPY, KGS, KRW, LKR, MDL, MXN, MYR, NGN, NOK, NPR, NZD, PEN, PHP, PLN, SEK, THB, TJS, TRY, USD, VND, ZAR | | POL | BTC, BNB-BSC, ETH (Ethereum / Arbitrum / Base), USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL) | EUR, USD, GBP, ARS, AUD, AZN, BDT, BRL, CAD, CHF, CLP, CNY, CZK, GEL, HUF, IDR, ILS, INR, JPY, KGS, KRW, LKR, MDL, MXN, MYR, NGN, NOK, NPR, NZD, PEN, PHP, PLN, SEK, THB, TJS, TRY, VND, ZAR | | SOL | ADA, BCH, BNB-BSC, BTC, DOGE, ETH (Ethereum / Arbitrum / Base), EURC (ERC-20), LTC, TRX, USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL), XRP | ARS, AUD, AZN, BDT, BRL, CAD, CHF, CLP, CNY, CZK, EUR, GBP, GEL, HUF, IDR, ILS, INR, JPY, KGS, KRW, LKR, MDL, MXN, MYR, NGN, NOK, NPR, NZD, PEN, PHP, PLN, SEK, THB, TJS, TRY, USD, VND, ZAR | | TRX | BTC, SOL, EURC (ERC-20), USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL) | ARS, AUD, AZN, BDT, BRL, CAD, CHF, CLP, CNY, CZK, EUR, GBP, GEL, HUF, IDR, ILS, INR, JPY, KGS, KRW, LKR, MDL, MXN, MYR, NGN, NOK, NPR, NZD, PEN, PLN, SEK, THB, TJS, TRY, USD, VND, ZAR | | USDC (ERC-20) | ADA, BCH, BNB-BSC, BTC, ETH (Ethereum / Arbitrum / Base), EURC (ERC-20), LTC, SOL, USDC (Arbitrum / BEP-20 / Base / POL / SOL), TRX, XRP, DOGE, USDG (ERC-20 / SOL), POL | ARS, BDT, EUR, INR, PLN, USD | | USDC (Arbitrum) | BTC, ETH (Ethereum / Arbitrum / Base), LTC, BNB-BSC, USDC (ERC-20 / BEP-20 / Base / POL / SOL), SOL, BCH, TRX, ADA, DOGE, XRP, USDG (ERC-20 / SOL), POL | EUR, USD, ARS, GBP, IDR, AUD, ILS, NZD, AZN, INR, PEN, JPY, PHP, BRL, KGS, PLN, CAD, KRW, SEK, CHF, THB, CLP, TJS, CNY, MDL, TRY, CZK, MXN, GEL, MYR, VND, HUF, NGN, ZAR, NOK, BDT | | USDC (BEP-20) | ADA, BCH, BNB-BSC, BTC, DOGE, ETH (Ethereum / Arbitrum / Base), LTC, POL, SOL, TRX, USDC (ERC-20 / Arbitrum / Base / POL / SOL), USDG (ERC-20 / SOL), XRP | EUR, USD, ARS, AUD, AZN, BDT, BRL, CAD, CHF, CLP, CNY, CZK, GBP, GEL, HUF, IDR, ILS, INR, JPY, KGS, KRW, MDL, MXN, MYR, NGN, NOK, NZD, PEN, PHP, PLN, SEK, THB, TJS, TRY, VND, ZAR | | USDC (Base) | BTC, ETH (Ethereum / Arbitrum / Base), LTC, BNB-BSC, SOL, BCH, TRX, ADA, DOGE, XRP, USDC (ERC-20 / Arbitrum / BEP-20 / POL / SOL), USDG (ERC-20 / SOL), POL | EUR, USD, ARS, GBP, IDR, AUD, ILS, NZD, AZN, INR, PEN, JPY, PHP, BRL, KGS, PLN, CAD, KRW, SEK, CHF, THB, CLP, TJS, CNY, MDL, TRY, CZK, MXN, GEL, MYR, VND, HUF, NGN, ZAR, NOK, BDT | | USDC (POL) | BTC, ETH (Ethereum / Arbitrum / Base), LTC, BNB-BSC, USDC (ERC-20 / Arbitrum / BEP-20 / Base / SOL), SOL, BCH, TRX, ADA, DOGE, XRP, USDG (ERC-20 / SOL), POL | EUR, USD, GBP, ARS, AUD, AZN, BDT, BRL, CAD, CHF, CLP, CNY, CZK, GEL, HUF, IDR, ILS, INR, JPY, KGS, KRW, MDL, MXN, MYR, NGN, NOK, NZD, PEN, PHP, PLN, SEK, THB, TJS, TRY, VND, ZAR | | USDC (SOL) | ADA, BCH, BNB-BSC, BTC, DOGE, ETH (Ethereum / Arbitrum / Base), LTC, SOL, TRX, USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL), USDG (ERC-20 / SOL), XRP, POL | ARS, AUD, AZN, BDT, BRL, CAD, CHF, CLP, CNY, CZK, EUR, GBP, GEL, HUF, IDR, ILS, INR, JPY, KGS, KRW, MDL, MXN, MYR, NGN, NOK, NZD, PEN, PHP, PLN, SEK, THB, TJS, TRY, USD, VND, ZAR | | USDG (ERC-20) | USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL), USDG (SOL) | USD, EUR | | USDG (SOL) | USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL), USDG (ERC-20) | USD, EUR | | XRP | BTC, SOL, EURC (ERC-20), USDC (ERC-20 / Arbitrum / BEP-20 / Base / POL / SOL) | ARS, AUD, AZN, BRL, CAD, CHF, CLP, CNY, CZK, EUR, GBP, GEL, IDR, ILS, INR, JPY, KGS, KRW, MDL, MXN, MYR, NGN, NOK, NZD, PEN, PLN, SEK, THB, TJS, TRY, USD, VND, ZAR | # User data collection Source: https://docs.cryptoprocessing.com/user-data-collection To comply with EU regulations, CryptoProcessing by Coinspaid has to collect user data for all transactions. This affects three endpoints: * [/v2/withdrawal/crypto](/api-reference/endpoints/withdrawal-crypto) (Withdraw crypto) * [/v2/addresses/take](/api-reference/endpoints/addresses-take) (Create a crypto address) * [/payments/v1/requests](/api-reference/endpoints/payments) (Create a payment request) As an EU-based entity, CryptoProcessing by Coinspaid is required to comply with the MiCA (Markets in Crypto-Assets) regulations that aim to combat money laundering. This includes collecting certain data about natural persons and companies who send and receive crypto using our services. We are not collecting anything outside of the data you and your customers provide in API calls and in-app transactions. ## What data is required When you generate a new crypto address or create a payment request, you need to provide certain user data depending on who the sender is. This includes the `sender_type` parameter (either `legal` or `natural`) and the `sender_data` object. To make a withdrawal, you also need to share the same information about the recipient (`receiver_type` and `receiver_data`). In case of internal transfers within a company, `receiver_type` can be set to `self`. For legal entities, we ask for the company name and registration country. For natural persons, you need to provide the sender's first and last names and their date of birth.
Legal entity Natural person
* Company name (**required**) * Country of registration (**required**) * Email (optional) * First name (**required**) * Last name (**required**) * Date of birth (**required**) * Email (optional)
## Requesting data from the customer When requesting funds via a payment request, you can omit the `sender_type` and `sender_data` parameters. In this case, CryptoProcessing will use the data provided earlier for the same user, according to `end_user_reference`. If the data is omitted and cannot be found for the given `end_user_reference` (or if `end_user_reference` is omitted, too), the user will see a form for entering the data manually. They will have to fill in the data before they are shown the crypto address for sending funds. User data form in the payment request interface # Approve a withdrawal Source: https://docs.cryptoprocessing.com/withdrawals/approve-a-withdrawal When a withdrawal exceeds a configured limit, it is held for manual review and assigned a status. A user with the **Owner** or **Approver** role must then approve or decline the transaction before it can be processed. For withdrawals created in the merchant dashboard, the approving user must be a different user than the one who created the withdrawal. For API withdrawals, any user with the **Owner** or **Approver** role can approve or decline. There are two ways to approve or decline pending withdrawals. We recommend using the **Moderation queue**, which shows only the pending withdrawals awaiting your decision and lets you act on one or several at once. You can also approve withdrawals from the **Transactions** tab, which lists all transactions regardless of status. Both approaches are described below: * [Approve transactions in the Moderation queue](#approve-transactions-in-the-moderation-queue) — review pending withdrawals and apply a single decision to one or several transactions at once. * [Approve a transaction in the Transactions tab](#approve-a-transaction-in-the-transactions-tab) — open a single transaction and approve or decline it. The **Moderation queue (N)** tab shows the number of transactions you are authorized to approve right in its name, so you can tell at a glance whether anything is awaiting your decision without opening the queue. A number means that multiple transactions are pending; no number (or `0`) means there is nothing waiting for your approval. ## Approve transactions in the Moderation queue Use the **Moderation queue** to review and process several withdrawals at the same time. The queue shows only the transactions you are authorized to act on, and lets you apply a single approve or decline decision to multiple transactions in one step. The **Moderation queue** lists only the transactions available to you for **Approve** / **Decline** actions, and shows the number of transactions you are currently authorized to approve. By default, the **Date Range** filter is applied, showing transactions created within the last 3 months. To narrow the list further, click **Filters** and configure filters such as **Contact** (contacts from the address book), **Initiated by** (transaction initiator), and other transaction filters. Click any transaction to open a pane with additional information. You can process the transaction directly from this pane by clicking **Approve** or **Decline**. To approve or decline a single transaction without opening the pane, click the corresponding icon (the checkmark or the **x**) in that transaction's row. To process multiple transactions at once, either: * Select individual transactions by ticking the checkboxes next to them, or * Select all transactions currently visible in the queue by clicking the checkbox in the first column of the table header. Click **Approve** or **Decline** to apply the same moderation decision to all selected transactions. A **Comment** field appears when you confirm your decision — required when you decline, optional when you approve — and applies to all selected transactions. A single 2FA confirmation covers the whole action. In the Moderation queue, you cannot see transactions that you created yourself. As with individual approvals, these must be approved by a different user with the **Owner** or **Approver** role and will appear in the Moderation queue for other eligible users. ## Approve a transaction in the Transactions tab Approve or decline a single pending withdrawal directly from the Transactions tab. Optionally, click **Filters** and set the status filter to **Pending**. Find the withdrawal in the list and click it to open the transaction details. Click **Approve** to process the withdrawal or **Decline** to reject it. A **Comment** field appears when you confirm your decision — required when you decline, optional when you approve. The decision requires 2FA confirmation. ## FAQ #### Why is the Approve button greyed out? The **Approve** button is greyed out for either of these reasons: * You are the same user who created the withdrawal in the merchant dashboard. Interface withdrawals must be approved by a different user with the **Owner** or **Approver** role. Log in as a different eligible user to approve the transaction. * [Withdrawals are disabled](/merchant-administration/disable-withdrawals) for your merchant account. ## Related topics * [Configure withdrawal limits](/merchant-administration/configure-withdrawal-limits) # Contacts for crypto withdrawals Source: https://docs.cryptoprocessing.com/withdrawals/contacts When making a [crypto withdrawal](/withdrawals) using the merchant dashboard, you can use previously saved recipient addresses instead of pasting them again. The saved addresses are available from the withdrawal form or from the dedicated tab **Addresses → Contacts**. For cryptocurrencies with a [tag field](/deposits/tags), the tag is stored in the contact, too. Each contact must have a unique name. Addresses → Contacts To save a new address, go to **Addresses → Contacts** and click **Add contact**. Alternatively, after you made a withdrawal to a new address, click **Save address** on the withdrawal screen. To send cryptocurrency to a saved address, select it in **Addresses → Contacts** and click **Send**. Alternatively, select a cryptocurrency on the **Balances** tab, click **Send**, then click the book icon and select the contact. Save a contact Use a contact # Create a withdrawal Source: https://docs.cryptoprocessing.com/withdrawals/create-a-withdrawal You can send funds from your balance to your own crypto address or to a customer's address. This guide covers creating a withdrawal via the merchant dashboard; for the API method, see [/v2/withdrawal/crypto](/api-reference/endpoints/withdrawal-crypto). Alternatively, click the address-book icon next to the address field to select a saved contact instead of entering the address manually. See [Contacts](/withdrawals/contacts) for more details. See [User data collection](/user-data-collection) for details on what information may be required. If the withdrawal is internal, select the internal transfer checkbox instead; you don't need to fill out the user data in this case. # Design a crypto withdrawal form Source: https://docs.cryptoprocessing.com/withdrawals/design-withdrawal-form To let your customers withdraw in crypto from their balance on your site, add a custom withdrawal form. Withdrawalform We recommend that you: 1. Let your customers choose their preferred network and currency. 2. Warn your customers that if they make a withdrawal to an address on the wrong network, they might lose their funds. ## Currency selection Your customers should be able to choose their withdrawal currency and network. For withdrawals with conversion, the funds on your balance will be automatically converted to the customer's chosen currency. ## Recipient address Add an input field prompting the customer for their crypto address. We highly recommend warning the customer that they should make sure they're entering the address for their chosen currency and network. ## Withdrawal amount Add an input field prompting the customer for the withdrawal amount. # Crypto withdrawal fees Source: https://docs.cryptoprocessing.com/withdrawals/fees Crypto withdrawals are subject to both [processing fees](#processing-fee) and [mining fees](#mining-fee). ## Processing fee The processing fees are the paid to CryptoProcessing. They are listed on the **Fees** tab in your merchant dashboard, under the **Withdrawal operations** section. The exact fee may depend on the currency and on whether the payment involved a conversion between different currencies. Each fee has a minimum amount that will be subtracted regardless of the transaction amount. The applicable fees are: * **Withdrawal crypto** * **Withdrawal crypto exchange from crypto** * **Withdrawal crypto exchange from fiat** When the withdrawal is being processed [off-chain](/withdrawals#off-chain-withdrawals), the system uses the fees with "internal" in the name: * **Withdrawal crypto internal** * **Withdrawal crypto exchange from crypto internal** * **Withdrawal crypto exchange from fiat internal** ## Mining fee For some currencies, a mining fee will be deducted from your balance after each withdrawal. These fees are paid to the miners in the cryptocurrency's network. The fee amount depends on how busy the network is at the moment. CryptoProcessing deducts the mining fee for all withdrawals in BCH, LTC, DOGE, ADA and XRP, as well as [instant withdrawals](/withdrawals/instant-withdrawals) in BTC. In all other cases, the mining fees are not deducted. Instead, CryptoProcessing may use the average mining fee in the network to update the [minimum deposit fees](/deposits/fees#minimum-deposit-fee). # Crypto withdrawals Source: https://docs.cryptoprocessing.com/withdrawals/index You can send funds from your balance to your own or your customers' crypto addresses. This can be done via the API or from the merchant dashboard. Optionally, you can [convert funds](#withdrawals-with-conversion) from one currency to another when making a withdrawal. For some cryptocurrencies, [instant withdrawals](#instant-withdrawals) are available that are processed with higher priority. Depending on the target address, withdrawals can happen on-chain or [off-chain](#off-chain-withdrawals). When withdrawing via the merchant dashboard, you can save addresses as [contacts](/withdrawals/contacts) for future use. [Fees](/withdrawals/fees), [minimal withdrawal amounts](/confirmations-and-limits) and [withdrawal limits](/merchant-administration/configure-withdrawal-limits) may apply. ## Withdrawals with conversion When making a withdrawal using API, you can enable conversion to another currency. For a standard withdrawal, specify either the *sender amount* that will be deducted from your balance or the *received amount* that will be received by the other person. CryptoProcessing will automatically calculate the other value using the current currency rate. Both values do not include the [fees](/withdrawals/fees). For an [instant withdrawal](#instant-withdrawals), specify the *sender amount*. ## Instant withdrawals To provide the best experience for your customers, consider using *instant withdrawals* when the processing speed is critical. They work just like standard withdrawals, but faster: CryptoProcessing processes them with a higher priority and sends them to the network within **30 seconds to 2 minutes**. When using instant withdrawals, the [mining fee](/withdrawals/fees#mining-fee) is always charged, regardless of your fee package. Instant withdrawals are only supported for **Bitcoin, Bitcoin Cash, Litecoin, and DOGE**. If you are already using standard withdrawals, follow [these instructions](/withdrawals/instant-withdrawals) to start using instant withdrawals. ## Off-chain withdrawals If the withdrawal address happens to be controlled by CryptoProcessing, too, the transaction is being processed *off-chain*. This means that CryptoProcessing registers it internally but does not send the transaction to the blockchain. Just like a standard withdrawal, an off-chain withdrawal can be found on the **Transactions** tab. However, an off-chain withdrawal has an internal **TXID** instead of a public one. You can use this **TXID** to find the internal transaction in the merchant dashboard, but not in a blockchain explorer. In the [API callback](/api-reference/callbacks/withdrawal-callbacks), an off-chain withdrawal has the `transaction.transaction_type` property set to `"internal"` instead of `"blockchain"`. The [fee](/withdrawals/fees) for an off-chain withdrawal may differ from the standard one. The network fee is not paid for an off-chain withdrawal, as there is no network involved. ## Further reading Learn how to integrate the withdrawals flow into your site Walk through all scenarios to make sure your integration works correctly API endpoint API endpoint API endpoint API callbacks # Send crypto instantly Source: https://docs.cryptoprocessing.com/withdrawals/instant-withdrawals To switch from standard withdrawals to [instant withdrawals](/withdrawals#instant-withdrawals): Ask CryptoProcessing support team to enable the feature for the currencies you need. Replace [/v2/withdrawal/crypto](/api-reference/endpoints/withdrawal-crypto) with one of these special API endpoints wherever you need to prioritize the processing speed: * [/v2/crypto/withdrawal\_instant](/api-reference/endpoints/crypto-withdrawal-instant) * [/v2/crypto/withdrawal\_instant\_exchange](/api-reference/endpoints/crypto-withdrawal-instant-exchange) The requests for both API endpoints are similar to [/v2/withdrawal/crypto](/api-reference/endpoints/withdrawal-crypto), but some parameter names are different. Update the callback handler to support two additional CryptoProcessing [callbacks](/api-reference/callbacks/withdrawal-callbacks): * **withdrawal\_instant** * **withdrawal\_instant\_exchange** To make sure you support all possible scenarios, use our [integration test cases](/withdrawals/test-cases#instant-withdrawals). # Crypto withdrawals integration guide Source: https://docs.cryptoprocessing.com/withdrawals/integration-guide If your customers have a balance on your site, you can provide withdrawals in crypto. ## Set up withdrawals Configure your account and get an API key, see [Initial setup](/initial-setup). Add a withdrawal form to your site. For our recommendations on how to design the form, see [Design a withdrawal form](/withdrawals/design-withdrawal-form). Send a request to [/v2/withdrawal/crypto](/api-reference/endpoints/withdrawal-crypto). To request a withdrawal with exchange, include the `convert_to` parameter. You will also need to include these required parameters: * `foreign_id` is the unique ID of the withdrawal request. You can use any format you prefer. * `end_user_reference` is the customer's unique ID. CryptoProcessing uses it to group withdrawal requests made by each customer. It must not contain any identifying information, such as the customer's name. ```json title="Request example" theme={null} { "amount": "100", "currency": "EUR", "convert_to": "BTC", "address": "tb1qfdxh6gkfr0qgyatnlkd8khcnxph9tw06n6qwjc", "foreign_id": "withdrawal_123", "end_user_reference": "user_12345", "sender_type": "legal", "sender_data": { "legal_name": "Example GmbH", "country_of_registration": "DEU" }, "receiver_type": "natural", "receiver_data": { "first_name": "Friedrich", "last_name": "Müller", "date_of_birth": "1995-08-17" } } ``` ```json title="Response example" theme={null} { "data": { "id": 134702831, "foreign_id": "withdrawal_123", "end_user_reference": "user_12345", "type": "withdrawal_exchange", "status": "processing", "amount": "100.00000000", "sender_amount": "100.00000000", "sender_currency": "EUR", "receiver_currency": "BTC" } } ``` Once the withdrawal is processed, CryptoProcessing will send you a [callback](/api-reference/callbacks/withdrawal-callbacks). # Withdrawal statuses Source: https://docs.cryptoprocessing.com/withdrawals/statuses This section describes the statuses displayed in the merchant dashboard for withdrawals.
Status Description
The transaction is waiting to be reviewed by another team member, according to the merchant's [withdrawal limits](/merchant-administration/configure-withdrawal-limits).
Based on the team member's decision, the status will then change to .
The transaction is being generated and sent to the blockchain.
After sending, CryptoProcessing will change the status to .
The transaction is successfully sent to the blockchain.
The transaction is declined by another team member who reviewed it.
The transaction cannot be completed because the merchant's balance does not meet the requirements, or because [withdrawals have been disabled](/merchant-administration/disable-withdrawals) for the merchant. The specific error is shown in the transaction's details panel on the **Transactions** tab.
Possible errors are: * *"Not enough money on balance"* * *"Total of negative balances exceeds the allowed value"*
The transaction was cancelled by CryptoProcessing due to some other error. The specific error is shown in the transaction's details panel on the **Transactions** tab.
# Crypto withdrawals integration test cases Source: https://docs.cryptoprocessing.com/withdrawals/test-cases These are the test cases to help you test your site's integration with CryptoProcessing [crypto withdrawals](/withdrawals/integration-guide). For each test case, initiate a withdrawal via the [/v2/withdrawal/crypto](/api-reference/endpoints/withdrawal-crypto) endpoint and then process the relevant [callback](/api-reference/callbacks/withdrawal-callbacks). Depending on whether you work with standard withdrawals or instant withdrawals, you will need to use different callback types and field names. If your site supports both, make sure to go through both lists of test cases. Make sure to check these test cases if your site uses the [/v2/withdrawal/crypto](/api-reference/endpoints/withdrawal-crypto) endpoint.
Procedure Expected results
**Successful withdrawal**
1. Initiate a crypto withdrawal. * The site gets a `withdrawal` callback. * The callback status is `confirmed`.
**Successful withdrawal with conversion**
1. Initiate a withdrawal with the `convert_to` field. * The site gets a `withdrawal` callback. * The callback status is `confirmed`. * `currency_sent` describes the amount you sent (minus the network fee). Its currency is the same as you specified in `currency`. * `currency_received` describes the amount you received on your balance. Its currency is the same as you specified in `convert_to`.
**Withdrawal declined by the owner**
1. Go to **Settings → Withdrawal limits → API withdrawals → Custom API withdrawal limits** and set up a limit for a specific currency. 2. Initiate a withdrawal in that currency with an amount above the limit. 3. As an *Owner*, go to **Transactions** and select the pending transaction. 4. Click **Decline**. 5. Remove the withdrawal limit if you won't need it after testing. * The site gets two `withdrawal` callbacks. * The callback status is first `pending`, then `declined`.
**Withdrawal approved by the owner**
1. Go to **Settings → Withdrawal limits → API withdrawals → Custom API withdrawal limits** and set up a limit for a specific currency. 2. Initiate a withdrawal in that currency with an amount above the limit. 3. As an *Owner*, go to **Transactions** and select the pending transaction. 4. Click **Approve**. 5. Remove the withdrawal limit if you won't need it after testing. * The site gets two `withdrawal` callbacks. * The callback status is first `pending`, then `confirmed`.
Make sure to check these test cases if your site uses the [/v2/crypto/withdrawal\_instant](/api-reference/endpoints/crypto-withdrawal-instant) or [/v2/crypto/withdrawal\_instant\_exchange](/api-reference/endpoints/crypto-withdrawal-instant-exchange) endpoints.
Procedure Expected results
**Successful withdrawal**
1. Initiate an instant crypto withdrawal. * The site gets a `withdrawal_instant` callback. * The callback status is `confirmed`.
**Successful withdrawal with conversion**
1. Initiate an instant withdrawal with conversion. * The site gets a `withdrawal_instant_exchange` callback. * The callback status is `confirmed`. * `currency_sent` describes the amount you sent (minus the network fee). Its currency is the same as you specified in `sender_currency`. * `currency_received` describes the amount you received on your balance. Its currency is the same as you specified in `received_currency`.
**Withdrawal declined by the owner**
1. Go to **Settings → Withdrawal limits → API withdrawals → Custom API withdrawal limits** and set up a limit for a specific currency. 2. Initiate an instant withdrawal in that currency with an amount above the limit. 3. As an *Owner*, go to **Transactions** and select the pending transaction. 4. Click **Decline**. 5. Remove the withdrawal limit if you won't need it after testing. * The site gets two `withdrawal_instant` or `withdrawal_instant_exchange` callbacks. * The callback status is first `pending`, then `declined`.
**Withdrawal approved by the owner**
1. Go to **Settings → Withdrawal limits → API withdrawals → Custom API withdrawal limits** and set up a limit for a specific currency. 2. Initiate an instant withdrawal in that currency with an amount above the limit. 3. As an *Owner*, go to **Transactions** and select the pending transaction. 4. Click **Approve**. 5. Remove the withdrawal limit if you won't need it after testing. * The site gets two `withdrawal_instant` or `withdrawal_instant_exchange` callbacks. * The callback status is first `pending`, then `confirmed`.