Overview
Crypto Pay is a solution designed to be used as a crypto-currency Payment Service Provider for Payment Aggregators and as a standalone crypto-currency payment solution for Corporate Clients (Merchants) and provides the ability for Merchant Clients to deposit or pay for goods/services using crypto-currency. Features:
- Pay in crypto.
- Withdraw in crypto.
Base URL
The base url is https://api.cryptopayx.tech
As per RESTful design patterns, Crypto Pay API uses following HTTP methods:
GET
- Read resources.POST
- Create new resources.PUT
- Modify existing resources.DELETE
- Remove resources.
When you are making a request, you can pass arguments in it as:
- Parameters
- Valid JSON with
application/json
header.
Timestamps and other time-related fields are in milliseconds.
Data in response is listed in chronological order, newest on top.
Parameters for GET
endpoints must be sent as a query string.
Parameters For POST
, PUT
, and DELETE
endpoints may be sent as a query string or in the request body with content type application/json. You can mix parameters between both the query string and request body.
Parameters can be sent in any order.
If a parameter is sent in both the query string and request body, the query string parameter will be used.
Postman
We provide postman collections and environments for quick and easy use:
Return codes
200
Successful Request.
201
Created successfully.
400
Bad Request. Check the format of your request for mistakes and try again.
401
Unauthorized. Check if your API key is eligible for using the endpoint.
500
Server Error. Issue on our side. Contact us for more information.
404
Resource is missing. Contact us for more information.
Authentication
API Key
To access Crypto PayX API endpoints you have to obtain API key and secret. Starting 09/12/2024, we added a possibility for customers to generate and manage Crypto PayX credentials directly from Client Area.
For the customers with this functionality enabled, it can be accessed in their account Security settings.
The following API key management functionality is possible within the Client Area: - New API key request. One pair (key/secret) can be created for Crypto PayX. - Delete the existing API key. - Reset. Delete the existing API key and create a new one.
Make sure to replace <apiKey>
and <apiSecret>
in the code examples with your API key and secret respectively.
Use https://api.sandbox.cryptopayx.tech/ URL for Crypto PayX Sandbox. See Sandbox for more info.
// C# example
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json;
var apiKey = "<apiKey>";
var apiSecret = "<apiSecret>";
var client = new HttpClient
{
BaseAddress = new Uri("https://api.cryptopayx.tech")
};
var pathWithQuery = "/v1/test-api?testParam1=test1&testParam2=test2";
var pathWithOutQuery = "/v1/test-api";
var requestBody = JsonConvert.SerializeObject(
new
{
testProperty1 = "test1",
testProperty2 = "test12"
});
var request = new HttpRequestMessage()
{
Method = HttpMethod.Post,
Content = new StringContent(requestBody, Encoding.UTF8, "application/json"),
RequestUri = new Uri($"{pathWithQuery}", UriKind.Relative)
};
using HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(apiSecret));
using var sha256 = SHA256.Create();
var contentHash = Convert.ToBase64String(sha256.ComputeHash(Encoding.UTF8.GetBytes(content)));
var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
var signatureString = $"{timestamp}{request.Method}{pathWithOutQuery}{contentHash}";
var signatureHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(signatureString));
request.Headers.Add("CRYPTO-PAY-API-KEY", apiKey);
request.Headers.Add("CRYPTO-PAY-API-SIGN", Convert.ToBase64String(signatureHash));
request.Headers.Add("CRYPTO-PAY-API-TIMESTAMP", timestamp.ToString());
var response = await client.SendAsync(request);
// ...
//JavaScript example
const crypto = require('crypto');
const request = require('request');
const apiKey = "<apiKey>";
const apiSecret = "<apiSecret>";
const pathWithOutQuery = "/v1/test-api";
const req = {
method: 'POST',
url: '/v1/test-api?testParam1=test1&testParam2=test2',
body: JSON.stringify({testProperty1:"test1",testProperty2:"test2"})
};
const timestamp = Math.floor(Date.now());
const contentHash = crypto.createHash("sha256").update(req.body).digest().toString("base64");
const signatureString = timestamp + req.method + pathWithOutQuery + contentHash;
const signature = crypto.createHmac("sha256", Buffer.from(apiSecret, "base64")).update(Buffer.from(signatureString,"utf8")).digest().toString("base64");
const options = {
baseUrl: 'https://api.cryptopayx.tech',
url: req.url,
method: req.method,
headers: {
'CRYPTO-PAY-API-SIGN': signature,
'CRYPTO-PAY-API-TIMESTAMP': timestamp,
'CRYPTO-PAY-API-KEY': apiKey,
'content-type': 'application/json'
},
body: req.body
};
request(options,function(err, response){
// ...
}
Making a request
All requests to authorized endpoints must contain the following headers:
CRYPTO-PAY-API-KEY
- API Key.CRYPTO-PAY-API-SIGN
- Signature (see below).CRYPTO-PAY-API-TIMESTAMP
- request timestamp.
All request bodies should have content type application/json
and be valid JSON
Selecting timestamp
CRYPTO-PAY-API-TIMESTAMP
must be number of milliseconds since
UNIX Epoch. It should be within 60 seconds of the API service time to be considered as valid.
Signing message
Signature is generated by creating a SHA256 HMAC
using the API secret
on the string timestamp + method + pathWithQuery + contentHash
timestamp
- the same value asCRYPTO-PAY-API-TIMESTAMP
.method
- HTTP method in UPPER CASE.pathWithQuery
- path of the URL without query string params.contentHash
-base64
encodedSHA256
hash of serialized content (empty for GET requests).
Sandbox for payment intent
Overview
Crypto Payx sandbox is aimed to help those involved in Crypto Pay integration.
With Sandbox, it is possible to emulate payment intents with different parameters to test all possible scenarios for the integration, without the need to operate real data.
All the endpoints, response formats, error codes, and security features for the Sandbox are identical to that of real Crypto Payx.
How to test Crypto Payx integration using Sandbox
Make sure to have a real Crypto Payx Sandbox account created beforehand.
Crypto Payx Sandbox account is separate from your real account, and uses a separate API key and secret, which need to be generated for it. To create it please contact us.
After you have the API key and secret for your Crypto Pay Sandbox, you can authenticate by following the instructions at Authentication and test various flows for the payment intent.
URL for the Crypto Pay Sandbox: https://api.sandbox.cryptopayx.tech/
Possible payment intent flows
All the the mock payment intents in Crypto Payx Sandbox are done in the following amounts for the currencies in the table below:
Coin | Network | Mock payment amount |
---|---|---|
USDT | BNB_TEST | 100 USDT |
BTC | BTC_TEST | 0.01 BTC |
ETH | BNB_TEST | 1 ETH |
XRP | XRP_TEST | 0 XRP |
ADA | ADA_TEST | 100 ADA in two separate deposits for one payment intent. |
It means that if a payment intent is created with USDT coin and BNB_TEST network, Sandbox will emulate sending 100USDT for this payment intent. All the possible flows can be tested by adjusting the requested amount of crypto, and changing the account settings for:
- Threshold.
- Conversion settings.
Default threshold is set at 2%, if enabled. See Payment intent threshold for more info.
Flow 1
- Condition: Received amount is equal to expected amount.
- Threshold: Satisfied.
- Conversion Settings: n/a (applicable for all conversion settings).
- Resulting payment intent status: Completed.
- Available manual actions: n/a.
Executing the flow via iframe
HTTP Request
POST /v1/payment-intents/
- Create payment intent for 100 USD regardless of threshold and conversion settings.
- Choose coin USDT and network Binance Smart Chain Testnet (BNB_TEST).
Executing the flow via API
HTTP Request
POST /v2/payment-intents/
Request Body
"currencyFrom": "USDT",
"currencyTo": "USD",
"amountTo": 100,
"networkCode": "BNB_TEST",
"customOrderId": "test 1",
"callbackUrl": "https://webhook.site/e3f6bc53-f711-456d-85cb-a8cc3f9d27e7"
}
Expected Response
{
"paymentIntentId": "f7d6bb02-b399-40ef-9127-676d4db21861",
"currencyFrom": "USDT",
"amountFrom": 100,
"currencyTo": "USD",
"amountTo": 100,
"address": "pZvcn7hQNR7ptnF0X8mM4gnMBC6e3ihOrNsfWQRZ",
"additionalAddress": "string",
"additionalAddressType": "string",
"quoteValidTo": "2024-01-01T10:40:10.840Z",
"customOrderId":"test 1"
}
Expected Result
You should get two notifications as the payment intent is processed.
The first one with the payment intent pending.
{
"paymentIntentId": "f34d28d4-ddf2-448a-b70a-ae14342d1e83",
"customOrderId": "test 1",
"amountFrom": 100,
"amountTo": 100,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "Pending",
"receivedAmount": null,
"executedAmountTo": 100,
"executedCurrencyTo": null,
"statusDescription": null,
"address": "pZvcn7hQNR7ptnF0X8mM4gnMBC6e3ihOrNsfWQRZ",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": null,
"sourceAddress": null,
"notificationType": "PaymentIntentNotification"
}
The second notification - when the payment intent is successfully completed.
{
"paymentIntentId": "f34d28d4-ddf2-448a-b70a-ae14342d1e83",
"customOrderId": "test 1",
"amountFrom": 100,
"amountTo": 100,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "Completed",
"receivedAmount": 100,
"executedAmountTo": 100,
"executedCurrencyTo": "USD",
"statusDescription": null,
"address": "pZvcn7hQNR7ptnF0X8mM4gnMBC6e3ihOrNsfWQRZ",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": "lcevjc4idx7i1819t7uasgnjkv03gh",
"sourceAddress": "JYp7hxUCsm",
"notificationType": "PaymentIntentNotification"
}
Flow 2
- Condition: Received amount is more or less than expected amount.
- Threshold: Enabled (2%) and satisfied.
- Conversion Settings: n/a (applicable for all conversion settings).
- Resulting payment intent status: Partially completed.
- Available manual actions: n/a.
Executing the flow via iframe
HTTP Request
POST /v1/payment-intents/
- Create payment intent for 102 USD with default 2% threshold and conversion disabled for account or a specific currency.
- Choose coin USDT and network Binance Smart Chain Testnet (BNB_TEST).
Executing the flow via API
HTTP Request
POST /v2/payment-intents/
Request Body
{
"currencyFrom": "USDT",
"currencyTo": "USD",
"amountTo": 102,
"networkCode": "BNB_TEST",
"customOrderId": "test 1",
"callbackUrl": "https://webhook.site/e3f6bc53-f711-456d-85cb-a8cc3f9d27e7"
}
Expected Response
{
"paymentIntentId": "f7d6bb02-b399-40ef-9127-676d4db21862"
"currencyFrom": "USDT",
"amountFrom": 102,
"currencyTo": "USD",
"amountTo": 102,
"address": "rltH58oowqTZjCziPhGL6m4jdzqeeqx3jAGr16de",
"additionalAddress": "string",
"additionalAddressType": "string",
"quoteValidTo": "2024-01-01T10:40:10.840Z",
"customOrderId":"test 1"
}
Expected Result
You should get three notifications as the payment intent is processed.
The first one with the payment intent pending.
{
"paymentIntentId": "3d53363a-e3f1-412e-a808-457802e42d7c",
"customOrderId": "test 1",
"amountFrom": 102,
"amountTo": 102,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "Pending",
"receivedAmount": null,
"executedAmountTo": 102,
"executedCurrencyTo": null,
"statusDescription": null,
"address": "rltH58oowqTZjCziPhGL6m4jdzqeeqx3jAGr16de",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": null,
"sourceAddress": null,
"notificationType": "PaymentIntentNotification"
}
As the amount is not equal to the amount requested, which fails the initial payment intent, but within the threshold, the automatic retry payment intent is initiated and gets completed successfully.
{
"paymentIntentId": "3d53363a-e3f1-412e-a808-457802e42d7c",
"retryPaymentIntentId": "9fffbaa3-e565-4b81-96ef-a474042a902b",
"customOrderId": "test 1",
"amountFrom": 100,
"amountTo": 100,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "Completed",
"notificationType": "AutoRetryPaymentIntentNotification"
}
After the auto retry is completed, the initial payment intent is completed with "Partially completed" status, and the third notification is sent.
{
"paymentIntentId": "3d53363a-e3f1-412e-a808-457802e42d7c",
"customOrderId": "test 1",
"amountFrom": 102,
"amountTo": 102,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "PartiallyCompleted",
"receivedAmount": 100,
"executedAmountTo": 100,
"executedCurrencyTo": "USD",
"statusDescription": "Invalid amount: Less than expected",
"address": "rltH58oowqTZjCziPhGL6m4jdzqeeqx3jAGr16de",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": "oixtgm042pg7p4y12qbwybq3ne2w6e",
"sourceAddress": "6VYFAWqT1g",
"notificationType": "PaymentIntentNotification"
}
Flow 3
- Condition: Received amount is more or less than expected amount.
- Threshold: Enabled (2%) and is not satisfied.
- Conversion Settings: Disabled for account or specific currency.
- Resulting payment intent status: Manual action required
- Available manual actions: Refund,Accept recieved amount.
- Comment: it is not possible to deposit more within the initial payment intent after the initial transaction.
Executing the flow via iframe
HTTP Request
POST /v1/payment-intents/
- Create payment intent for 132 USD with default 2% threshold and conversion disabled for account or specific currency.
- Choose coin USDT and network Binance Smart Chain Testnet (BNB_TEST).
Executing the flow via API
HTTP Request
POST /v2/payment-intents/
Request Body
{
"currencyFrom": "USDT",
"currencyTo": "USD",
"amountTo": 132,
"networkCode": "BNB_TEST",
"customOrderId": "test 1",
"callbackUrl": "https://webhook.site/e3f6bc53-f711-456d-85cb-a8cc3f9d27e7"
}
Expected Response
{
"paymentIntentId": "f7d6bb02-b399-40ef-9127-676d4db21862",
"currencyFrom": "USDT",
"amountFrom": 132,
"currencyTo": "USD",
"amountTo": 132,
"address": "rltH58oowqTZjCziPhGL6m4jdzqeeqx3jAGr16de",
"additionalAddress": "string",
"additionalAddressType": "string",
"quoteValidTo": "2024-01-01T10:40:10.840Z",
"customOrderId":"test 1"
}
Expected Result
You should get three notifications as the payment intent is processed.
The first one with the payment intent pending.
{
"paymentIntentId": "2d24bd55-2cbd-456a-9319-9972d5394237",
"customOrderId": "test 1",
"amountFrom": 132,
"amountTo": 132,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "Pending",
"receivedAmount": null,
"executedAmountTo": 132,
"executedCurrencyTo": null,
"statusDescription": null,
"address": "GutRzPnRdFRKnF6IMtgiYXbq9dxMbJsLLUpT8dBn",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": null,
"sourceAddress": null,
"notificationType": "PaymentIntentNotification"
}
As the amount is not equal to the amount requested, which fails the initial payment intent, and doesn't satisfy the threshold, the automatic retry payment intent is initiated and fails.
{
"paymentIntentId": "2d24bd55-2cbd-456a-9319-9972d5394237",
"retryPaymentIntentId": "81e00873-cb54-4fe2-9969-58804ad75a07",
"customOrderId": "test 1",
"amountFrom": 100,
"amountTo": 100,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "Failed",
"notificationType": "AutoRetryPaymentIntentNotification"
}
After the auto retry has failed, the initial payment intent is completed with "Manual action required" status, and the third notification is sent.
{
"paymentIntentId": "2d24bd55-2cbd-456a-9319-9972d5394237",
"customOrderId": "test 1",
"amountFrom": 132,
"amountTo": 132,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "ManualActionRequired",
"receivedAmount": 100,
"executedAmountTo": 132,
"executedCurrencyTo": null,
"statusDescription": "Invalid amount: Less than expected",
"address": "GutRzPnRdFRKnF6IMtgiYXbq9dxMbJsLLUpT8dBn",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": "lrkzdzu28mtq93m1jtzc2fsaaqhaaz",
"sourceAddress": "XIzmJWPM63",
"notificationType": "PaymentIntentNotification"
}
Flow 4
- Condition: Received amount is more or less than expected amount.
- Threshold: Enabled (2%) and is not satisfied.
- Conversion Settings: Enabled.
- Resulting payment intent status: Manual action required
- Available manual actions: Refund,Retry,Accept recieved amount
- Comment: it is not possible to deposit more within the initial payment intent after the initial transaction.
Executing the flow via iframe
HTTP Request
POST /v1/payment-intents/
- Create payment intent for 92 USD with default 2% threshold and enabled conversion.
- Choose coin USDT and network Binance Smart Chain Testnet (BNB_TEST).
Executing the flow via API
HTTP Request
POST /v2/payment-intents/
Request Body
{
"currencyFrom": "USDT",
"currencyTo": "USD",
"amountTo": 92,
"networkCode": "BNB_TEST",
"customOrderId": "test 1",
"callbackUrl": "https://webhook.site/e3f6bc53-f711-456d-85cb-a8cc3f9d27e7"
}
Expected Response
{
"paymentIntentId": "f7d6bb02-b399-40ef-9127-676d4db21862",
"currencyFrom": "USDT",
"amountFrom": 92,
"currencyTo": "USD",
"amountTo": 92,
"address": "rltH58oowqTZjCziPhGL6m4jdzqeeqx3jAGr16de",
"additionalAddress": "string",
"additionalAddressType": "string",
"quoteValidTo": "2024-01-01T10:40:10.840Z",
"customOrderId":"test 1"
}
Expected Result
You should get three notifications as the payment intent is processed.
The first one with the payment intent pending.
{
"paymentIntentId": "2d24bd55-2cbd-456a-9319-9972d5394237",
"customOrderId": "test 1",
"amountFrom": 92,
"amountTo": 92,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "Pending",
"receivedAmount": null,
"executedAmountTo": 92,
"executedCurrencyTo": null,
"statusDescription": null,
"address": "GutRzPnRdFRKnF6IMtgiYXbq9dxMbJsLLUpT8dBn",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": null,
"sourceAddress": null,
"notificationType": "PaymentIntentNotification"
}
As the amount is not equal to the amount requested, which fails the initial payment intent, and doesn't satisfy the threshold, the automatic retry payment intent is initiated and fails.
{
"paymentIntentId": "2d24bd55-2cbd-456a-9319-9972d5394237",
"retryPaymentIntentId": "81e00873-cb54-4fe2-9969-58804ad75a07",
"customOrderId": "test 1",
"amountFrom": 100,
"amountTo": 100,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "Failed",
"notificationType": "AutoRetryPaymentIntentNotification"
}
After the auto retry has failed, the initial payment intent is completed with "Manual action required" status, and the third notification is sent.
{
"paymentIntentId": "2d24bd55-2cbd-456a-9319-9972d5394237",
"customOrderId": "test 1",
"amountFrom": 92,
"amountTo": 92,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "ManualActionRequired",
"receivedAmount": 100,
"executedAmountTo": 92,
"executedCurrencyTo": null,
"statusDescription": "Invalid amount: Less than expected",
"address": "GutRzPnRdFRKnF6IMtgiYXbq9dxMbJsLLUpT8dBn",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": "lrkzdzu28mtq93m1jtzc2fsaaqhaaz",
"sourceAddress": "XIzmJWPM63",
"notificationType": "PaymentIntentNotification"
}
Flow 5
- Condition: Received amount is more or less than expected amount.
- Threshold: Disabled (0%).
- Conversion Settings: Enabled.
- Resulting payment intent status: Manual action required
- Available manual actions: Refund,Retry,Accept recieved amount.
- Comment: it is not possible to deposit more within the initial payment intent after the initial transaction.
Executing the flow via iframe
HTTP Request
POST /v1/payment-intents/
- Create payment intent for 99 USD with disabled threshold and enabled conversion.
- Choose coin USDT and network Binance Smart Chain Testnet (BNB_TEST).
Executing the flow via API
HTTP Request
POST /v2/payment-intents/
Request Body
{
"currencyFrom": "USDT",
"currencyTo": "USD",
"amountTo": 99,
"networkCode": "BNB_TEST",
"customOrderId": "test 1",
"callbackUrl": "https://webhook.site/e3f6bc53-f711-456d-85cb-a8cc3f9d27e7"
}
Expected Response
{
"paymentIntentId": "f7d6bb02-b399-40ef-9127-676d4db21862",
"currencyFrom": "USDT",
"amountFrom": 99,
"currencyTo": "USD",
"amountTo": 99,
"address": "rltH58oowqTZjCziPhGL6m4jdzqeeqx3jAGr16de",
"additionalAddress": "string",
"additionalAddressType": "string",
"quoteValidTo": "2024-01-01T10:40:10.840Z",
"customOrderId":"test 1"
}
Expected Result
You should get three notifications as the payment intent is processed.
The first one with the payment intent pending.
{
"paymentIntentId": "2d24bd55-2cbd-456a-9319-9972d5394237",
"customOrderId": "test 1",
"amountFrom": 99,
"amountTo": 99,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "Pending",
"receivedAmount": null,
"executedAmountTo": 99,
"executedCurrencyTo": null,
"statusDescription": null,
"address": "GutRzPnRdFRKnF6IMtgiYXbq9dxMbJsLLUpT8dBn",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": null,
"sourceAddress": null,
"notificationType": "PaymentIntentNotification"
}
As the amount is not equal to the amount requested, which fails the initial payment intent, and there is no threshold to allow any deviation from the requested amount, the automatic retry payment intent is initiated and fails.
{
"paymentIntentId": "2d24bd55-2cbd-456a-9319-9972d5394237",
"retryPaymentIntentId": "81e00873-cb54-4fe2-9969-58804ad75a07",
"customOrderId": "test 1",
"amountFrom": 100,
"amountTo": 100,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "Failed",
"notificationType": "AutoRetryPaymentIntentNotification"
}
After the auto retry has failed, the initial payment intent is completed with "Manual action required" status, and the third notification is sent.
{
"paymentIntentId": "2d24bd55-2cbd-456a-9319-9972d5394237",
"customOrderId": "test 1",
"amountFrom": 99,
"amountTo": 99,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "ManualActionRequired",
"receivedAmount": 100,
"executedAmountTo": 99,
"executedCurrencyTo": null,
"statusDescription": "Invalid amount: More than expected",
"address": "GutRzPnRdFRKnF6IMtgiYXbq9dxMbJsLLUpT8dBn",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": "lrkzdzu28mtq93m1jtzc2fsaaqhaaz",
"sourceAddress": "XIzmJWPM63",
"notificationType": "PaymentIntentNotification"
}
Flow 6
- Condition: Received amount is more or less than expected amount.
- Threshold: Disabled (0%).
- Conversion Settings: Disabled for account or specific currency.
- Resulting payment intent status: Manual action required
- Available manual actions: Refund,Accept recieved amount.
- Comment: it is not possible to deposit more within the initial payment intent after the initial transaction.
Executing the flow via iframe
HTTP Request
POST /v1/payment-intents/
- Create payment intent for 101 USD with disabled threshold and disabled conversion.
- Choose coin USDT and network Binance Smart Chain Testnet (BNB_TEST).
Executing the flow via API
HTTP Request
POST /v2/payment-intents/
Request Body
{
"currencyFrom": "USDT",
"currencyTo": "USD",
"amountTo": 101,
"networkCode": "BNB_TEST",
"customOrderId": "test 1",
"callbackUrl": "https://webhook.site/e3f6bc53-f711-456d-85cb-a8cc3f9d27e7"
}
Expected Response
{
"paymentIntentId": "f7d6bb02-b399-40ef-9127-676d4db21862",
"currencyFrom": "USDT",
"amountFrom": 101,
"currencyTo": "USD",
"amountTo": 101,
"address": "rltH58oowqTZjCziPhGL6m4jdzqeeqx3jAGr16de",
"additionalAddress": "string",
"additionalAddressType": "string",
"quoteValidTo": "2024-01-01T10:40:10.840Z",
"customOrderId":"test 1"
}
Expected Result
You should get three notifications as the payment intent is processed.
The first one with the payment intent pending.
{
"paymentIntentId": "2d24bd55-2cbd-456a-9319-9972d5394237",
"customOrderId": "test 1",
"amountFrom": 101,
"amountTo": 101,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "Pending",
"receivedAmount": null,
"executedAmountTo": 101,
"executedCurrencyTo": null,
"statusDescription": null,
"address": "GutRzPnRdFRKnF6IMtgiYXbq9dxMbJsLLUpT8dBn",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": null,
"sourceAddress": null,
"notificationType": "PaymentIntentNotification"
}
As the amount is not equal to the amount requested, which fails the initial payment intent, and there is no threshold to allow any deviation from the requested amount, the automatic retry payment intent is initiated and fails.
{
"paymentIntentId": "2d24bd55-2cbd-456a-9319-9972d5394237",
"retryPaymentIntentId": "81e00873-cb54-4fe2-9969-58804ad75a07",
"customOrderId": "test 1",
"amountFrom": 100,
"amountTo": 100,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "Failed",
"notificationType": "AutoRetryPaymentIntentNotification"
}
After the auto retry has failed, the initial payment intent is completed with "Manual action required" status, and the third notification is sent.
{
"paymentIntentId": "2d24bd55-2cbd-456a-9319-9972d5394237",
"customOrderId": "test 1",
"amountFrom": 101,
"amountTo": 101,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "ManualActionRequired",
"receivedAmount": 100,
"executedAmountTo": 101,
"executedCurrencyTo": null,
"statusDescription": "Invalid amount: Less than expected",
"address": "GutRzPnRdFRKnF6IMtgiYXbq9dxMbJsLLUpT8dBn",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": "lrkzdzu28mtq93m1jtzc2fsaaqhaaz",
"sourceAddress": "XIzmJWPM63",
"notificationType": "PaymentIntentNotification"
}
Flow 7
- Condition:No funds were received within the payment intent validity timeframe (30 seconds as of now).
- Threshold: n/a.
- Conversion Settings: n/a.
- Resulting payment intent status: Failed.
- Available manual actions: n/a.
If the deposit will be received after the payment intent validity timeframe, and the deposit sum satisfies payment intent threshold requirements, payment intent status will change to `Completed'
Executing the flow via iframe
HTTP Request
POST /v1/payment-intents/
- Create payment intent for 0 USD.
- Choose coin XRP and network XRP_TEST.
Executing the flow via API
HTTP Request
POST /v2/payment-intents/
Request Body
{
"currencyFrom": "XRP",
"currencyTo": "USD",
"amountTo": 132,
"networkCode": "XRP_TEST",
"customOrderId": "test 1",
"callbackUrl": "https://webhook.site/e3f6bc53-f711-456d-85cb-a8cc3f9d27e7"
}
Expected Response
{
"paymentIntentId": "f7d6bb02-b399-40ef-9127-676d4db21862",
"currencyFrom": "XRP",
"amountFrom": 1334.52,
"currencyTo": "USD",
"amountTo": 132,
"address": "rltF58oowqTZjCziPhGL6m4jdzqeeqx3jAGr16de",
"additionalAddress": "string",
"additionalAddressType": "string",
"quoteValidTo": "2024-01-01T10:40:10.840Z",
"customOrderId":"test 1"
}
Expected Result
You should get two notifications as the payment intent is processed.
The first one with the payment intent pending.
{
"paymentIntentId": "c435d1fb-82b8-4ed9-8aee-535996fe5e01",
"customOrderId": "test 1",
"amountFrom": 1334.52,
"amountTo": 132,
"currencyFrom": "XRP",
"currencyTo": "USD",
"status": "Pending",
"receivedAmount": null,
"executedAmountTo": 132,
"executedCurrencyTo": null,
"statusDescription": null,
"address": "okwKBxzZWygcCPNO2QTu8G6dIuv9WfzZu1D9C2Os",
"networkCode": "XRP_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": null,
"sourceAddress": null,
"notificationType": "PaymentIntentNotification"
}
since "receivedAmount": null
means no mock deposit is send for this payment intent, after the 30 seconds from the creation of this payment intent is elapsed, it fails and sends a notification
for this.
{
"paymentIntentId": "c435d1fb-82b8-4ed9-8aee-535996fe5e01",
"customOrderId": "test 1",
"amountFrom": 1334.52,
"amountTo": 132,
"currencyFrom": "XRP",
"currencyTo": "USD",
"status": "Failed",
"receivedAmount": null,
"executedAmountTo": 132,
"executedCurrencyTo": null,
"statusDescription": "Out of time",
"address": "okwKBxzZWygcCPNO2QTu8G6dIuv9WfzZu1D9C2Os",
"networkCode": "XRP_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": null,
"sourceAddress": null,
"notificationType": "PaymentIntentNotification"
}
Flow 8
Refund
In case deposit amount by the payment intent is more than zero, and it has a status "ManualActionRequired"
, it is possible to emulate processing a crypto refund and return the deposited funds back.
Two endpoints are used to emulate the flow.
- Payment intent refund fee estimate.
- Payment intent refund execution.
1.HTTP Request
[POST] /v1/payment-intents/{paymentIntentId}/crypto-refunds/fee
where {paymentIntentID}
is the ID of a payment intent you want to refund.
Expected Response
{
"amount" : 80.00,
"feeAmount" : 10.00,
"totalAmount" : 90.00
}
Expected Result
No notification is sent on this step.
2.HTTP Request
[POST] /v1/payment-intents/{paymentIntentId}/crypto-refunds
where {paymentIntentID}` is the ID of a payment intent to manually retry.
Expected Result
On the second step, refund is executed, and the deposit amount gets sent to the address it was sent from, minus the fee.
Three notifications should be sent on this step.
The first one notifies about the processing refund.
{
"paymentIntentId": "470d0f71-6c7f-455f-a742-064992af8781",
"cryptoRefundPaymentIntentId": "4c438cc0-422c-4d90-ab2a-688bb78f6f0b",
"customOrderId": "test 1",
"amount": 100,
"feeAmount": 10,
"currency": "USDT",
"destinationAddress": "sdfsd",
"destinationAdditionalAddress": "",
"networkCode": "BNB_TEST",
"status": "ProcessingRefund",
"externalTransactionId": null,
"statusDescription": null,
"notificationType": "CryptoRefundPaymentIntentNotification"
}
The second notification is sent when the refund has been successfully withdrawn to the source address.
{
"paymentIntentId": "470d0f71-6c7f-455f-a742-064992af8781",
"cryptoRefundPaymentIntentId": "4c438cc0-422c-4d90-ab2a-688bb78f6f0b",
"customOrderId": "test 1",
"amount": 100,
"feeAmount": 10,
"currency": "USDT",
"destinationAddress": "sdfsd",
"destinationAdditionalAddress": "",
"networkCode": "BNB_TEST",
"status": "Completed",
"externalTransactionId": null,
"statusDescription": null,
"notificationType": "CryptoRefundPaymentIntentNotification",
}
The third notification is sent when the initial payment intent status is changed to "ManuallyCompletedWithRefund"
.
{
"paymentIntentId": "470d0f71-6c7f-455f-a742-064992af8781",
"customOrderId": "test 1",
"amountFrom": 132,
"amountTo": 132,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "ManuallyCompletedWithRefund",
"receivedAmount": 100,
"executedAmountTo": 100,
"executedCurrencyTo": "USDT",
"statusDescription": "Invalid amount: Less than expected",
"address": "F2uCZbiEXadqm1L79aRkRjTKPP7JuVGsFYQKbbIV",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": "1bv12qcs8ihsrlnszs2gyik4jbizze",
"sourceAddress": "Vyiq1dF0xp",
"notificationType": "PaymentIntentNotification"
}
Flow 9
Retry
In case deposit amount by the payment intent is more than zero, it has a status "ManualActionRequired"
and conversion is enabled, it is possible to emulate processing a retry.
Retry flow wiil process this payment intent with the actual amount deposited.
Two endpoints are used to emulate the flow
1.Manual payment intent retry quote request. 2.Manual payment intent retry execution.
1.HTTP Request
[POST] /v1/payment-intents/
{paymentIntentId}/retry/request-for-quotewhere {paymentIntentID}
is the ID of a payment intent to manually retry.
Expected Response
{
"currencyFrom": "USDT",
"amountFrom": 90,
"currencyTo": "USD",
"amountTo": 90,
"quoteValidTo": "2023-11-01T10:40:10.840Z"
}
Expected Result
Requesting the quote for the payment intent manual retry is a required step.
It will initiate the manual payment retry, and put it in Pending
status until the second step is completed.
Notification regarding that should be sent.
{
"paymentIntentId": "b11c532e-a552-437f-8fe5-1e8a837126b3",
"retryPaymentIntentId": "21c4ad2a-1a07-4b15-ae7e-589f256c6c50",
"customOrderId": "test 1",
"amountFrom": 90,
"amountTo": 90,
"currencyFrom": "USDT",
"currencyTo": "USD",
"quoteValidTo": "2024-02-01T17:23:53.5312917Z",
"status": "Pending",
"notificationType": "RetryPaymentIntentNotification"
}
2.HTTP Request
[POST] /v1/payment-intents/
{paymentIntentId}/retrywhere {paymentIntentID}
is the ID of a payment intent to manually retry.
Expected Result
On the second step, manual retry is executed, and payment intent gets processed with the actual deposit amount, regardless of the initial requested one.
Two notifications should be sent on this step.
The first one notifies about the completed retry payment intent.
{
"paymentIntentId": "b11c532e-a552-437f-8fe5-1e8a837126b3",
"retryPaymentIntentId": "21c4ad2a-1a07-4b15-ae7e-589f256c6c50",
"customOrderId": "test 1",
"amountFrom": 90,
"amountTo": 90,
"currencyFrom": "USDT",
"currencyTo": "USD",
"quoteValidTo": "2024-02-01T17:23:53.531291Z",
"status": "Completed",
"notificationType": "RetryPaymentIntentNotification"
}
In case of customer currency conversion, an additional PaymentIntentMerchantConversion notification will be sent.
{
"merchantConversionId": "6dd8d03d-0c01-4560-892d-24f3efb9453b",
"paymentIntentId": "e0c2f97c-48f7-4c31-883d-2e2621b88592",
"amountFrom": 72,
"amountTo": 0.02650896,
"currencyFrom": "USDT",
"currencyTo": "ETH",
"status": "Completed",
"failureReason": null,
"notificationType": "PaymentIntentMerchantConversionNotification"
}
The second notification is sent when the initial payment intent status is changed to "ManuallyCompletedWithRetry"
.
{
"paymentIntentId": "b11c532e-a552-437f-8fe5-1e8a837126b3",
"customOrderId": "test 1",
"amountFrom": 132,
"amountTo": 132,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "ManuallyCompletedWithRetry",
"receivedAmount": 100,
"executedAmountTo": 90,
"executedCurrencyTo": "USD",
"statusDescription": "Invalid amount: Less than expected",
"address": "b4R6rWXQn8fqpMD5LOXkPu90iCilwvHRGuE55fw0",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": "a0aone30w9vicfb9jk2fn1jvd6g59x",
"sourceAddress": "gbOsgDPwfV",
"notificationType": "PaymentIntentNotification"
}
Flow 10
Accept recieved amount
Any deposited amount more than 0(zero) can be manually accepted for the payment intent with "ManualActionRequired"
status.
HTTP Request
[POST] /v1/payment-intents/{paymentIntentId}/manually-completed
where {paymentIntentID} is the ID of a payment intent to manually complete.
Expected Response
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"createdOn": "2024-03-13T09:33:53.712Z",
"customOrderId": "string",
"callbackUrl": "string",
"amountFrom": 0,
"amountTo": 0,
"currencyFrom": "string",
"currencyTo": "string",
"status": "string",
"receivedAmount": 0,
"executedAmountTo": 0,
"executedCurrencyTo": "string",
"statusDescription": "string",
"address": "string",
"networkCode": "string",
"additionalAddress": "string",
"processingFeeAmount": 0,
"processingFeeCurrency": "string",
"originTransactionId": 0,
"transactionHash": "string",
"sourceAddress": "string",
"accountId": "string",
"retryPaymentIntents": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"createdOn": "2024-03-13T09:33:53.712Z",
"type": "string",
"amountFrom": 0,
"amountTo": 0,
"quoteValidTo": "2024-03-13T09:33:53.712Z",
"status": "string",
"failureReason": "string",
"address": "string",
"additionalAddress": "string",
"networkCode": "string",
"feeAmount": 0,
"externalTransactionId": "string"
}
],
"customConversion": {
"id": "string",
"currencyTo": "string",
"amountTo": 0,
"processingFeeAmount": 0,
"processingFeeCurrency": "string",
"status": "string",
"failureReason": "string"
}
}
Expected Result
The deposited amount is manually accepted for the payment intent, and its status changes to "ManuallyCompletedAmountAcceptable"
.
Notification is sent once the payment intent status updates.
{
"paymentIntentId": "303e492d-1cde-4625-bd45-372a38bd92a1",
"customOrderId": "test 1",
"amountFrom": 132,
"amountTo": 132,
"currencyFrom": "USDT",
"currencyTo": "USD",
"status": "ManuallyCompletedAmountAcceptable",
"receivedAmount": 100,
"executedAmountTo": 132,
"executedCurrencyTo": null,
"statusDescription": "Invalid amount: Less than expected",
"address": "jg2BYq1G7PsjWHCXBuPfzmKbKFTzHSJOxW9Me55T",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": "yglcgkkninm3cq1h55rc79ydxi7el7",
"sourceAddress": "IBe17lGkHh",
"notificationType": "PaymentIntentNotification"
}
Flow 11
Underpaid payment intent top-up
- Condition: Underpaid payment intent top-up, two separate deposits for one payment intent.
- Threshold: Not satisfied after first deposit and after second and consecutive deposits in case of a failed top-up flow, satisfied after second deposit in case of a successful top-up flow.
- Conversion Settings: n/a (applicable for all conversion settings).
- Resulting payment intent status: Partially completed.
- Available manual actions: In case of a successful top-up flow - n/a, in case of a failed top-up flow - Refund,Retry,Accept recieved amount.
HTTP Request
POST /v2/payment-intents/
Request Body
{
"currencyFrom": "ADA",
"currencyTo": "USD",
"amountTo": 100,
"networkCode": "ADA_TEST",
"customOrderId": "test 1",
"callbackUrl": "https://webhook.site/e3f6bc53-f711-456d-85cb-a8cc3f9d27e"
}
Expected Response
{
"paymentIntentId": "8d6f8bad-e00f-405d-897f-45a8e5896770"
"currencyFrom": "ADA",
"amountFrom": 200,
"currencyTo": "USD",
"amountTo": 100,
"address": "EVnabLyYuXmINTMrRAsantpIyIHrSR0O1EC8Ugv0",
"additionalAddress": "string",
"additionalAddressType": "string",
"quoteValidTo": "2024-01-01T10:40:10.840Z",
"customOrderId":"test 1"
}
Expected Result in case of a successful top-up flow
In this Sandbox flow we simulate the situation, where:
- The first deposit by the payment intent is less than the requested amount and doesn't satisfy the threshold.
- The second deposit by the payment intent adds the missing amount to the first deposit, so the deposits sum satisfies the requirements of the payment intent.
ADA to USD exchange rate is assumed to be 2 to 1 in this example, so 200 ADA=100 USD.
The following notifications are sent for that flow.
The first one with the payment intent pending.
{
"paymentIntentId": "8d6f8bad-e00f-405d-897f-45a8e5896770",
"customOrderId": "test 1",
"amountFrom": 200,
"amountTo": 100,
"currencyFrom": "ADA",
"currencyTo": "USD",
"status": "Pending",
"receivedAmount": null,
"executedAmountTo": 100,
"executedCurrencyTo": null,
"statusDescription": null,
"address": "EVnabLyYuXmINTMrRAsantpIyIHrSR0O1EC8Ugv0",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": null,
"sourceAddress": null,
"notificationType": "PaymentIntentNotification"
}
The first deposit of 100 ADA(=50 USD) is sent. As the first deposit amount is not equal to the amount requested(200 ADA=100 USD), which fails the initial payment intent, and doesn't satisfy the threshold, the automatic retry payment intent is initiated and fails.
{
"paymentIntentId": "8d6f8bad-e00f-405d-897f-45a8e5896770",
"retryPaymentIntentId": "f217d6b2-98d8-428a-bf21-fa2800aff282",
"customOrderId": "test 1",
"amountFrom": 100,
"amountTo": 50,
"currencyFrom": "ADA",
"currencyTo": "USD",
"status": "Failed",
"notificationType": "AutoRetryPaymentIntentNotification"
}
After the auto retry has failed, the initial payment intent is completed with "Manual action required" status, and the following notification is sent.
{
"paymentIntentId": "8d6f8bad-e00f-405d-897f-45a8e5896770",
"customOrderId": "test 1",
"amountFrom": 200,
"amountTo": 100,
"currencyFrom": "ADA",
"currencyTo": "USD",
"status": "ManualActionRequired",
"receivedAmount": 100,
"executedAmountTo": 100,
"executedCurrencyTo": null,
"statusDescription": "Invalid amount: Less than expected",
"address": "EVnabLyYuXmINTMrRAsantpIyIHrSR0O1EC8Ugv0",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": "x8e2veduhrlnc36n4mlddqkz5tnikb",
"sourceAddress": "lUROvAjmN2",
"notificationType": "PaymentIntentNotification"
}
The second deposit of 100 ADA(=50 USD) is sent for the same payment request.
As the sum of the first and second deposit (100 ADA+100 ADA=200 ADA=100 USD) satisfies the initial payment request of 100 USD, the automatic retry payment intent is initiated and completes successfully.
{
"paymentIntentId": "8d6f8bad-e00f-405d-897f-45a8e5896770",
"retryPaymentIntentId": "f217d6b2-98d8-428a-bf21-fa2800aff282",
"customOrderId": "test 1",
"amountFrom": 200,
"amountTo": 100,
"currencyFrom": "ADA",
"currencyTo": "USD",
"status": "Completed",
"notificationType": "AutoRetryPaymentIntentNotification"
}
After the auto retry is successfully completed, the initial payment intent is completed with "Partially completed" status, and the following notification is sent.
{
"paymentIntentId": "8d6f8bad-e00f-405d-897f-45a8e5896770",
"customOrderId": "test 1",
"amountFrom": 200,
"amountTo": 100,
"currencyFrom": "ADA",
"currencyTo": "USD",
"status": "PartiallyCompleted",
"receivedAmount": 200,
"executedAmountTo": 100,
"executedCurrencyTo": "USD",
"statusDescription": "Invalid amount: Less than expected",
"address": "EVnabLyYuXmINTMrRAsantpIyIHrSR0O1EC8Ugv0",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": "zo8n4xw52c7tuc903k2csbulx9mex9",
"sourceAddress": "lUROvAjmN2",
"notificationType": "PaymentIntentNotification"
}
Expected Result in case of a failed top-up flow
In this Sandbox flow we simulate the situation, where:
- The first deposit by the payment intent is less than the requested amount and doesn't satisfy the threshold.
- The second deposit by the payment intent adds more than the requested amount to the first deposit, so the deposits sum exceeds the requirements of the payment intent and the threshold.
ADA to USD exchange rate is assumed to be 2 to 1 in this example, so 200 ADA=100 USD.
In this case consecutive deposits won't change the "Manual action required" status of a payment intent, as the sum of deposits by the payment intent wil still exceed both the payment intent required amount and the threshold, and further manual action will be required:
Executing the flow via iframe
- Create payment intent for 100 USD.
- Choose coin ADA and network ADA_TEST.
Payment intent
Payment intent is a request for a deposit of a certain amount and currency on Crypto PayX customer's wallet. Crypto PayX customers can deposit crypto to their account and accept deposits from others via payment intents. Payment intents can be payed in a currency different from the currency customer wants to deposit on their account. In that case the deposit equvalent is requested and converted automatically.
There are two ways of creating and processing a payment intent:
- Via
iframe
generated for the particular payment intent. - Via API.
- Without the need of integration, by payment request link.
Payment intent fees
Each payment intent has a percentage-based and fixed processing fees. To know the exact amount of processing fees, please contact us.
If multiple deposits are made per payment intent, the sum of processing fees will be charged for each deposit.
If the amount sent by the payment intent is equal to or less than the processing fees sum, it will be spent on paying these fees, and no amount will be deposited per the payment intent.
If the payment intent amount is equal to or less than processing fees sum, its creation will not be possible, and an error will be returned in response.
Single payment intent address
By default, a separate crypto address is generated per each payment intent. In some cases, where this can be problematic, Crypto PayX can enable single payment intent address by customer request.
Single payment intent address flow allows Crypto PayX customers to use a single permanent crypto address for multiple payment intents per one Account ID.
If single address flow is enabled for the customer, Crypto PayX will recognise multiple deposits to the address and associate each of them with the appropriate payment intents by account ID.
Account ID needs to be passed as accountId
parameter when creating a payment intent using the following endpoints.
If Account ID will not be added when creating a payment intent request, single payment intent address flow will not be applied, regardless of single address settings for the customer. Please check your integration to ensure it complies with this requirement.
Payment intent statuses grid
Flow # | Payment intent condition | Threshold | Conversion settings | Old status (obsolete from 15.02.24) | Current status | Available manual actions | Сomment |
---|---|---|---|---|---|---|---|
Is initiated and awaits deposit | n/a | n/a | Pending | Pending | n/a | ||
Transaction is received and being processed | n/a | n/a | n/a | Processing | n/a | ||
1 | Received amount is equal to expected amount | Satisfied | n/a | Completed | Completed | n/a | |
2 | Received amount is more or less than expected amount | Satisfied | n/a | Partially completed | Partially completed | n/a | |
3 | Received amount is more or less than expected amount | Not satisfied | Conversion disabled for account or deposit currency | Partially completed | Manual action required | Refund, Accept recieved amount, Underpaid payment intent top-up | |
4 | Received amount more or less than expected amount | Not satisfied | Conversion enabled | Failed | Manual action required | Refund, Retry, Accept recieved amount, Underpaid payment intent top-up | |
5 | Received amount more or less than expected amount | 0% | Conversion disabled for account or deposit currency | Partially completed | Manual action required | Refund, Accept recieved amount, Underpaid payment intent top-up | |
6 | Received amount more or less than expected amount | 0% | Conversion disabled for account or deposit currency | Failed | Manual action required | Refund, Retry, Accept recieved amount, Underpaid payment intent top-up | |
7 | No funds were received within 30 seconds validity timeframe | n/a | n/a | Failed | Failed | n/a | If the deposit will be received after the time limit, and the deposit sum satisfies payment intent threshold requirements, payment intent status will change to Completed |
8.Refund | Deposit is greater than 0, payment intent is in "Manual action required" status | n/a | n/a | n/a | Manually completed with Refund | n/a | Payment intent ID status will be changed. |
9.Retry | Deposit is greater than 0, payment intent is in "Manual action required" status | n/a | Conversion enabled | n/a | Manually completed with Retry | n/a | Payment intent ID status will be changed. |
10.Accept recieved amount | Deposit is greater than 0, payment intent is in "Manual action required" status | n/a | n/a | n/a | Manually completed. Accepted received amount | n/a | Payment intent ID status will be changed. |
11.Underpaid payment intent top-up | Underpaid payment intent top-up, two separate deposits | Not satisfied after first deposit, satisfied after second deposit. | n/a | n/a | Partially completed | n/a | Functionality description,Top-up flow |
All of the possible payment intent flows, as well as the way to test them in Crypto Payx Sandbox, are described in more detail in Possible payment intent flows
Non-completed payment intent status descriptions
If the initial payment intent has not been completed, the reason for it is stated in the "statusDescription"
field of the payment intent notification.
Status name | Description |
---|---|
"Out of time" |
No deposit was made within the specified timeframe. |
"Out of money" |
Deposit was made during large fluctuations in deposit currency market price, making it impossible to complete it. |
"Invalid amount: Less than expected" |
Deposit amount is Less than expected and is lower than the payment intent threshold, if applicable. |
"Invalid amount: More than expected" |
Deposit amount is more than expected and is higher than the payment intent threshold, if applicable. |
"Server Error" |
Error on Crypto PayX side. Please contact us for further assistance. |
Payment intent via iframe
See Payment intent via iframe endpoints.
Payment intent via API
It is possible to create a payment intent using API.
Customers can request a quote for a specific pair and amount, and create a payment intent using the endpoints. In response to a successful payment intent creation, customers get a crypto deposit address.
Auto-retry and notifications functionality work as usual for payment intents created using API.
See API payment intent endpoints.
Payment request link
We now give customers the possibility to generate the link to Crypto PayX payment with all the requisites filled. This link can be distributed to customers clients, so that clients can pay in a streamlined manner, without the need to authorize on Crypto PayX.
Payment link will be active for 5(five) days after it has been generated.
To generate a payment link, customer needs to click on Create a payment link. Button can be accessed either to the left, below the account funds details, or in the right top corner of Crypto PayX tab.
After clicking the button, customers will see Payment request popup, where they can add the details of the payment they will request using the link.
Popup contains the following fields:
- Currency. Fiat currency of the deposit. Required.
- Amount. Amount of the deposit. Required.
- Payment reason. Those who open the link, will see the text written here. Required.
- Comment. Internal payment information. Those who receive the link will NOT see this text. Optional.
After entering the needed data, customers click Create a payment link button, which will generate the payment link with the provided details and copy to customers clipboard. Now customers can share the link to request a payment with the specified details. Payment link is active for 5(five) days after it has been generated. Those who receive the payment request link(requestees) and open it will see the payment request page.
On this page it is possible to choose the coin and network of the cryptocurrency that will be sent for this payment request.
After the requestee fills all the fields, they click Continue and go to the next page, where they see all the details, including active quote, wallet address and the amount they need to send to this address.
Requestee can see the status of their deposit on the payment request page in real time.
Customers can see statuses for the payment they requested in payment history grid on Crypto PayX tab.
in case of:
- Expired token.
- Expired payment link.
- Broken payment link.
- Payment link, that has been already used.
- Opened payment.Cryptopayx.tech page.
We will display "page not found" to Crypto PayX customers and payment link requestees.
Failed payment intent handling
In case of initial payment intent failure, and the deposit sum being greater than 0(zero), failed payment intent can be:
Retried automatically, if the deposit sum is within the payment intent threshold. See Payment intent threshold for details.
Retried manually with the new actual quote. See Payment intent manual retry for details.
Refunded manually either via API or Crypto PayX UI. See Refund failed payment intent for details.
Topped up with one or more deposits, until it satisfies the initial payment intent requirements. See Underpaid payment intent top-up for details.
Accept the received amount. See Flow 10.Accept recieved amount for details.
Payment intent threshold
By default, the amount of cryptocurrency deposited for the payment intent needs to be the equal to the request, to the decimals. If the deposited amount is not equal to the requested amount, payment intent status becomes failed, and further actions are needed to successfully complete it.
Threshold is a percentage of deviation from the requested fiat sum, which allows such payment intents to be processed automatically, minimizing manual handling from merchant's side. In case of a successful auto retry, no further action is required from them.
For example, if the threshold for the merchant is 2%, and fiat amount of the payment intent is 100 USD, deposits for this payment intent, equivalent to the range from 98 USD to 102 USD will be processed automatically, in case the deposit sum is not equal to the requested cryptocurrency amount and the initial payment intent is failed.
The new quote will be calculated for the automatic retry of the payment request, with the conversion rate valid at the time the automatic retry is initiated.
Payment intent manual retry
In case of payment intent retry, you need to first request for the actual quote of the retry, and if you agree with the quote, execute the retry payment intent by the date, given by the "quoteValidTo"
field in the quote request response.
See Retry OTC for Payment intent for the endpoints to retry failed initial payment intent.
Refund failed payment intent
To refund failed payment intent, you first request the currency of payment intent. Refunds can be made only in the currency in which the deposit for the payment intent was made. Then calculate fee for the refund and create a refund payment intent.
See Create crypto refund for the endpoints to refund failed initial payment intent.
It is also possible to initiate a refund with UI on Crypto PayX platform.
Underpaid payment intent top-up
It is possible to add funds to the existing payment intent in case the requested sum wasn’t deposited the first time.
One or more deposits after the initial underpaid deposit are possible per payment intent until it:
- Satisfies the payment intent’s threshold requirements.
- In case threshold is set to 0%, makes the sum of deposits equal to the initially requested amount.
Once the sum of deposits amount satisfies the requirements of payment intent it will be processed with autoretry, with the usual payment request flow.
Underpaid payment intent top-up is available both for Sandbox and real Crypto PayX account. See How to test top-up flow on Sandbox for more info.
Conversion rules for the payment intent
We are able to customize payment intent conversion rules individually. Please contact us to implement the specific configuration you need.
The following conversion settings are available:
- Disable conversion rules. In that case all deposits for the payment intent will not be converted and will stay in the cryptocurrency they were deposited in. See Disable conversion for payment intent for more info.
- Convert into a specific currency. In that case all deposits for the payment intent will be converted into the specified currency. The currency can be crypto or fiat.
- Convert into payment intent fiat currency. In that case all deposits for the payment intent will be converted into fiat currency, set during the creation of payment intent. Fiat currency can be EUR, USD or GBP.
You can also select the exceptions – one or more cryptocurrencies, deposits in which will not be converted, and will stay in the cryptocurrency they were deposited in.
Disable conversion for payment intent
In case there's no need to convert crypto funds, deposited for the payment intent, please contact us, and we disable the default conversion rules for your account.
In the case conversion is disabled, the payment intent flow will be as following:
- If a crypto deposit is equal to the requested sum, the status of payment intent will be changed to
"Completed"
. - If a crypto deposit is greater than 0(zero) differs from the requested sum the status of payment intent will be changed to
"PartiallyCompleted"
. - If no deposit was made within the specified timeframe, the status of payment intent will be changed to
"Failed"
.
Manual handling will be required only for cases where refund option is available.
Virtual fiat currencies
We have added a list of the following virtual fiat currencies:
- SAR (Saudi Arabian Riyal).
- AED (Arab Emirates Dirham).
- INR (Indian Rupee).
- EGP (Egyptian Pound).
- QAR (Quatari Riyal).
Adding these currencies gives merchant the possibility to give payment intent quote using them, e.g "in order to get the equivalent of AED 200, deposit X amount of ETH."
The following scenarios are available for the merchant:
- Exchange the deposited crypto to other configured currency (e.g. USD or USDT).
- Keep the deposited crypto without performing actual OTC exchange.
Contact us to setup the scenario that will optimally suit your needs.
Payment intent Endpoints
Payment intent via API endpoints
List all networks and coins available for payment intent
HTTP Request
[GET] v1/currencies
Successful Response
[
{
"fiatCurrency": "string",
"isVirtual": false,
"fiatCurrencyName": "string",
"coins": [
{
"coin": "string",
"name": "string",
"coinNetworks": [
{
"addressType": "Single",
"networkCode": "string",
"networkName": "string",
"order": 0
}
]
}
]
}
]
Response Fields
Name | Type | Description |
---|---|---|
fiatCurrency |
string |
Acronym of fiat currency. |
isVirtual |
boolean |
Is the currency listed a virtual fiat currency. true only for virtual fiat currencies. See Virtual fiat currencies for more info. |
fiatCurrencyName |
string |
Name of fiat currency. |
coin |
string |
Acronym of cryptocurrency. |
name |
string |
Name of cryptocurrency. |
addressType |
AddressType |
Type of address, based on crypto network. Can be: Single , Multiple , MultipleWithTag , MultipleWithMemo , MultipleWithNote . |
networkCode |
string |
Code of network. |
networkName |
string |
Name of network. |
Request a quote for the payment intent
HTTP Request
POST /v2/payment-intents/estimated-quote
Request Body Example
{
"currencyFrom": "string",
"amountTo": 0,
"currencyTo": "string"
}
Parameters
Name | Type | Required | Description |
---|---|---|---|
currencyFrom |
string |
+ | Acronym of the currency to convert FROM. |
amountTo |
number($decimal) |
+ | Amount of the currency to convert TO. |
currencyTo |
string |
+ | Acronym of the currency to convert TO. |
Successful Response
{
"currencyFrom": "string",
"amountFrom": 0,
"currencyTo": "string",
"amountTo": 0
}
Create a payment intent via API
HTTP Request
POST /v2/payment-intents/
Request Body Example
{
"currencyFrom": "string",
"currencyTo": "string",
"amountTo": 0,
"networkCode": "string",
"customOrderId": "string",
"accountId": "string",
"callbackUrl": "string"
}
Parameters
Name | Type | Required | Description |
---|---|---|---|
currencyFrom |
string |
+ | Acronym of the currency to convert FROM. |
amountTo |
number($decimal) |
+ | Amount of the currency to convert TO. |
currencyTo |
string |
+ | Acronym of the currency to convert TO. |
networkCode |
string |
Code of the network. | |
customOrderId |
string |
Unique internal order ID in customer's system. | |
accountId |
string |
Required for Single payment intent address. | Internal account ID in customer's system. |
callbackUrl |
string |
Callback URL to track status changes via notifications. |
Successful Response
{
"paymentIntentId": "f7d6bb02-b399-40ef-9127-676d4db21861"
"currencyFrom": "string",
"amountFrom": 0,
"currencyTo": "string",
"amountTo": 0,
"address": "string",
"additionalAddress": "string",
"additionalAddressType": "string",
"quoteValidTo": "2023-11-01T10:40:10.840Z",
"customOrderId":"string"
}
Response Fields
Name | Type | Description |
---|---|---|
paymentIntentId |
string($uuid) |
ID of the payment made by customer's client. |
currencyFrom |
string |
Acronym of the currency to convert FROM. |
amountFrom |
number($decimal) |
Amount of the currency to convert FROM. |
currencyTo |
string |
Acronym of the currency to convert TO. |
amountTo |
number($decimal) |
Amount of the currency to convert TO. |
address |
string |
Wallet address. |
additionalAddress |
string |
Additional wallet address. |
additionalAddressType |
string |
Additional address info of network, if applicable. Used for TAG , MEMO and NOTE of the network. |
quoteValidTo |
string |
Time, to which the payment intent quote is valid. |
customOrderId |
string |
Unique internal order ID in customer's system. |
Payment intent via iframe endpoints
Initiate a payment intent
Payment intent is initiated when customer requests exchange, selecting Crypto Pay as a PSP. Amount and Currency are passed as a parameters to the endpoint.
HTTP Request
POST /v1/payment-intents/
Request Body Example
{
"currency": "string",
"amount": 0,
"customOrderId": "string",
"accountId": "string",
"callbackUrl": "string"
}
Parameters
Name | Type | Required | Description |
---|---|---|---|
currency |
string |
+ | Acronym of currency. |
amount |
number(decimal) |
+ | Amount of currency. |
customOrderId |
string |
Unique internal order ID in customer's system. | |
accountId |
string |
Required for Single payment intent address. | Internal account ID in customer's system. |
callbackUrl |
string |
Callback URL to track status changes via notifications. |
Successful Response
URL to Crypto Pay iframe
for the specific client's payment. Format: https://payment.cryptopayx.tech/deposit?currencyTo=USD&amountTo=100&paymentIntentId=988a2d89-2655-4641-b368-72fe802f6731&merchantId={merchantId}&token={token}
.
Check payment intent status
Use this endpoint to check payment intent status by payment intent ID. Includes detailed info on failure reasons for the retry payment intent and custom conversion settings, if applicable for the account.
HTTP Request
GET v1/payment-intents/{paymentIntentId}
Parameters
Name | Type | Required | Description |
---|---|---|---|
paymentIntentId |
string($uuid) |
+ | ID of the payment intent made by customer's client. |
Successful Response
[
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"customOrderId": "string",
"accountId": "string",
"callbackUrl": "string",
"amountFrom": 0,
"amountTo": 0,
"currencyFrom": "string",
"currencyTo": "string",
"executedAmountTo": 0,
"executedCurrencyTo": "string",
"status": "string",
"receivedAmount": 0,
"statusDescription": "string",
"address": "string",
"networkCode": "string",
"additionalAddress": "string",
"originTransactionId": "string",
"transactionHash": "18d0f8fb499a571ae88ff257d43071648d0661bf4fbf0cda3cc8bf9c603aac72",
"sourceAddress": "string",
"processingFeeAmount": 0.98100000,
"processingFeeCurrency": "USD",
"retryPaymentIntents": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"type": "string",
"currencyFrom": "string",
"amountFrom": 0,
"currencyTo": "string",
"amountTo": 0,
"quoteValidTo": "2023-12-01T08:59:02.292Z",
"status": "string",
"failureReason": "string",
"address": "string",
"additionalAddress": "string",
"networkCode": "string",
"feeAmount": 0,
"externalTransactionId": "string"
}
],
"customConversion": {
"id": "string",
"currencyTo": "string",
"amountTo": 0,
"processingFeeAmount": 0,
"processingFeeCurrency": "string",
"status": "string",
"failureReason": "string"
}
}
Response Fields
Name | Type | Description |
---|---|---|
Id |
string($uuid) |
ID of the payment. |
customOrderId |
string |
Unique internal order ID in customer's system. |
accountId |
string |
Internal account ID in customer's system. |
callbackUrl |
string |
Callback URL to track status changes via notifications. |
amountFrom |
number($decimal) |
Amount of the currency to convert FROM. |
amountTo |
number($decimal) |
Amount of the currency to convert TO. |
currencyFrom |
string |
Acronym of the currency to convert FROM. |
currencyTo |
string |
Acronym of the currency to convert TO. |
executedAmountTo |
number($decimal) |
The actual amount customer gets with custom configuration and retry policy applied. |
executedCurrencyTo |
string |
The actual currency customer gets with custom configuration and retry policy applied. |
status |
string |
Status of payment at the moment of response. See Payment intent statuses for more info. |
receivedAmount |
number($decimal) |
Resulting amount received to the wallet address. |
statusDescription |
string |
The reason of payment failure, empty if the payment is not failed. See Failed payment intent statuses for more info. |
address |
string |
Wallet address. |
networkCode |
string |
Code of the network. |
additionalAddress |
string |
Additional address info of network, if applicable. Used for TAG , MEMO and NOTE of the network. |
originTransactionId |
string |
ID of a transaction within the internal system. Applied for internal transactions instead of transaction hash. |
transactionHash |
string |
Unique identifier of a transaction in a blockchain. |
sourceAddress |
string |
The address, from where the funds were withdrawn for the payment intent. |
processingFeeAmount |
number($decimal) |
Payment intent transaction processing fee amount. |
processingFeeCurrency |
string |
Payment intent transaction processing fee currency. |
Response Fields for "retryPaymentIntents"
Name | Type | Description |
---|---|---|
Id |
string($uuid) |
ID of the payment. |
currencyFrom |
string |
Acronym of the currency to convert FROM. |
amountFrom |
number($decimal) |
Amount of the currency to convert FROM. |
currencyTo |
string |
Acronym of the currency to convert TO. |
amountTo |
number($decimal) |
Amount of the currency to convert TO. |
quoteValidTo |
string |
Time, to which the retry payment intent quote is valid. |
status |
string |
Status of payment intent retry at the moment of response. See Retry payment intent statuses for more info. |
failureReason |
string |
The reason of payment intent retry failure, empty if the payment is not failed. Failed payment intent statuses for more info. |
address |
string |
Wallet address. |
additionalAddress |
string |
Additional address info of network, if applicable. Used for TAG , MEMO and NOTE of the network. |
networkCode |
string |
Code of the network. |
feeAmount |
number($decimal) |
Fee amount. |
externalTransactionId |
string($uuid) |
ID of the external transaction in PSP. |
Response Fields for "customConversion"
Name | Type | Description |
---|---|---|
Id |
string($uuid) |
ID of the custom conversion settings. |
currencyTo |
string |
Acronym of the currency to convert TO. |
amountTo |
number($decimal) |
Amount of the currency to convert TO. |
processingFeeAmount |
number($decimal) |
Fee amount. |
processingFeeCurrency |
string |
Fee amount. |
status |
string |
Status of conversion at the moment of response. |
failureReason |
string |
The reason of custom conversion failure. |
Search payment intent by Account ID, Custom Order ID
Use this endpoint to search and filter payment intents by:
- Payment intent ID.
- Custom Order ID –
CustomOrderId
. - Custom Account ID –
AccountId
. - Date timeframe.
If multiple parameters for filtering are selected, response will return only the items, which satisfy ALL the parameters.
Items in response are sorted by date, newer on top.
HTTP Request
POST v1/payment-intents/search
Request Body Example
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"customOrderId": "string",
"accountId": "string",
"createdDateFrom": "2024-02-23T12:50:24.833Z",
"createdDateTo": "2024-02-23T12:50:24.833Z",
"skip": 0,
"take": 0
}
Parameters
Name | Type | Required | Description |
---|---|---|---|
id |
string |
Exact ID of a payment intent. | |
customOrderId |
string |
Unique internal order ID in customer's system. | |
accountId |
string |
Internal account ID in customer's system. | |
createdDateFrom |
string(dateTtime) |
Start date the payment intent was initiated. | |
createdDateTo |
string(dateTtime) |
End date the payment intent was initiated. | |
skip |
int |
The number of items to skip in the response. If the value is 500 ,the response will return the items, starting from 501. |
|
take |
int |
The amount of items returned in response. Max value is 500 . |
Successful Response
[
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"createdOn": "2024-02-23T14:02:11.195Z",
"customOrderId": "string",
"amountFrom": 0,
"amountTo": 0,
"currencyFrom": "string",
"currencyTo": "string",
"status": "string",
"receivedAmount": 0,
"executedAmountTo": 0,
"executedCurrencyTo": "string",
"statusDescription": "string",
"address": "string",
"networkCode": "string",
"additionalAddress": "string",
"processingFeeAmount": 0,
"processingFeeCurrency": "string",
"originTransactionId": 0,
"transactionHash": "string",
"sourceAddress": "string",
"accountId": "string",
"callbackUrl": "string"
"retryPaymentIntents": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"createdOn": "2024-02-23T14:02:11.195Z",
"type": "string",
"amountFrom": 0,
"amountTo": 0,
"quoteValidTo": "2024-02-23T14:02:11.196Z",
"status": "string",
"failureReason": "string",
"address": "string",
"additionalAddress": "string",
"networkCode": "string",
"feeAmount": 0,
"externalTransactionId": "string"
}
],
"customConversion": {
"id": "string",
"currencyTo": "string",
"amountTo": 0,
"processingFeeAmount": 0,
"processingFeeCurrency": "string",
"status": "string",
"failureReason": "string"
}
}
Response Fields
Name | Type | Description |
---|---|---|
Id |
string($uuid) |
ID of the payment. |
customOrderId |
string |
Internal order ID in customer's system. |
accountId |
string |
Internal account ID in customer's system. |
callbackUrl |
string |
Callback URL to track status changes via notifications. |
amountFrom |
number($decimal) |
Amount of the currency to convert FROM. |
amountTo |
number($decimal) |
Amount of the currency to convert TO. |
currencyFrom |
string |
Acronym of the currency to convert FROM. |
currencyTo |
string |
Acronym of the currency to convert TO. |
executedAmountTo |
number($decimal) |
The actual amount customer gets with custom configuration and retry policy applied. |
executedCurrencyTo |
string |
The actual currency customer gets with custom configuration and retry policy applied. |
status |
string |
Status of payment at the moment of response. See Payment intent statuses for more info. |
receivedAmount |
number($decimal) |
Resulting amount received to the wallet address. |
statusDescription |
string |
The reason of payment failure, empty if the payment is not failed. See Failed payment intent statuses for more info. |
address |
string |
Wallet address. |
networkCode |
string |
Code of the network. |
additionalAddress |
string |
Additional address info of network, if applicable. Used for TAG , MEMO and NOTE of the network. |
originTransactionId |
string |
ID of a transaction within the internal system. Applied for internal transactions instead of transaction hash. |
transactionHash |
string |
Unique identifier of a transaction in a blockchain. |
sourceAddress |
string |
The address, from where the funds were withdrawn for the payment intent. |
processingFeeAmount |
number($decimal) |
Payment intent transaction processing fee amount. |
processingFeeCurrency |
string |
Payment intent transaction processing fee currency. |
Response Fields for "retryPaymentIntents"
Name | Type | Description |
---|---|---|
Id |
string($uuid) |
ID of the payment. |
currencyFrom |
string |
Acronym of the currency to convert FROM. |
amountTo |
number($decimal) |
Amount of the currency to convert TO. |
quoteValidTo |
string |
Time, to which the retry payment intent quote is valid. |
status |
string |
Status of payment intent retry at the moment of response. See Retry payment intent statuses for more info. |
failureReason |
string |
The reason of payment intent retry failure, empty if the payment is not failed. Failed payment intent statuses for more info. |
address |
string |
Wallet address. |
additionalAddress |
string |
Additional address info of network, if applicable. Used for TAG , MEMO and NOTE of the network. |
networkCode |
string |
Code of the network. |
feeAmount |
number($decimal) |
Fee amount. |
externalTransactionId |
string($uuid) |
ID of the external transaction in PSP. |
Response Fields for "customConversion"
Name | Type | Description |
---|---|---|
Id |
string($uuid) |
ID of the custom conversion settings. |
currencyTo |
string |
Acronym of the currency to convert TO. |
amountTo |
number($decimal) |
Amount of the currency to convert TO. |
processingFeeAmount |
number($decimal) |
Fee amount. |
processingFeeCurrency |
string |
Fee amount. |
status |
string |
Status of conversion at the moment of response. |
failureReason |
string |
The reason of custom conversion failure. |
Retry OTC for Payment intent
If the initial payment intent has "status" : "failed"
and "receivedAmount"
is greater than 0, Crypto Pay gives a possibility to retry it.
Use the endpoints below to request a current quote for the retry transaction and execute it.
Request quote for the retry transaction
Use this endpoint to request a current quote for the retry transaction by payment intent ID.
HTTP Request
[POST] /v1/payment-intents/{paymentIntentId}/retry/request-for-quote
Parameters
Name | Type | Required | Description |
---|---|---|---|
paymentIntentId |
string($uuid) |
+ | Unique ID of the payment intent made by customer. |
Successful Response
{
"currencyFrom": "BTC",
"currencyTo": "USD",
"amountFrom": 1.00,
"amountTo": 30000
}
Response Fields
Name | Type | Description |
---|---|---|
currencyFrom |
string |
Acronym of the currency to convert FROM. |
currencyTo |
string |
Acronym of the currency to convert TO. |
amountFrom |
number($decimal) |
Amount of the currency to convert FROM. |
amountTo |
number($decimal) |
Amount of the currency to convert TO. |
Execute the retry transaction
Use this endpoint to execute the retry transaction, if you agree with the current quote.
HTTP Request
[POST] /v1/payment-intents/{paymentIntentId}/retry
Parameters
Name | Type | Required | Description |
---|---|---|---|
paymentIntentId |
string($uuid) |
+ | Unique ID of the payment intent made by customer. |
Successful Response
200
if the transaction is executed successfully.
Refund failed payment intent
Available networks for the refund
Use this endpoint to list all the networks, available for the cryptocurrency of a particular payment intent.
HTTP Request
[GET] /v1/payment-intents/{paymentIntentId}/coin-networks
Parameters
Name | Type | Required | Description |
---|---|---|---|
paymentIntentId |
string($uuid) |
+ | ID of the payment intent made by customer. |
Successful Response
{
"coin" : "string",
"name" : "string",
"coinNetworks" :
[
{
"addressType": "AddressType",
"networkCode": "string",
"networkName": "string",
"order": 0
}
]
}
Response Fields
Name | Type | Description |
---|---|---|
coin |
string |
Acronym of cryptocurrency. |
name |
string |
Name of cryptocurrency. |
addressType |
AddressType |
Type of address, based on crypto network. Can be: Single , Multiple , MultipleWithTag , MultipleWithMemo , MultipleWithNote . |
networkCode |
string |
Code of network. |
networkName |
string |
Name of network. |
Calculate commission fee for the crypto refund
Use this endpoint to calculate fee for the refund transaction.
HTTP Request
[POST] /v1/payment-intents/{paymentIntentId}/crypto-refunds/fee
Request Body Example
{
"address" : "string",
"networkCode" : "string",
"additionalAddress" : "string"
}
Parameters
Name | Type | Required | Description |
---|---|---|---|
paymentIntentId |
string($uuid) |
+ | Unique ID of the payment intent made by customer. |
address |
string |
+ | Wallet address. |
networkCode |
string |
Code of the network. | |
additionalAddress |
string |
Additional address info of network, if applicable. Used for TAG , MEMO and NOTE of the network. |
Successful Response
{
"amount" : 98.00,
"feeAmount" : 2.00,
"totalAmount" : 100.00
}
Response Fields
Name | Type | Description |
---|---|---|
amount |
number($decimal) |
Amount that will be refunded, fee deducted. |
feeAmount |
number($decimal) |
Fee amount. |
totalAmount |
number($decimal) |
Total amount, with fee. |
Create crypto refund
HTTP Request
[POST] /v1/payment-intents/{paymentIntentId}/crypto-refunds
Request Body Example
{
"externalTransactionId" : "string"
}
Parameters
Name | Type | Required | Description |
---|---|---|---|
paymentIntentId |
string($uuid) |
+ | Unique ID of the payment intent made by customer. |
externalTransactionId |
string($uuid) |
Unique ID of the external transaction in PSP. |
Successful Response
{
"paymentIntentId": "771c6736-f0b6-4670-97fd-ad60f67e8c29",
"cryptoRefundPaymentIntentId": "5d2d5427-9ab9-4192-8ef7-8fa1f60b098f",
"customOrderId": "15847474-a84a-43b4-9fa6-d95cece2d6f1",
"amount": 0.06,
"currency": "ETH",
"destinationAddress": "0x08A7aeDcB87088dd8b311fD709B64e13FdAFac8a",
"destinationAdditionalAddress": "",
"networkCode": "ETH_GOERLI",
"status": "ProcessingRefund",
"externalTransactionId": "0x08A7aeDcB87088dd8b311fD709B64e13FdAFac8a"
}
Response Fields
Name | Type | Description |
---|---|---|
paymentIntentId |
string($uuid) |
ID of the payment intent the refund is issued for. |
cryptoRefundPaymentIntentId |
string($uuid) |
ID of the refund. |
customOrderId |
string |
Unique internal order ID in customer's system. |
amount |
number($decimal) |
Deposited amount. |
currency |
string |
Currency of the refund. |
destinationAddress |
string |
Wallet address where the refund will be sent. |
additionalAddress |
string |
Additional address info, if applicable. Used for TAG , MEMO and NOTE |
networkCode |
string |
Code of the network. |
status |
string |
Status of refund at the moment of response. Can be Pending , if the refund is initiated, ProcessingRefund ,Completed , Failed . |
externalTransactionId |
string($uuid) |
ID of the external transaction in PSP. |
Payout
Crypto Pay allows to withdraw fiat currency from customer's account by converting it to cryptocurrency of their choice and sending it to the wallet address they provide.
There are two ways of doing that:
- Via graphical user interface of the
iframe
generated for the particular payout. - Via API.
See Payout Endpoints.
After confirmation, the payout intent is set to "Pending". Once the fiat for the payout request is converted to crypto and the crypto withdrawal transaction is created, status is set to "Processing", "transactionid" is set to the unique ID of crypto transaction. After the transaction completion, status of payout intent is set to "Completed". In case of issues preventing to complete the payment intent, its status is set to "Failed".
Notifications are sent for each payout intent's status change.
Payout with iframe
If payout intent request is valid, new payout intent is initiated. The response will contain the URL to Withdrawal iframe
, with the payout intent's fiat currency and amount prefilled.
Following fields in Withdrawal iframe
need to be filled manually:
- Cryptocurrency to convert to.
- Crypto wallet address.
- Crypto network.
- Tag/memo of the network, if applicable.
Amount of the cryptocurrency after conversion, and the quote validity expiration time are shown in the iframe
.
After clicking "Continue", customers will be redirected to the confirmation step, where they can: - Double-check the information entered. - See the transaction fee. - See the amount of the cryptocurrency, which will be sent to the wallet address provided.
See Payout with iframe Endpoints.
Payout with API
It is possible to create and execute a payout only using API. In that case all the parameters of the payout need to be passed with the appropriate endpoints. It is also possible to access all networks and coins available for the payout, as well as calculate a fee for the particular payout.
See Payout with API Endpoints.
Payout Endpoints
Use the endpoints below to create a payout intent.
Payout with API endpoints
Use the endpoints below to create payout intent via API.
List all networks and coins available for payout
HTTP Request
[GET] v1/currencies
Successful Response
[
{
"fiatCurrency": "string",
"fiatCurrencyName": "string",
"coins": [
{
"coin": "string",
"name": "string",
"coinNetworks": [
{
"addressType": "Single",
"networkCode": "string",
"networkName": "string",
"order": 0
}
]
}
]
}
]
Response Fields
Name | Type | Description |
---|---|---|
fiatCurrency |
string |
Acronym of fiat currency. |
fiatCurrencyName |
string |
Name of fiat currency. |
coin |
string |
Acronym of cryptocurrency. |
name |
string |
Name of cryptocurrency. |
addressType |
AddressType |
Type of address, based on crypto network. Can be: Single , Multiple , MultipleWithTag , MultipleWithMemo , MultipleWithNote . |
networkCode |
string |
Code of network. |
networkName |
string |
Name of network. |
Calculate a fee for the payout
Use the endpoint below to estimate a fee for the particular payout, before creating a payout intent.
HTTP Request
[POST] v2/payout-intents/estimated-fee
Request Body Example
{
"currencyFrom": "string",
"amountFrom": 0,
"currencyTo": "string",
"networkCode": "string",
"address": "string",
"additionalAddress": "string"
}
Parameters
Name | Type | Required | Description |
---|---|---|---|
currencyFrom |
string |
+ | Acronym of the currency to convert FROM. |
amountFrom |
number($decimal) |
+ | Amount of the currency to convert FROM. |
currencyTo |
string |
+ | Acronym of the currency to convert TO. |
networkCode |
string |
+ | Code of the network. |
address |
string |
+ | Wallet address. |
additionalAddress |
string |
Additional address info of network, if applicable. Used for TAG , MEMO and NOTE of the network. |
Successful Response
{
"currencyFrom": "string",
"amountFrom": 0,
"currencyTo": "string",
"amountTo": 0,
"feeAmount": 0,
"feeCurrency": "string",
"receivedAmount": 0
}
Response Fields
Name | Type | Description |
---|---|---|
currencyFrom |
string |
Acronym of the currency to convert FROM. |
amountFrom |
number($decimal) |
Amount of the currency to convert FROM. |
currencyTo |
string |
Acronym of the currency to convert TO. |
amountTo |
number($decimal) |
Amount of the currency to convert TO. |
feeAmount |
number(decimal) |
Fee amount. |
feeCurrency |
string |
Acronym of currency for the fee. |
receivedAmount |
number($decimal) |
Resulting amount received to the wallet address. |
Create payout with API
Use the endpoint below to create a payout with preselected parameters.
HTTP Request
[POST] v2/payout-intents
Request Body Example
{ "currencyFrom": "string", "amountFrom": 0, "currencyTo": "string", "networkCode": "string", "address": "string", "additionalAddress": "string", "accountId": "string", "callbackUrl": "string" }
Parameters
Name | Type | Required | Description |
---|---|---|---|
currencyFrom |
string |
+ | Acronym of the currency to convert FROM. |
amountFrom |
number($decimal) |
+ | Amount of the currency to convert FROM. |
currencyTo |
string |
+ | Acronym of the currency to convert TO. |
networkCode |
string |
+ | Code of the network. |
address |
string |
+ | Wallet address. |
additionalAddress |
string |
Additional address info of network, if applicable. Used for TAG , MEMO and NOTE of the network. |
|
accountId |
string |
Internal account ID in customer's system. | |
callbackUrl |
string |
Callback URL to track status changes via notifications. |
Successful Response
{
"payoutIntentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"currencyFrom": "string",
"amountFrom": 0,
"currencyTo": "string",
"amountTo": 0,
"feeAmount": 0,
"feeCurrency": "string",
"receivedAmount": 0
}
Response Fields
Name | Type | Description |
---|---|---|
payoutIntentId |
string($uuid) |
ID of the payout. |
currencyFrom |
string |
Acronym of the currency to convert FROM. |
amountFrom |
number($decimal) |
Amount of the currency to convert FROM. |
currencyTo |
string |
Acronym of the currency to convert TO. |
amountTo |
number($decimal) |
Amount of the currency to convert TO. |
feeAmount |
number(decimal) |
Fee amount. |
feeCurrency |
string |
Acronym of currency for the fee. |
receivedAmount |
number($decimal) |
Resulting amount received to the wallet address. |
Payout with iframe endpoints
Use the endpoint below to create a payout intent with iframe
link generation.
HTTP Request
[POST] /v1/payout-intents/
Request Body Example
{
"currency": "string",
"amount": 0,
"customOrderId": "string",
"accountId": "string",
"callbackUrl": "string"
}
Parameters
Name | Type | Required | Description |
---|---|---|---|
currency |
string |
+ | Acronym of currency for payout. |
amount |
number(decimal) |
+ | Amount of currency for payout. |
customOrderId |
string |
Unique Internal order ID in customer's system. | |
accountId |
string |
Internal account ID in customer's system. | |
callbackUrl |
string |
Callback URL to track status changes via notifications. |
Successful Response
URL to Crypto Pay iframe
for the payout intent. Format: https://payment.cryptopayx.tech/payout?currencyTo=USD&amountTo=100&payoutIntentId=988a2d89-2655-4641-b368-72fe802f6731&merchantId={merchantId}&token={token}
.
csharp
$"{this.generalOptions.CurrentValue.CryptoPayUiExternalUrl}/payout?currencyFrom={request.Currency}&amountFrom={request.Amount}&token={token}"
Check Payout status
Use the endpoint below to check the status of payout.
HTTP Request
GET v1/payout-intents/{payoutIntentId}
Parameters
Name | Type | Required | Description |
---|---|---|---|
payoutIntentId |
string($uuid) |
+ | ID of the payout. |
Successful Response
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"transactionId": 0,
"customOrderId": "string",
"accountId": "string",
"amountFrom": 0,
"amountTo": 0,
"feeAmountTo": 0,
"currencyFrom": "string",
"currencyTo": "string",
"status": "string",
"address": "string",
"networkCode": "string",
"additionalAddress": "string",
"transactionHash": "string",
"statusDescription": "string"
}
Search payout by Account ID, Custom Order ID
Use this endpoint to search and filter payouts by:
- Payout ID.
- Custom Order ID –
CustomOrderId
. - Custom Account ID –
AccountId
. - Date timeframe.
If multiple parameters for filtering are selected, response will return only the items, which satisfy ALL the parameters.
Items in response are sorted by date, newer on top.
HTTP Request
POST v1/payout-intents/search
Request Body Example
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"customOrderId": "string",
"accountId": "string",
"createdDateFrom": "2024-02-23T12:50:24.833Z",
"createdDateTo": "2024-02-23T12:50:24.833Z",
"skip": 0,
"take": 0
}
Parameters
Name | Type | Required | Description |
---|---|---|---|
id |
string |
Exact ID of a payout intent. | |
customOrderId |
string |
Unique internal order ID in customer's system. | |
accountId |
string |
Internal account ID in customer's system. | |
createdDateFrom |
string(dateTtime) |
Start date the payout was initiated. | |
createdDateTo |
string(dateTtime) |
End date the payout was initiated. | |
skip |
int |
The number of items to skip in the response. If the value is 500 ,the response will return the items, starting from 501. |
|
take |
int |
The amount of items returned in response. Max value is 500 . |
Successful Response
[
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"transactionId": 0,
"customOrderId": "string",
"amountFrom": 0,
"amountTo": 0,
"feeAmountTo": 0,
"currencyFrom": "string",
"currencyTo": "string",
"status": "string",
"address": "string",
"networkCode": "string",
"additionalAddress": "string",
"transactionHash": "string",
"statusDescription": "string",
"accountId": "string"
}
]
Response Fields
Name | Type | Description |
---|---|---|
Id |
string($uuid) |
ID of the payout. |
transactionId |
string |
Crypto Payx ID of the transaction executed for the payout. |
customOrderId |
string |
Unique internal order ID in customer's system. |
amountFrom |
number($decimal) |
Amount of the currency to convert FROM. |
amountTo |
number($decimal) |
Amount of the currency to convert TO. |
feeAmountTo |
number($decimal) |
Fee amount deducted from FIAT after conversion. |
currencyFrom |
string |
Acronym of the currency to convert FROM. |
currencyTo |
string |
Acronym of the currency to convert TO. |
status |
string |
Status of payout at the moment of response. |
address |
string |
Wallet address. |
networkCode |
string |
Code of the network. |
additionalAddress |
string |
Additional address info of network, if applicable. Used for TAG , MEMO and NOTE of the network. |
transactionHash |
string |
Unique identifier of a transaction in a blockchain. |
statusDescription |
string |
The reason of payout failure, empty if the payment is not failed. |
accountId |
string |
Internal account ID in customer's system. |
Notifications
Crypto Pay notifies merchants about the status changes of payments, made by their clients. Notifications are sent to the callback URL, provided in the corresponding payment intent.
Notification signing message
Merchants need to be authorized to get access to the payload of notification.
var bodyHash = Convert.ToBase64String(sha256.ComputeHash(Encoding.UTF8.GetBytes(body)));
var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
var signatureString = $"{timestamp}{method}{callbackUrl}{bodyHash}";
Signature is generated by creating a SHA256 HMAC using the API secret on the string timestamp
+ method
+ pathWithQuery
+ contentHash
timestamp
- the same value asCRYPTO-PAY-API-TIMESTAMP
.method
- HTTP method in UPPER CASE.callbackUrl
- URL for notifications, provided by merchant.bodyHash
- base64 encoded SHA256 hash of notification content (empty forGET
requests).
Payment intent notifications
Notification payload contains the detailed info about the payment intent.
See the examples of notifications for all payment intent statuses. See Payment intent statuses grid for more info.
Processing payment intent notification
//Processing payment intent example
{
"expectedAmount": 16.71,
"paymentIntentId": "e71f4c41-472d-483e-b20e-2cfb0f1af6b8",
"customOrderId": "Order_151223-175400",
"amountFrom": 16.71,
"amountTo": 15,
"currencyFrom": "USDT",
"currencyTo": "EUR",
"executedAmountTo": null,
"executedCurrencyTo": null,
"status": "Processing",
"receivedAmount": null,
"statusDescription": null,
"address": "0x5290341182CAb5bf7555eD49d91afA9275b2De92",
"networkCode": "ERC20",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": null,
"sourceAddress": null,
"notificationType": "PaymentIntentNotification"
}
Pending payment intent notification
//Pending payment intent example
{
"paymentIntentId": "e71f4c41-472d-483e-b20e-2cfb0f1af6b8",
"customOrderId": "Order_151223-175400",
"amountFrom": 16.71,
"amountTo": 15,
"currencyFrom": "USDT",
"currencyTo": "EUR",
"executedAmountTo": null,
"executedCurrencyTo": null,
"status": "Pending",
"receivedAmount": null,
"statusDescription": null,
"address": "0x5290341182CAb5bf7555eD49d91afA9275b2De92",
"networkCode": "ERC20",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": null,
"sourceAddress": null,
"notificationType": "PaymentIntentNotification"
}
Completed payment intent notification
//Completed payment intent example
{
"paymentIntentId": "c8bd6c45-db94-4615-8735-97bb076ab617",
"customOrderId": "Order_151223-173434",
"amountFrom": 16.71,
"amountTo": 15,
"currencyFrom": "USDT",
"currencyTo": "EUR",
"executedAmountTo": 14.60,
"executedCurrencyTo": "EUR",
"status": "Completed",
"receivedAmount": 16.71,
"statusDescription": null,
"address": "0x9fd548c05F070337457d5c0FBC9DBFFD7D7E619f",
"networkCode": "ERC20",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": "18d0f8fb499a571ae88ff257d43071648d0661bf4fbf0cda3cc8bf9c603aac72",
"sourceAddress": null,
"notificationType": "PaymentIntentNotification"
}
Failed payment intent notification
See Failed payment intent statuses for more info.
//Failed payment intent example
{
"paymentIntentId": "66cd1a7a-3047-40b8-b928-3ae28911b321",
"customOrderId": "Order_170523-170028",
"amountFrom": 0.00061622,
"amountTo": 15,
"currencyFrom": "BTC",
"currencyTo": "EUR",
"executedAmountTo": 15,
"executedCurrencyTo": null,
"status": "Failed",
"receivedAmount": 0.000616,
"statusDescription": "Out of time",
"address": "tb1qhljsj8nmwjmzlscr0x9rq5fp59ksxvsl72wteq",
"networkCode": "BTC_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": "18d0f8fb499a571ae88ff257d43071648d0661bf4fbf0cda3cc8bf9c603aac72",
"sourceAddress": null,
"notificationType": "PaymentIntentNotification"
}
Auto retry payment intent notification
If the threshold is set up for the merchant, and failed initial payment intent deposit is within the threshold, auto retry payment intent is executed.
Initial payment intent status is set to "PartiallyCompleted"
if the auto retry for it is successful, and its status is set to "Completed"
.
See the example of notification for auto retry payment intent.
// Auto retry payment intent example
{
"paymentIntentId": "66cd1a7a-3047-40b8-b928-3ae28911b321",
"retryPaymentIntentId": "ef54010f-554c-4066-80b6-40fa21304dea",
"customOrderId": "Order_170523-170028",
"amountFrom": 0.000616,
"amountTo": 15.32,
"currencyFrom": "BTC",
"currencyTo": "EUR",
"status": "Completed",
"notificationType": "AutoRetryPaymentIntentNotification"
}
Partially completed payment intent notification
Initial payment intent status is set to "PartiallyCompleted"
, if the auto retry for it is successful, and its status is set to "Completed"
.
See the example of notification for partially completed payment intent.
// Partially completed payment intent example
{
"paymentIntentId": "9d09dff0-4a6b-4394-ac7f-1f063dbab5f7",
"customOrderId": "Order_261223-152725",
"amountFrom": 16.71,
"amountTo": 15,
"currencyFrom": "USDT",
"currencyTo": "EUR",
"status": "PartiallyCompleted",
"executedAmountTo": 14.60,
"executedCurrencyTo": "EUR",
"receivedAmount": 16.7,
"statusDescription": "Invalid amount: Less than expected",
"address": "0xFCC972B2E6B1312B1AA28bCdaf4a219285254764",
"networkCode": "BNB_TEST",
"additionalAddress": "",
"originTransactionId": null,
"transactionHash": "18d0f8fb499a571ae88ff257d43071648d0661bf4fbf0cda3cc8bf9c603aac72",
"sourceAddress": null,
"notificationType": "PaymentIntentNotification"
}
Manual retry payment intent notification
If the initial payment intent has "status" : "failed"
, its "recievedAmount"
is greater than 0, no threshold is set up for the merchant and retry transaction for it is executed, its "notificationType": "RetryPaymentIntentNotification"
.
See the example of notification for retry payment intent.
//Retry payment intent example
{
"paymentIntentId": "66cd1a7a-3047-40b8-b928-3ae28911b321",
"customOrderId": "Order_170523-170028",
"amountFrom": 0.000616,
"amountTo": 15.35,
"currencyFrom": "BTC",
"currencyTo": "EUR",
"quoteValidTo": "2023-05-18T12:41:36.5339709Z",
"status": "Pending",
"notificationType": "RetryPaymentIntentNotification"
}
Refund payment intent notification
Notification payload contains the detailed info about the refund for failed initial payment intent.
//Refund payment intent example
{
"paymentIntentId": "7d3d2e72-5aa4-42dd-9cd1-16fadf3220fc",
"cryptoRefundPaymentIntentId": "0c648b75-f314-4fa7-8d9d-9358c76ca0f9",
"customOrderId": "Order_230523-155734",
"amount": 0.00055,
"currency": "BTC",
"destinationAddress": "tb1qdu5wgl6zqx79mw7dq7gp9pygxs349gkwl59duj",
"destinationAdditionalAddress": null,
"networkCode": "BTC_TEST",
"status": "Completed",
"notificationType": "CryptoRefundPaymentIntentNotification"
}
Payout intent notifications
Pending payout intent notification
Notification payload contains the detailed info about the payout intent.
//Pending payout intent example
{
"payoutIntentId": "4e12da21-e9c2-48ac-8874-e26d3a59cf11",
"transactionId": 123412,
"customOrderld": "Order_110523-094305",
"amountFrom": 35,
"amountTo": 0.0012551,
"feeAmountTo": 0,
"currencyFrom": "USD",
"currencyTo": "BTC",
"status": "Pending",
"address": "tblq4yp7sceez346scrklfyhghhnnaj7gkzeyddhgt",
"networkCode": "BTCTEST",
"additionalAddress": null
}
Completed payout intent notification
In case of completed payout intent, the notification includes the transaction hash.
//Completed payout intent example
{
"payoutIntentId": "4e12da21-e9c2-48ac-8874-e26d3a59cf11",
"transactionId": 123412,
"customOrderld": "Order_110523-094305",
"amountFrom": 35,
"amountTo": 0.0012551,
"feeAmountTo": 0,
"currencyFrom": "USD",
"currencyTo": "BTC",
"status": "Сompleted",
"address": "tblq4yp7sceez346scrklfyhghhnnaj7gkzeyddhgt",
"transactionHash": "18d0f8fb499a571ae88ff257d43071648d0661bf4fbf0cda3cc8bf9c603aac72",
"networkCode": "BTCTEST",
"additionalAddress": null
}
Failed payout intent notification
See the example of the notification sent in case of failed payout intent.
"failureReason"
field can have the following values:
"Declined by backoffice"
"Not enough balance"
"Blockchain operation failed"
"Invalid address"
"Invalid tag"
"Rejected by AML screening"
//Failed withdrawal notification example
{
"transactionId":64086,
"customerId":170000,
"currency":"USDT",
"currencyType":"crypto",
"amount":100001.00000000,
"amountUsd":99727.99727,
"feeAmount":0.00010000,
"feeAmountUsd":0.00010,
"failureReason":"Not enough balance",
"producedOn":"2023-11-28T14:56:53.3285832Z"
}
Other notifications
Withdrawal via bank transfer notification
Notification payload contains the detailed info about the withdrawal via bank transfer.
//Processing withdrawal via bank transfer example
{
"id": "7c3af34f-7271-47e6-bdc5-ace979402c9f",
"fiatWithdrawalTransactionId": 1445,
"amount": 35,
"feeAmount": 2.35,
"currency": "USD",
"bankCountryCode": "UA",
"comment": null,
"status": "Processing",
"iban": "UA582124178898553591476647222",
"recipientName": "CryptoPay_recipient",
"paymentReason": "CryptoPay_reason",
"externalTransactionId": "EXT1686232925805",
"failureReason": null,
"createdOn": "2023-06-08T14:02:10.2607593Z",
"notificationType": "FiatTransactionNotification"
}
Merchant account management
Check Account Balance
Use this endpoint to check the balance on your accounts.
HTTP Request
[GET] /v1/accounts?type={type}
Type can be:
- fiat
to return only fiat accounts balances.
- crypto
to return only crypto accounts balances.
- none to return only crypto accounts balances.
Request Body Example
[
{
"name": "US Dollar",
"symbol": "USD",
"type": "Fiat",
"totalBalance": 788720.56,
"totalBalanceUsd": 786196.66,
"availableBalance": 788720.56,
"blockedAmount": 0
},
{
"name": "USD Coin",
"symbol": "USDC",
"type": "Crypto",
"totalBalance": 788720.5662889,
"totalBalanceUsd": 786196.66,
"availableBalance": 788720.5662889,
"availableWithdrawalBalance" : 0,
"availableWithdrawalBalanceUsd": 0,
"blockedAmount": 0
}
]
Response Fields
Name | Type | Description |
---|---|---|
name |
string |
Name of fiat or cryptocurrency. |
symbol |
string |
Acronym of fiat or cryptocurrency. |
type |
string |
Type of fiat or cryptocurrency. Can be Fiat and Crypto . |
totalBalance |
number($decimal) |
Total balance of the account. |
totalBalanceUsd |
number($decimal) |
USD equivalent of the account balance sum. |
availableBalance |
number($decimal) |
Available balance. |
availableWithdrawalBalance |
number($decimal) |
Balance available for withdrawal. Credit funds are deducted from the available balance. |
availableWithdrawalBalanceUsd |
number($decimal) |
Balance available for withdrawal equivalent in USD. |
blockedAmount |
string |
Is 1 in case the account is blocked, otherwise the account is active. |
Bank transfer
Crypto pay allows to withdraw fiat via bank transfer. To successfully execute the transfer, account balance needs to be at least the amount of withdrawal + fee. Notifications are sent for each status change of the withdrawal.
Use the endpoints below to withdraw fiat from account via bank transfer.
Calculate fee for the withdrawal
Use this endpoint to calculate fee and total amount for the withdrawal.
HTTP Request
[POST] v1/fiat-withdrawals/fee
Request Body Example
{
"amount": 100,
"currency": "USD",
"bankCountryCode":"BR"
}
Parameters
Name | Type | Required | Description |
---|---|---|---|
amount |
number(decimal) |
+ | Amount of currency for withdrawal. |
currency |
string |
+ | Acronym of currency for withdrawal. |
bankCountryCode |
string |
+ | Country two-letter code in ISO 3166-1 alpha-2 code format. |
Successful Response
{
"amount": 100,
"feeAmount": 3.5,
"totalAmount": 103.5
}
Response Fields
Name | Type | Description |
---|---|---|
amount |
number(decimal) |
Amount of withdrawal. |
feeAmount |
number(decimal) |
Fee amount. |
totalAmount |
number(decimal) |
Total amount, with fee. |
Create a fiat withdrawal via bank transfer
HTTP Request
[POST] v1/fiat-withdrawals/
Request Body Example
{
"amount": 100,
"feeAmount": 3.5,
"currency": "USD",
"iban": "UA1231231231234444",
"recipientName": "string",
"paymentReason": "string",
"externalTransactionId": "string",
"callbackUrl": "string",
"bankCountryCode": "BR"
}
Parameters
Name | Type | Required | Description |
---|---|---|---|
amount |
number(decimal) |
+ | Amount of currency for withdrawal. |
feeAmount |
number(decimal) |
+ | Fee amount. |
currency |
string |
+ | Acronym of currency for withdrawal. |
iban |
string |
+ | International bank account number of the recepient. |
recipientName |
string |
+ | Name of the recepient. |
paymentReason |
string |
+ | Payment reason. |
externalTransactionId |
string |
Unique ID of the external transaction in PSP. | |
callbackUrl |
string |
Callback URL to track status changes via notifications. | |
bankCountryCode |
string |
+ | Country two-letter code in ISO 3166-1 alpha-2 code format. |
Successful Response
{
"id": "51af711f-b041-44bd-90e0-82d2880cae0f",
"fiatWithdrawalTransactionId": 1610,
"amount": 35.0,
"feeAmount": 2.57,
"currency": "EUR",
"status": "Processing",
"iban": "UA582124178898553591476647222",
"bankCountryCode": "BR",
"recipientName": "CryptoPay_recipient",
"paymentReason": "CryptoPay_reason",
"externalTransactionId": "EXT1686319532841",
"createdOn": "2023-06-09T14:05:39.5388983Z"
}
Response Fields
Name | Type | Description |
---|---|---|
id |
string |
Unique ID of the withdrawal transaction. |
fiatWithdrawalTransactionId |
string |
Unique ID of the fiat withdrawal. |
amount |
number(decimal) |
Amount of currency for withdrawal. |
feeAmount |
number(decimal) |
Fee amount. |
currency |
string |
Acronym of currency for withdrawal. |
status |
string |
Status of the withdrawal. Can be Pending , Declined , Completed . |
iban |
string |
International bank account number of the recepient. |
bankCountryCode |
string |
Country two-letter code in ISO 3166-1 alpha-2 code format. |
recipientName |
string |
Name of the recepient. |
paymentReason |
string |
Payment reason. |
externalTransactionId |
string |
Unique ID of the external transaction in PSP. |
createdOn |
string |
Time the withdrawal was initiated. |
Crypto PayX Updates
Keep yourself up to date on new and updated Crypto PayX features. See Authentication for details.
(19/12/2024)
Support virtual fiat currency
It is now possible to configure any virtual fiat currency for pay in operations, in case real fiat currency is not supported by our liquidity providers. Using virtual fiat currency means that CryptoPayX merchant can offer any fiat currency to their customers, while actual conversion to this currency is not available. See Virtual fiat currencies for more info.
Request a new quote after expiration
If the quote for the payment intent is expired, customers of a CryptoPayX merchant will be able to request a new one. Request attempts are not limited and are available during 5(five) calendar days after the payment link is generated.
(9/12/2024)
API key management via Client Area
API keys can be generated and managed in your Client Areа Security settings.
(07/11/2024)
Payment intent Processing status and notification
We have added an additional Processing status for payment intent, which will make the process clearer and make it easier to diagnose possible issues.
This status is assigned to payment intent as soon as the deposit started being processed by Crypto PayX.
We also will sending a notification for this status, with the added expectedAmount
parameter, with the value representing the amount of funds which started processing, and will be received in case of a successful payment intent.
(14/03/2024)
Single payment intent address per Account ID
We added a single address flow that allows Crypto PayX customers to use single permanent address per one Account ID. This feature will be helpful for customers operating in specific regions, where using multiple addresses for deposits requires additional actions from the customer.
See Single payment intent address for more info.
(29/02/2024)
Add external customer Account ID for payment intent and payout
We added an additional AccountId
field, which will allow merchant to save external custom identifier to create payment intents and payouts with it and use it to search the transactions by this parameter.
Search transaction status by Custom Order ID and Account ID
We added two endpoints:
POST v1/payout-intents/search
POST v1/payment-intents/search
Using which customers can check the statuses for their payment intent and payout intents respectively.
It is possible to filter transactions by:
- Payment intent/Payout ID.
- Custom Order ID –
CustomOrderId
. - Customer Account ID –
AccountId
. - Date timeframe.
Underpaid payment intent top-up
We now make it possible adding funds to the existing payment intent in case the requested sum wasn’t deposited the first time.
See Underpaid payment intent top-up for more info.
(18/01/2024)
Source address, transaction hash in payment intent response and UI
We added the following parameters to notifications and payment intent status check response:
- Source address.
- Transaction hash.
- Processing fee amount.
- Processing fee currency.
- Executed amount.
This info is also added to the payment intent detail in transaction UI for desktop and mobile view.
Empty fields will be hidden from the view.
(04/01/2024)
Separate notification for partially completed payment intent
Previously, in case of the initial payment intent failure, we’ve changed its status to “PartiallyCompleted”, but didn’t send the automatic notification for that. Now, we’re sending Crypto PayX customers a separate notification in case the initial payment intent fails for some reason, with the field “failureReason” to understand why it has failed.
Processing fee field in payment intent status response
We’ve added processing fee amount and currency fields in response for payment intent status check via API, to clarify the amount Crypto PayX subtracted from the transaction amount.
"Not found" page
Now in case of: - Expired token. - Expired payment link. - Broken payment link. - Payment link, that has been already used. - Opened payment.Cryptopayx.tech page.
We will display customers and payment link requestees page not found in Crypto PayX GUI.
(21/12/2023)
Payment link available for all XBO customers
Overview
We give XBO customers, retail and corporate, the ability to request and use Payment link.
With this release, Get payment link button will be active for all customer types. (1.) Crypto PayX menu tab will be available for all customers on Webtrader. (2.)
Customers will request access on Request access popup. (3.)
How will it work?
In case the customer didn't have access to Crypto PayX, upon entering Crypto PayX tab they will see empty transactions grid, with Get payment link button active.
After clicking the button, they will see Payment request popup with the Request access button in the yellow section below, that they need to click to initiate the credential request.
Once customer clicks Request access button,they will be taken to a newpopup with the same name, with the information regarding Crypto PayX key features, and Proceed button they need to click to confirm the request.
After customer click Proceed, Crypto PayX credentials are created for their account on the background, their account gets marked as Merchant in our system, and button changes from Proceed to Done.
After that, customer can click on Done button, which will take them to the Request Payment popup, but with the full access to its functionality, including the ability to generate payment link for deposit requests.