Payout methods
Payout object
- id
string
The unique system identifier of a payout.
This value is generated automatically at the moment of payout creation and can’t be changed.
- amount
string
The payout amount, in the payment currency.
- address
string
The blockchain address of a receiver’s wallet.
- target_deposit
string or null
The identifier of a B2BinPay deposit, in the UUID4 format. The same as the payment page identifier.
- target_wallet
string or null
For payouts to client’s own wallets (such as payouts from Enterprise/Merchant wallets to Swap wallets and back): the identifier of a wallet to which the payout is made.
For other payouts, the value is
null
.- tracking_id
string
The identifier assigned to a payout for easier locating related payments in external systems.
This value is set when creating a payout and can be changed anytime.
- label
string
The tag or name assigned to a payout for easier locating it in the system.
This value is set when creating a payout and can be changed anytime.
- confirmations_needed
number
The number of confirmations needed to trigger an additional callback.
If this field is not
null
, two callbacks are sent: upon receiving the number of confirmations specified here and upon receiving the number of confirmations specified in the system settings. The corresponding transaction is assigned the Confirmed status as soon as the number of confirmations specified in this field received.- fee_amount
string
The blockchain fee charged for processing an on-chain transaction, in the payment currency.
- is_fee_included
boolean
If
true
, the fee is included in the payment amount, the remaining part is credited to the receiver’s account. Iffalse
, the fee is additionally debited from the wallet.The fee can’t be included in the amount for tokens and the following currencies:
ADA (Cardano)
ARB (Arbitrium)
AVAX (Avalanche)
BNB (BSC)
ETH
ETH-BASE
MATIC (Polygon)
OPT (Optimism)
TRX (Tron)
XLM (Stellar)
XMR (Monero)
XRP (Ripple)
- status
number
The current payout status. Possible values:
1
— Waiting for approval — for a payout created by a user with the Withdrawal with approval role: the payout was created and awaits the approval.2
— Approved — the payout was approved.3
— Cancelled — the payout was cancelled.
- rate_requested
string
If the payment currency differs from the wallet currency, the value is the exchange rate of the payment currency to the wallet currency; otherwise, the value is
1
.The exchange rates are updated every 30 seconds.
- callback_url
string
The URL for callback notifications on new payments.
- force_blockchain
boolean
Applicable for payouts from Merchant wallets only.
If the destination address of a payout also belongs to B2BinPay, such a transaction is off-chain. As a result, it doesn’t have a
txid
and can’t be found in block explorers. Set this value totrue
, to obtaintxid
.By default, the value is
false
.- exp
number
The payment currency precision, that is the number of digits after the decimal separator.
- tag_type
string or null
Applicable for payouts in XLM only.
The tag or memo type. Possible values:
0
— no memo1
— a 64-bit unsigned integer
- tag
string or null
For payouts in XRP or XLM: the destination tag.
For other payouts, the value is
null
.- destination
object
The payment address.
The object contains the following fields:
- address_type
string or null
For payments in BTC, LTC, BCH, XRP, the value is the address type. Refer to Address types for supported values.
For other payments, the value is
null
.- address
string
The payout destination address.
For payments in XRP, an array of objects is returned containing the
x-address
andaddress
(with a destinationtag
additionally specified):"destination": [ { "address_type": "x-address", "address": "X7dBkB9KmvUh6GGHbjhxdu4LfkwhJ74oVWbGRoy7VLnHdJ6" }, { "address_type": "address", "address": "rsxXXvBXmKUkCyCeNCHUFpfCX9pQdxQhv5", "tag": "0" } ]
For wallets denominated in XLM, the
destination
object is as follows:"destination": { "address_type": "address", "address": "GCZJFWB5NVQHVBMV4U6CCJIXXBGINGYF2W33PMD5REBD5VQ6H6BLCJR5", "tag_type": 0, "tag": "" }
where:
address_type
is always"address"
.address
is a string value containing the wallet address.tag_type
is a number value containing tag or memo type. Possible values:0
— no memo1
— a 64-bit unsigned integer
tag
is a string value containing the tag.
- address_type
- travel_rule_info
object
The information about a payment receiver.
The object fields are different for natural and legal persons, refer to Travel rule for more information and examples.
- currency
object
The payment currency.
The object contains the string
id
field matching the currency ISO code (refer to Currency codes for possible values).- wallet
object
The wallet from which the payout was made.
The object contains the string
id
field matching the wallet system identifier.
{
"type": "payout",
"id": "1815",
"attributes": {
"amount": "1.00000000",
"address": "bcrt1qs8vkvgj53tdzxaxzcxrwnvtp0ezse0vmrjty6u",
"target_deposit": "15987fbe-993e-45a8-93fa-cdd1a626488f",
"target_wallet": null,
"tracking_id": "",
"label": "",
"confirmations_needed": null,
"fee_amount": "0.00000000",
"is_fee_included": false,
"status": 2,
"rate_requested": "1.00000000",
"callback_url": "",
"force_blockchain": false,
"exp": 8,
"tag_type": null,
"tag": null,
"destination": {
"address_type": "bech32",
"address": "bcrt1qs8vkvgj53tdzxaxzcxrwnvtp0ezse0vmrjty6u"
},
"travel_rule_info": {
"beneficiary": {
"beneficiaryPersons": [
{
"naturalPerson": {
"name": [
{
"nameIdentifier": [
{
"primaryIdentifier": "John",
"secondaryIdentifier": "Smith"
}
]
}
],
"geographicAddress": [
{
"country": "Country",
"addressLine": [
"Address"
],
"addressType": "HOME"
}
]
}
}
]
}
}
},
"relationships": {
"currency": {
"data": {
"type": "currency",
"id": "1000"
}
},
"wallet": {
"data": {
"type": "wallet",
"id": "3614"
}
}
}
}
Get payout
Request
- id
string
The unique system identifier of a payout.
Filtering by object parameters can be applied according to the JSON API Specification.
GET[base]/payout/{id}
curl --request GET \
--url [base]/payout/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/vnd.api+json'
import requests
url = '[base]/payout/'
headers = {
'Authorization': 'Bearer <token>',
'Content-Type': 'application/vnd.api+json',
}
requests.get(url, headers=headers)
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$client = new GuzzleHttp\Client();
try {
$res = $client->get('[base]/payout/', [
'headers' => [
'Authorization' => 'Bearer <token>',
'Content-Type' => 'application/vnd.api+json',
],
]);
echo $res->getBody();
} catch (RequestException $e) {}
Response
In case of success, the response body contains a payout object or an array of objects (if id
was not specified).
Response codes
HTTP code |
Application code |
Description |
Suggested action |
---|---|---|---|
200 |
— |
The request succeeded. |
— |
400 |
5001: You can not view payout |
You don’t have permissions to view the payout. |
— |
401 |
2007: No active account found with the given credentials. |
Incorrect credentials. |
Send correct credentials. |
404 |
404: Not found |
The payout with the given |
Send a correct |
500 |
— |
Internal server error. |
Try again later. |
502 |
— |
Bad gateway. |
Try again later. |
503 |
— |
Service unavailable. |
Try again later. |
504 |
— |
Gateway timeout. |
Try again later. |
5xx |
— |
Other server errors. |
Try again later. |
Create payout
Before creating a payout, you can retrieve parameters of the fields you need to fill in by calling the Payout options method.
Note
For security reasons, an additional HTTP header with a unique idempotency key must be sent in the request.
The key is a UUID4 string with hyphens: for example, 2dbcb513-bd35-404f-9709-e34878def180
.
Refer to Useful links for recommended programming packages and libraries that you can use to generate UUID4.
Request
- label
string
The tag or name assigned to a payout for easier locating it in the system.
The maximum string length is 32 characters.
- amount
string
required The payout amount, in the payment currency.
The maximum string length is 36 characters.
- fee_amount
string
The blockchain fee to be charged for processing an on-chain transaction, in the payment currency.
The maximum string length is 36 characters.
To determine the fee value, call the Precalculate fee method.
- address
string
The payout destination address.
The maximum string length is 128 characters.
- tracking_id
string
The identifier assigned to a payout for easier locating related payments in external systems.
The maximum string length is 128 characters.
- confirmations_needed
number
The number of confirmations needed to trigger an additional callback, in the range from
0
to100
.Refer to Payout callback for more details.
- callback_url
string
The URL for callback notifications on new payments.
The maximum string length is 256 characters.
Refer to Payout callback for more details.
- travel_rule_info
object
required The information about a payment receiver.
The object fields are different for natural and legal persons, refer to Travel rule for more information and examples.
- currency
object
required The payment currency.
The object contains the string
id
field containing the currency ISO code (refer to Currency codes for possible values).- wallet
object
required The wallet from which the payout was made.
The object contains the string
id
field containing the wallet system identifier.
POST[base]/payout/
curl --request POST \
--url [base]/payout/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/vnd.api+json' \
--header 'idempotency-key: b6891f5b-d16f-4ba9-a1c4-9828be64a492' \
--data '{
"data": {
"type": "payout",
"attributes": {
"label": "My Payout",
"amount": "0.05",
"fee_amount": "0.00000550",
"address": "bcrt1q92k5z02dyrjahm4hput42nps3t7ryxzzz0vl76",
"tracking_id": "f12",
"confirmations_needed": 2,
"callback_url": "https://my.client.com/cb/",
"travel_rule_info": {
"beneficiary": {
"beneficiaryPersons": [
{
"naturalPerson": {
"name": [
{
"nameIdentifier": [
{
"primaryIdentifier": "John",
"secondaryIdentifier": "Smith"
}
]
}
],
"geographicAddress": [
{
"country": "Country",
"addressLine": [
"Address"
],
"addressType": "HOME"
}
]
}
}
]
}
}
},
"relationships": {
"wallet": {
"data": {
"type": "wallet",
"id": "1"
}
},
"currency": {
"data": {
"type": "currency",
"id": "1000"
}
}
}
}
}'
import requests
import json
url = "[base]/payout/"
payload = json.dumps({
"data": {
"type": "payout",
"attributes": {
"label": "My Payout",
"amount": "0.05",
"fee_amount": "0.00000550",
"address": "bcrt1q92k5z02dyrjahm4hput42nps3t7ryxzzz0vl76",
"tracking_id": "f12",
"confirmations_needed": 2,
"callback_url": "https://my.client.com/cb/",
"travel_rule_info": {
"beneficiary": {
"beneficiaryPersons": [
{
"naturalPerson": {
"name": [
{
"nameIdentifier": [
{
"primaryIdentifier": "John",
"secondaryIdentifier": "Smith"
}
]
}
],
"geographicAddress": [
{
"country": "Country",
"addressLine": [
"Address"
],
"addressType": "HOME"
}
]
}
}
]
}
}
},
"relationships": {
"wallet": {
"data": {
"type": "wallet",
"id": "1"
}
},
"currency": {
"data": {
"type": "currency",
"id": "1000"
}
}
}
}
})
headers = {
'Content-Type': 'application/vnd.api+json',
'Authorization': 'Bearer <token>'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
<?php
$client = new Client();
$headers = [
'Content-Type' => 'application/vnd.api+json',
'Authorization' => 'Bearer <token>'
];
$body = '{
"data": {
"type": "payout",
"attributes": {
"label": "My Payout",
"amount": "0.05",
"fee_amount": "0.00000550",
"address": "bcrt1q92k5z02dyrjahm4hput42nps3t7ryxzzz0vl76",
"tracking_id": "f12",
"confirmations_needed": 2,
"callback_url": "https://my.client.com/cb/",
"travel_rule_info": {
"beneficiary": {
"beneficiaryPersons": [
{
"naturalPerson": {
"name": [
{
"nameIdentifier": [
{
"primaryIdentifier": "John",
"secondaryIdentifier": "Smith"
}
]
}
],
"geographicAddress": [
{
"country": "Country",
"addressLine": [
"Address"
],
"addressType": "HOME"
}
]
}
}
]
}
}
},
"relationships": {
"wallet": {
"data": {
"type": "wallet",
"id": "1"
}
},
"currency": {
"data": {
"type": "currency",
"id": "1000"
}
}
}
}
}';
$request = new Request('POST', '[base]/payout/', $headers, $body);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
Response
In case of success, the response body contains a newly created payout object.
Response codes
HTTP code |
Application code |
Description |
Suggested action |
---|---|---|---|
201 |
— |
The request succeeded. |
— |
400 |
1007 |
An invalid value was specified for a field. |
Send valid values. |
400 |
3008 |
The wallet is inactive or is being registered in the system. |
Activate the wallet or wait until the process of wallet registration in the system is finished and try again. |
400 |
3021 |
A wallet activation transfer is required. |
Make a transfer to activate the wallet. |
400 |
3022 |
An invalid wallet type. |
Make sure you specify either Enterprise, or Merchant, or Swap wallet. |
400 |
4002 |
A payout can’t be made from the specified wallet. |
Make sure you have the permission to make payouts from the wallet you have specified. |
400 |
4007 |
The funds are sent to the wallet from which the payout is being made. |
The funds can’t be sent to the wallet from which the payout is being made. Such transactions are allowed for the following blockchains: BTC, BCH, BSC, ADA, DASH, DOGE, ETH, LTC, OMNI, TRX, ZCASH. |
400 |
4008 |
Insufficient funds. |
Top up the wallet or decrease the payout amount. |
400 |
4009 |
The specified blockchain fee is either too high or too low. |
Correct the fee value. Refer to Precalculate fee. |
400 |
4010 |
The blockchain fee can’t be applied to tokens. |
Exclude the fee value from the payout body. |
400 |
4011 |
A payout amount can’t be zero or negative. |
Make sure that the payout amount is greater than zero. |
400 |
4012 |
The specified |
Specify a unique |
400 |
4013 |
The payout amount is less than the Minimal transfer amount. |
Specify the payout amount that is greater than or equal to the minimal transfer amount. |
400 |
4016 |
The blockchain fee can’t be applied to the selected currency. |
Set the |
400 |
4019 |
The blockchain fee amount exceeds the amount of the payout with the included fee. |
Increase the payout amount or decrease the fee value. |
400 |
6002 |
The selected currency is disabled. |
Select an active currency. |
400 |
6015 |
The currency is unavailable for all clients or for a specific client. |
Select an available currency. |
400 |
6017 |
A user is trying to make a transaction with a custom token that wasn’t paid for. |
Make a payment for a custom token and proceed with the transaction. |
400 |
7001 |
An incorrect payment address is specified or the address isn’t whitelisted. |
Specify a correct payment address and proceed with the payment. |
400 |
— |
Invalid data (serializer errors). |
Send valid data. |
401 |
2007 |
No active account with the given credentials is found. |
Send correct credentials or update access tokens. |
403 |
3019 |
Payouts are blocked for the selected wallet. |
Contact the account manager or technical support. |
409 |
1004 |
A request with the specified idempotency key has already been submitted. |
Specify another idempotency key for the request. |
428 |
1003 |
The idempotency key header is not specified. |
Specify the idempotency key header in the request header. |
429 |
— |
The request was throttled. |
Try again later. |
500 |
500 |
Internal server error. |
Try again later. |
500 |
— |
A node-related error. |
Try again later. |
502 |
— |
Bad gateway. |
Try again later. |
503 |
4018 |
Fee calculation or payout creation for the selected currency is temporarily unavailable. |
Change the currency or try again later. |
503 |
— |
Service unavailable. |
Try again later. |
504 |
— |
Gateway timeout. |
Try again later. |
5xx |
— |
Other server errors. |
Try again later. |
Travel rule
The travel_rule_info
object contains information about a payment receiver and must be filled in when creating a payout.
The object fields are different for natural and legal persons.
Natural person
"travel_rule_info": {
"beneficiary": {
"beneficiaryPersons": [
{
"naturalPerson": {
"name": [
{
"nameIdentifier": [
{
"primaryIdentifier": "First Name",
"secondaryIdentifier": "Last Name"
}
]
}
],
"geographicAddress": [
{
"country": "Country",
"addressLine": [
"Address"
],
"addressType": "HOME"
}
]
}
}
]
}
}
The object contains the following key fields:
- primaryIdentifier
string
required The family name, maiden name or married name, main name, surname, or, in some cases, the entire name when the natural person’s name can’t be divided into two parts, or when the sender is unable to divide the natural person’s name into two parts.
- secondaryIdentifier
string
required The forename, familiar name, given name, initials, prefixes, suffixes, Roman numerals (if legally part of the name), or any other secondary names.
- country
string
The ISO-3166-1 alpha-2 code or the value XX.
- addressLine
string
required Information that locates and identifies a specific address, as defined by postal services, presented in free format text.
- addressType
string
required The nature of the address. Possible values:
HOME
— Residential — the address is the home address.BIZZ
— Business — the address is the business address.GEOG
— Geographic — the address is the unspecified physical (geographical) address suitable for identification of the natural or legal person.
Legal person
"travel_rule_info": {
"beneficiary": {
"beneficiaryPersons": [
{
"legalPerson": {
"name": {
"nameIdentifier": [
{
"legalPersonName": "Name",
"legalPersonNameIdentifierType": "LEGL"
}
]
},
"geographicAddress": [
{
"country": "Country",
"addressLine": [
"Address"
],
"addressType": "BIZZ"
}
]
}
}
]
}
}
The object contains the following key fields:
- legalPersonName
string
required The name of a legal person.
- legalPersonNameIdentifierType
string
required The nature of name being specified for the legal person. Possible values:
LEGL
— Legal name — the official name under which an organization is registered.SHRT
— Short name — the short name of an organization.TRAD
— Trading name — the name used by a business for business purposes, although its registered legal name used for contracts and other formal situations may be different.
- country
string
The ISO-3166-1 alpha-2 code or the value XX.
- addressLine
string
required Information that locates and identifies a specific address, as defined by postal services, presented in free format text.
- addressType
string
required The nature of the address. Possible values:
HOME
— Residential — the address is the home address.BIZZ
— Business — the address is the business address.GEOG
— Geographic — the address is the unspecified physical (geographical) address suitable for identification of the natural or legal person.
Precalculate fee
Use this method to precalculate possible blockchain fee options.
For calculations, you need to provide the identifier of a wallet from which the payout is made along with the destination address and payout amount.
Request
- amount
string
required The payout amount, in the payment currency.
- to_address
string
required The payout destination address.
- wallet
object
required The unique system identifier of a wallet from which the payout is made.
- currency
object
The payout currency.
POST[base]/payout/calculate/
curl --request POST \
--url /payout/calculate/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/vnd.api+json' \
--data '{
"data": {
"type": "payout-calculation",
"attributes": {
"amount": "0.0000001",
"to_address": "2N3Ac2cZzRVoqfJGu1bFaAebq3izTgr1WLv"
},
"relationships": {
"wallet": {
"data": {
"type": "wallet",
"id": "13"
}
},
"currency": {
"data": {
"type": "currency",
"id": "1000"
}
}
}
}
}'
import requests
url = '[base]/payout/calculate/'
headers = {
'Authorization': 'Bearer <token>',
'Content-Type': 'application/vnd.api+json',
}
data = {
'data': {
'type': 'payout-calculation',
'attributes': {
'amount': '0.0000001',
'to_address': '2N3Ac2cZzRVoqfJGu1bFaAebq3izTgr1WLv',
},
'relationships': {
'wallet': {
'data': {
'type': 'wallet',
'id': '13',
}
},
'currency': {
'data': {
'type': 'currency',
'id': '1000',
},
},
},
},
}
requests.post(url, headers=headers, json=data)
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$client = new GuzzleHttp\Client();
try {
$res = $client->post('[base]/payout/calculate/', [
'json' => [
'data' => [
'type' => 'payout-calculation',
'attributes' => [
'amount' => '0.05',
'to_address' => 'bcrt1q92k5z02dyrjahm4hput42nps3t7ryxzzz0vl76',
],
'relationships' => [
'wallet' => [
'data' => [
'type' => 'wallet',
'id' => '1',
],
],
'currency' => [
'data' => [
'type' => 'currency',
'id' => '1000',
],
],
],
],
],
'headers' => [
'Authorization' => 'Bearer <token>',
'Content-Type' => 'application/vnd.api+json',
],
]);
echo $res->getBody();
} catch (RequestException $e) {}
Response
In case of success, the response body contains low, medium, and high blockchain fee values.
- is_internal
boolean
If
true
, the payout is made to the B2BinPay address.- fee.low
string
The low mode fee amount.
- fee.medium
string
The medium mode fee amount.
- fee.high
string
The high mode fee amount.
- dust_amount
string
The payout-related dust.
- warning
number or null
The blockchain-related warning. Possible values:
1
— the large withdrawal fee.2
— the payout may fail due to low finalizing balance or too low change amount.3
— the final balance may be less than minimal fee and can’t be withdrawn. Applicable for the Ethereum blockchain.
- fee.currency
number
The blockchain fee currency.
- commission.amount
object
The commission amount.
- commission.currency
number
The commission currency.
{
"data": {
"type": "payout-calculation",
"id": "0",
"attributes": {
"is_internal": true,
"fee": {
"low": "0.0001000",
"medium": "0.0001000",
"high": "0.1073686",
"dust_amount": "0.0000000",
"warning": null,
"currency": 1021
},
"commission": {
"amount": "0.0000000",
"currency": 1021
}
}
}
}
Response codes
HTTP code |
Application code |
Description |
Suggested action |
---|---|---|---|
200 |
— |
The request succeeded. |
— |
400 |
1006 |
Missing field {field_name}. |
Add the missing field to the request body. |
400 |
1007 |
An invalid value was specified for a field. |
Send valid values. |
400 |
3008 |
The wallet is inactive. |
Activate the wallet or choose another one. |
400 |
3021 |
A wallet activation transfer is required. |
Make a transfer to activate the wallet. |
400 |
4007 |
The funds are sent to the wallet from which the payout is being made. |
The funds can’t be sent to the same wallet from which the payout is being made. |
400 |
4008 |
Insufficient funds. |
Top up the wallet or decrease the payout amount. |
400 |
6002 |
The selected currency is disabled. |
Select an active currency. |
400 |
7001 |
An incorrect payment address is specified. |
Specify a correct payment address and proceed with the payment. |
401 |
— |
No active account with the given credentials is found. |
Send correct credentials or update access tokens. |
403 |
403 |
Permission denied. |
Make sure that:
|
500 |
500 |
Internal server error. |
Try again later. |
502 |
— |
Bad gateway. |
Try again later. |
503 (old 400) |
4018 |
Fee calculation or payout creation for the selected currency is temporarily unavailable. |
Change the currency or try again later. |
503 |
— |
Service unavailable. |
Try again later. |
504 |
— |
Gateway timeout. |
Try again later. |
5xx |
— |
Other server errors. |
Try again later. |
Payout callback
A callback is a notification sent to a user’s callback URL when a new payout-related transaction occurs in the blockchain. You can use the callback to make changes in your system.
Default callback
By default, the callback is sent after the transaction is confirmed.
To get confirmed, a transaction should receive a necessary number of confirmation blocks and pass the AML verification.
The required number of confirmations is determined by the confirmation_blocks
field in the Currency object.
For example, the confirmation_blocks
field is set to 3
.
This means that the callback will be sent after receiving three confirmations and passing the AML check.
Additional callback
It’s possible to trigger an additional callback.
To do this, specify a new number in the confirmations_needed
field when calling the Create payout method.
For example, the confirmation_blocks
value is set to 3
and the confirmations_needed
value is set to 1
.
In this case, two callbacks will be sent: one (additional) after a transaction receives one confirmation and another one (default) after a transaction receives three confirmations.
Callback processing
Upon receiving a required number of confirmations related to a new transaction, the callback is sent to your server if the payout request body includes a valid callback URL.
The callback is sent by a POST
-request, which contains useful JSON payload.
To verify that the callback was sent by B2BinPay, generate an HMAC-signature using sha256
as algorithm: sha256
hash of the concatenation of your login and password as a key, and the concatenation of the transfer.status
, transfer.amount
, payout.tracking_id
, meta.time
fields as message.
Refer to the example below for a callback verification example.
<?php
# set API user login and password
$login = 'Your API key';
$password = 'Your API secret';
# parse callback data
$callback_payload = json_decode (
'{
"data": {
"type": "payout",
"id": "26",
"attributes": {
"address": "2NBr9k5xhvE2PxAAiFuczqQkeN76ShMdRZ6",
"created_at": "2021-09-30T13:01:49.930612Z",
"tracking_id": "12",
"fee_amount": "0.00000823",
"is_fee_included": false,
"amount": "0.00010000",
"destination": {
"address_type": "legacy",
"address": "2NBr9k5xhvE2PxAAiFuczqQkeN76ShMdRZ6"
}
},
"relationships": {
"wallet": {
"data": {
"type": "wallet",
"id": "19"
}
},
"currency": {
"data": {
"type": "currency",
"id": "1000"
}
},
"transfer": {
"data": {
"type": "transfer",
"id": "145"
}
}
}
},
"included": [
{
"type": "currency",
"id": "1000",
"attributes": {
"iso": 1000,
"name": "Bitcoin",
"alpha": "BTC",
"alias": null,
"exp": 8,
"confirmation_blocks": 3,
"minimal_transfer_amount": "0.00000546",
"block_delay": 3600
}
},
{
"type": "transfer",
"id": "145",
"attributes": {
"confirmations": 3,
"risk": 0,
"risk_status": 4,
"op_id": 26,
"op_type": 2,
"amount": "0.00010000",
"commission": "0.00000000",
"fee": "0.00000823",
"txid": "c3cc36f4569fdbfaacdbc14647e5046d9f239ab1af0268b531a5a213411a8fc9",
"status": 2,
"message": null,
"user_message": null,
"created_at": "2021-09-30T13:01:50.273446Z",
"updated_at": "2021-09-30T13:02:33.743770Z"
},
"relationships": {
"currency": {
"data": {
"type": "currency",
"id": "1000"
}
}
}
}
],
"meta": {
"time": "2021-09-30T13:02:34.059939+00:00",
"sign": "8ef2a0f0c6826895593d0d137cf6ce7353a4bbe999d4a6c363f92f1e9d7f8e32"
}
}',
true
);
$callback_sign = $callback_payload['meta']['sign'];
$callback_time = $callback_payload['meta']['time'];
# retrieve transfer and payout attributes
$included_transfer = array_filter(
$callback_payload['included'],
function ($item) {
return $item['type'] === 'transfer';
}
);
$included_transfer = array_pop($included_transfer)['attributes'];
$payout = $callback_payload['data']['attributes'];
$status = $included_transfer['status'];
$amount = $included_transfer['amount'];
$tracking_id = $payout['tracking_id'];
# prepare data for hash check
$message = $status . $amount . $tracking_id . $callback_time;
$hash_secret = hash('sha256', $login . $password, true);
$hash_hmac_result = hash_hmac('sha256', $message, $hash_secret);
# print result
if ($hash_hmac_result === $callback_sign) {
echo 'Verified';
} else {
echo 'Invalid sign';
}
echo PHP_EOL;
After processing the payload, you should send back the HTTP 200
response code without a body.
If your server is temporarily unavailable or the status of the response is different from 200
, the system will resend the callback several times with the increasing delay time.
The number of re-sendings is limited.
If the manual resending is required, you can do it on the Wallet management > Events page in the Web UI.
Callback structure
The callback consists of three parts:
data
— the payout itself. Contains the Payout object API.included
— the transaction received for this payout. Contains the Currency object and Transfer object.meta
— the metadata used for callback authentication. Contains the following fields:time
(string) — the date and time when the callback was sent.sign
(string) — the HMAC signature for a callback authentication. Refer to the Callback processing section for a callback verification example.
{
"data": {
"type": "payout",
"id": "26",
"attributes": {
"address": "2NBr9k5xhvE2PxAAiFuczqQkeN76ShMdRZ6",
"created_at": "2021-09-30T13:01:49.930612Z",
"tracking_id": "12",
"fee_amount": "0.00000823",
"is_fee_included": false,
"amount": "0.00010000",
"destination": {
"address_type": "legacy",
"address": "2NBr9k5xhvE2PxAAiFuczqQkeN76ShMdRZ6"
}
},
"relationships": {
"wallet": {
"data": {
"type": "wallet",
"id": "19"
}
},
"currency": {
"data": {
"type": "currency",
"id": "1000"
}
},
"transfer": {
"data": {
"type": "transfer",
"id": "145"
}
}
}
},
"included": [
{
"type": "currency",
"id": "1000",
"attributes": {
"iso": 1000,
"name": "Bitcoin",
"alpha": "BTC",
"alias": null,
"exp": 8,
"confirmation_blocks": 3,
"minimal_transfer_amount": "0.00000546",
"block_delay": 3600
}
},
{
"type": "transfer",
"id": "145",
"attributes": {
"confirmations": 3,
"risk": 0,
"risk_status": 4,
"op_id": 26,
"op_type": 2,
"amount": "0.00010000",
"commission": "0.00000000",
"fee": "0.00000823",
"txid": "c3cc36f4569fdbfaacdbc14647e5046d9f239ab1af0268b531a5a213411a8fc9",
"status": 2,
"message": null,
"user_message": null,
"created_at": "2021-09-30T13:01:50.273446Z",
"updated_at": "2021-09-30T13:02:33.743770Z"
},
"relationships": {
"currency": {
"data": {
"type": "currency",
"id": "1000"
}
}
}
}
],
"meta": {
"time": "2021-09-30T13:02:34.059939+00:00",
"sign": "8ef2a0f0c6826895593d0d137cf6ce7353a4bbe999d4a6c363f92f1e9d7f8e32"
}
}
Payout options
Request
No request parameters.
OPT[base]/payout
curl --request OPTIONS \
--url [base]/payout/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/vnd.api+json' \
import requests
import json
url = '[base]/payout/'
headers = {
'Content-Type': 'application/vnd.api+json',
'Authorization': 'Bearer <token>'
}
response = requests.request('OPTIONS', url, headers=headers)
print(response.text)
<?php
$client = new Client();
$headers = [
'Content-Type' => 'application/vnd.api+json',
'Authorization' => 'Bearer <token>'
];
$request = new Request('OPTIONS', '[base]/payout/', $headers, $body);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
Response
In case of success, the response body contains an array of available methods along with a list of field parameters such as labels, min and max values, regular expressions used for validation, and so on.
Response codes
201 Success.
500 The request wasn’t completed due to an internal error on the server side.
{
"data": {
"renders": [
"application/vnd.api+json"
],
"parses": [
"application/vnd.api+json",
"multipart/form-data"
],
"allowed_methods": [
"GET",
"POST",
"HEAD",
"OPTIONS"
],
"actions": {
"GET": {
"currency": {
"lookup_expr": "exact",
"regexp": "^[1-9][0-9]*$",
"max_length": 8,
"required": false
},
"wallet": {
"lookup_expr": "exact",
"required": false
},
"wallet_from": {
"lookup_expr": "exact",
"max_length": 64,
"required": false
},
"wallet_to": {
"lookup_expr": "exact",
"max_length": 64,
"required": false
},
"wallet_type": {
"lookup_expr": "exact",
"choices": [
{
"value": 1,
"display_name": "Merchant"
},
{
"value": 2,
"display_name": "Enterprise"
},
{
"value": 3,
"display_name": "Custody"
},
{
"value": 4,
"display_name": "NFT"
},
{
"value": 5,
"display_name": "Swap"
}
],
"required": false
},
"id": {
"lookup_expr": "exact",
"regexp": "^[1-9][0-9]*$",
"max_length": 8,
"required": false
},
"created_at_from": {
"lookup_expr": "exact",
"max_length": 32,
"required": false
},
"created_at_to": {
"lookup_expr": "exact",
"max_length": 32,
"required": false
},
"updated_at_from": {
"lookup_expr": "exact",
"max_length": 32,
"required": false
},
"updated_at_to": {
"lookup_expr": "exact",
"max_length": 32,
"required": false
},
"label": {
"lookup_expr": "icontains",
"max_length": 32,
"required": false
},
"tracking_id": {
"lookup_expr": "icontains",
"max_length": 128,
"required": false
},
"commission": {
"lookup_expr": "exact",
"regexp": "[-+]?[0-9]*\\.?[0-9]*",
"max_length": 32,
"required": false
},
"address": {
"lookup_expr": "exact",
"required": false
},
"confirmations_needed": {
"lookup_expr": "exact",
"regexp": "^[1-9][0-9]*$",
"max_length": 2,
"required": false
},
"help_email": {
"lookup_expr": "exact",
"max_length": 64,
"required": false
},
"status": {
"lookup_expr": "exact",
"choices": [
{
"value": 1,
"display_name": "Waiting for approve"
},
{
"value": 2,
"display_name": "Approved"
},
{
"value": 3,
"display_name": "Cancelled"
}
],
"required": false
},
"time_limit": {
"lookup_expr": "exact",
"regexp": "^[1-9][0-9]*$",
"max_length": 8,
"required": false
},
"inaccuracy": {
"lookup_expr": "icontains",
"max_length": 32,
"required": false
},
"target_amount_requested": {
"lookup_expr": "exact",
"max_length": 32,
"required": false
},
"rate_requested": {
"lookup_expr": "exact",
"max_length": 32,
"required": false
},
"expired_at_from": {
"lookup_expr": "exact",
"max_length": 64,
"required": false
},
"expired_at_to": {
"lookup_expr": "exact",
"max_length": 64,
"required": false
},
"target_paid": {
"lookup_expr": "exact",
"max_length": 64,
"required": false
},
"enrolled": {
"lookup_expr": "exact",
"max_length": 64,
"required": false
},
"target_paid_pending": {
"lookup_expr": "exact",
"max_length": 64,
"required": false
},
"source_paid_pending": {
"lookup_expr": "exact",
"max_length": 64,
"required": false
},
"source_paid": {
"lookup_expr": "exact",
"max_length": 64,
"required": false
},
"source_commission": {
"lookup_expr": "exact",
"max_length": 64,
"required": false
},
"source_amount_requested": {
"lookup_expr": "exact",
"max_length": 64,
"required": false
},
"is_fee_included": {
"lookup_expr": "exact",
"required": false
},
"amount": {
"lookup_expr": "exact",
"regexp": "[-+]?[0-9]*\\.?[0-9]*",
"required": false
},
"charged": {
"lookup_expr": "icontains",
"max_length": 32,
"required": false
}
},
"POST": {
"amount": {
"type": "decimal",
"required": true,
"read_only": false,
"label": "Amount",
"min_value": 0
},
"currency": {
"type": "field",
"required": false,
"read_only": false,
"label": "Currency"
},
"address": {
"type": "string",
"required": false,
"read_only": false,
"label": "Address",
"max_length": 128
},
"target_deposit": {
"type": "string",
"required": false,
"read_only": false,
"label": "Target deposit"
},
"wallet": {
"type": "field",
"required": true,
"read_only": false,
"label": "Wallet"
},
"target_wallet": {
"type": "field",
"required": false,
"read_only": false,
"label": "Target wallet"
},
"tracking_id": {
"type": "string",
"required": false,
"read_only": false,
"label": "Tracking id",
"max_length": 128
},
"label": {
"type": "string",
"required": false,
"read_only": false,
"label": "Label",
"max_length": 32
},
"confirmations_needed": {
"type": "integer",
"required": false,
"read_only": false,
"label": "Confirmations needed",
"min_value": 0,
"max_value": 100
},
"fee_amount": {
"type": "decimal",
"required": false,
"read_only": false,
"label": "Fee amount",
"min_value": 0
},
"is_fee_included": {
"type": "boolean",
"required": false,
"read_only": false,
"label": "Is fee included"
},
"callback_url": {
"type": "url",
"required": false,
"read_only": false,
"label": "Callback url",
"max_length": 256
},
"force_blockchain": {
"type": "boolean",
"required": false,
"read_only": false,
"label": "Force blockchain"
},
"exp": {
"type": "field",
"required": false,
"read_only": true,
"label": "Exp"
},
"tag": {
"type": "string",
"required": false,
"read_only": false,
"label": "Tag",
"max_length": 64
},
"tag_type": {
"type": "string",
"required": false,
"read_only": false,
"label": "Tag type",
"max_length": 64
},
"travel_rule_info": {
"type": "field",
"required": false,
"read_only": false,
"label": "Travel rule info"
}
}
},
"custom": {
"POST": {
"address_masks": {
"1000": [
{
"address_type": "legacy",
"mask": [
"^1[1-9a-km-zA-HJ-NP-Z]{25,33}$"
],
"is_default": false
},
{
"address_type": "p2sh-segwit",
"mask": [
"^2[1-9a-km-zA-HJ-NP-Z]{33,34}$"
],
"is_default": true
},
{
"address_type": "bech32",
"mask": [
"^bcrt1[02-9ac-hj-np-z]{6,85}$"
],
"is_default": false
}
],
"1002": [
{
"address_type": null,
"mask": [
"^0x[0-9a-fA-F]{40}$"
],
"is_default": true
},
{
"address_type": "duplicate",
"mask": null,
"is_default": false
}
],
"1010": [
{
"address_type": null,
"mask": [
"^r[a-km-zA-HJ-NP-Z1-9]{24,34}$",
"^X[a-km-zA-HJ-NP-Z1-9]{46}$"
],
"is_default": true
}
],
"1125": [
{
"address_type": null,
"mask": [
"^0x[0-9a-fA-F]{40}$"
],
"is_default": true
},
{
"address_type": "duplicate",
"mask": null,
"is_default": false
}
],
"2015": [
{
"address_type": null,
"mask": [
"^0x[0-9a-fA-F]{40}$"
],
"is_default": true
},
{
"address_type": "duplicate",
"mask": null,
"is_default": false
}
],
"2065": [
{
"address_type": null,
"mask": [
"^0x[0-9a-fA-F]{40}$"
],
"is_default": true
},
{
"address_type": "duplicate",
"mask": null,
"is_default": false
}
]
}
}
}
}
}