Get Started
Welcome to the documentation page of our payment system!
We offer the following integration methods:
H2H (Host to Host) Integration
Payment Page Integration - integration through a payment window
H2H integration
Important varibles:
PASSWORD
- access the graphical interface of the system
API_KEY
- secret api key
DOMAIN
- backend URL
đź’ˇ You should get PASSWORD
, API_KEY
, DOMAIN
, two different
lists of banks: for request parameters and for response parameters from support.
Authorisation
To authorize requests, add the following header to your request
x-token
: API_KEY
Transactions
đź’ˇ There are two types of external transactions:
inbound
- pay in
outbound
- pay out
đź’ˇ Each request to create an external transaction has a tag_code field. It is used to send transactions with different fee rates.
For example, transfers by phone number and card number may have different fee rates for the merchant. In this case, unique tag_code is added to the transaction for each case.
We have 5 types of tag_code
: default
, account
, deeplink
, interbank
, cross-border
, where default
- default fee rate
account
- fee rate for account
deeplink
- fee rate for sberpay
interbank
- fee rate for SBP
cross-border
- fee rate for cross-border by using phone
đź’ˇ Pay in transaction statuses:
pending
accept
close
đź’ˇPay out transaction statuses:
pending
processing
accept
close
đź’ˇAnything with a code other than 200 is considered a failure
Create pay in transaction
request
curl --location 'https://DOMAIN/merchant/create/pay-in' \
--header 'accept: application/json' \
--header 'Content-Type: application/json' \
--header 'x-token: ${API_KEY}' \
--data '{
"amount": 159000000,
"hook_uri": "string",
"type": "card",
"tag_code": "default",
"banks": [
"alif"
],
"types": [
"phone", "cross-border-phone", "account", "card"
],
"payment_systems": [
"visa"
],
"merchant_payer_id": "e3d948f1-8d5a-4c3e-8b5f-2b8e11c6fd51e41a111",
"merchant_transaction_id": "b1c342a6-8e5b-4e8f-9c3ff-1a7e5e9b12a3b111"
}'
import requests
import json
url = "https://DOMAIN/merchant/create/pay-in"
payload = json.dumps({
"amount": 159000000,
"hook_uri": "string",
"type": "card",
"tag_code": "default",
"banks": [
"alif"
],
"types": [
"phone", "cross-border-phone", "account", "card", "sberpay"
],
"payment_systems": [
"visa"
],
"merchant_payer_id": "e3d9e441-8d5a-4c3e-8b5f-2b8e11c6fd51e41a111",
"merchant_transaction_id": "b1c3e2a6-8e44-4e8f-9c3ff-1a7e5e9b12a3b111"
})
headers = {
'accept': 'application/json',
'Content-Type': 'application/json',
'x-token': ' ${API_KEY}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
{
"amount": 159000000,
"hook_uri": "string",
"type": "card",
"tag_code": "default",
"banks": [
],
"types": [
"phone", "cross-border-phone", "account", "card"
],
"payment_systems": [
"visa"
],
"merchant_payer_id": "e3d9e8f1-8d5a-4c3e-8b5f-2b8e1c6d5e4a",
"merchant_transaction_id": "b1c3e2a6-8e5b-4e8f-9c3ff-1a7e5e9b12a3b111"
}
response
{
"id": "f2c4e8f1-8d1a-4c3e-8b5f-3f6c5e7b8b4e",
"direction": "inbound",
"amount": 169000000,
"currency_id": "KGS",
"exchange_rate": 94275000,
"status": "pending",
"create_timestamp": "2024-10-30T11:37:56.692887",
"bank_detail": {
"id": "192335d4-f819-4e23-985a-1c14f2a7ec29",
"name": "Ivan Ivanov",
"bank": "bakai",
"type": "card",
"payment_system": "visa",
"number": "1234567090987654",
"second_number": "string",
"bank_icon_url": "/payment-form/bank-icon/bakai"
},
"tag_id": "tag_id",
"payment_link": {
"sberpay_link": null,
"tpay_link": null
},
"transaction_auto_close_time_s": 900
}
{
"id": "f2c4e8f1-8d1a-4c3e-8b5f-3f6c5e7b8b4e",
"direction": "inbound",
"amount": 169000000,
"currency_id": "KGS",
"exchange_rate": 94275000,
"status": "pending",
"create_timestamp": "2024-10-30T11:37:56.692887",
"bank_detail": {
"id": "192335d4-f819-4e23-985a-1c14f2a7ec29",
"name": "Ivan Ivanov",
"bank": "bakai",
"type": "card",
"payment_system": "visa",
"number": "1234567090987654",
"second_number": "string",
"bank_icon_url": "/payment-form/bank-icon/bakai"
},
"tag_id": "tag_id",
"payment_link": {
"sberpay_link": null,
"tpay_link": null
},
"transaction_auto_close_time_s": 900
}
{
"id": "f2c4e8f1-8d1a-4c3e-8b5f-3f6c5e7b8b4e",
"direction": "inbound",
"amount": 169000000,
"currency_id": "KGS",
"exchange_rate": 94275000,
"status": "pending",
"create_timestamp": "2024-10-30T11:37:56.692887",
"bank_detail": {
"id": "192335d4-f819-4e23-985a-1c14f2a7ec29",
"name": "Ivan Ivanov",
"bank": "bakai",
"type": "card",
"payment_system": "visa",
"number": "1234567090987654",
"second_number": "string",
"bank_icon_url": "/payment-form/bank-icon/bakai"
},
"tag_id": "tag_id",
"payment_link": {
"sberpay_link": null,
"tpay_link": null
},
"transaction_auto_close_time_s": 900
}
method POST /merchant/create/pay-in
This method is used to create PAY IN transaction.
Request body parametrs
Name | Type | Mandatory | Description |
---|---|---|---|
amount |
LONG | YES | Real amount of the transaction* 1 000 000 (it is necessary to transmit to the system exactly in this form (* 1000000) it is necessary for accuracy) |
bank |
STRING | YES | Contact support to get a list of banks (a list of banks whose details can be issued for the successful creation of a transaction, therefore it can reduce conversion) |
merchant_payer_id |
STRING | YES | Inner client id (we need it to prevent spam)the id must be unique (means that each client has its own unique id) |
merchant_transaction_id |
STRING | YES | Inner transaction id (id set by the merchant) the id must be unique (creating transactions with the same merchant_transaction_id is prohibited and impossible) |
tag_code |
ENUM | YES | default - default fee rate account - fee rate for account deeplink - fee rate for sberpay interbank - fee rate for SBP cross-border - fee rate for cross-border by using phone and t-pay |
type |
STRING | YES | card phone - for sbp account cross-border-phone - for cross-border by phone The required type schould be selected |
banks |
LIST[ENUM] | NO | Contact support to get a list of banks |
hook_uri |
STRING | NO | The URL to which our system will send a POST request to display a change in the transaction status (status: pending -> status: accept or status: pending -> status: close*), the current status of the transaction is transmitted to the callback |
payment_systems |
STRING | NO | visa - both KGS and TJS mastercard - both KGS and TJS elcart - only KGS kortimilli - only TJS Name of the provider of electronic payment systems for transactions (available only for TJS and KGS) |
types |
LIST[ENUM] | NO | card phone account cross-border-phone - for and cross-border by phone |
đź’ˇ status close* occurs if the customer does not pay, or if they pay
later than needed. In this case, you will have to wait for the transfer from
the close to accept status manually (if it is possible to determine that
it was this client who made the payment, otherwise wait
for the appeal)
Response body parameters
name | Type | Description |
---|---|---|
amount |
LONG | Real amount of the transaction* 1 000 000 (for accuracy) |
bank_detail.bank |
ENUM | the bank to which the transfer should be made from the list of banks for response from support |
bank_detail.id |
UUID | Example: id = "d7e5c2a6-8e5b-4e8f-9c3f-1a7e5e9b2a3b" |
bank_detail.name |
STRING | The name of the cardholder to whom the transfer is being made. Example: Ivan Ivanov |
bank_detail.number |
ENUM | The number of phone/card/account details to which the client schould do transaction |
bank_detail.payment_systems |
ENUM | visa - both KGS and TJS mastercard - both KGS and TJS elcart - only KGS kortimilli - only TJS Name of the provider of electronic payment systems for transactions (available only for TJS and KGS) |
bank_detail.type |
ENUM | card phone account cross-border-phone - for cross-border by using phone (the difference between cross-border-phone and phone is that in the case of cross-border-phone, transfers are made in currency RUB to a foreign currency, which can reduce the commission as both types forced to use different tag_code ) |
create_timestamp |
ISO 8601 | Time when it was created |
currency_id |
ENUM | Currency id in our system of the currency for which the transaction is being carried out |
direction |
ENUM | inbound - inbound as it is a pay-in transaction outbound - for pay-out transaction |
exchange_rate |
LONG | This is the rate at which the amount is converted to usdt multiplied by 1 000 000 |
id |
UUID | Transaction id in our system |
payment_link |
URL | Example: https://provider-example.com/deeplink |
status |
ENUM | Status of the transaction is always pending After pending status must become close - (status occurs if the client does not pay, or if he pays late) or accept - ( if the client has paid in time) |
transaction_auto_close_time_s |
LONG | The time in seconds after which the transaction will close |
đź’ˇstatus close* occurs if the customer does not pay, or if they pay
later than needed. In this case, you will have to wait for the transfer from
the close to accept status manually (if it is possible to determine that
it was this client who made the payment, otherwise wait
for the appeal)
đź’ˇThere is a functionality in our system (it is optional): the amount from the request may differ from the amount amount in the response, since if there are transactions for the same amount at one time, our system offers the user to transfer bigger, close free amount, (for example: When creating a transaction for 1000, 1001 may be returned, since there are no details for 1000, then the client definitely needs to transfer 1001). This functionality will increase the conversion rate, for this you need to display the amount from the response to the user so that he can see exactly that the amount has changed to avoid errors with disputes. (if you are interested in using this functionality, please contact us)
Create pay out transaction
request
curl --location 'https://DOMAIN/merchant/create/pay-out' \
--header 'accept: application/json' \
--header 'Content-Type: application/json' \
--header 'x-token: ${API_KEY} ' \
--data '{
"amount": "10000000",
"bank_detail_number": "5500123456789010",
"merchant_payer_id": "a5b9e8f1-8d9a1-4c3e-8b5f-3f6c15e7b8b4e",
"merchant_transaction_id": " b1c3e2a6-8e5b-4ed8f-9c3f1-11a7e15e9b2a3b",
"type":"account",
"tag_code": "account",
"bank_detail_bank": "SBER",
"hook_uri": "https://DOMAIN.com/payments"
}'
import requests
import json
url = "https://DOMAIN/merchant/create/pay-out"
payload = json.dumps({
"amount": 1000000,
"hook_uri": "string",
"type": "account",
"tag_code": "account",
"bank": "string",
"banks": [
"string"
],
"types": [
"string"
],
"bank_detail_number": "5500123456789010",
"bank_detail_bank": "SBER",
"bank_detail_name": "Ivanov Ivan",
"merchant_payer_id": "a5b9e8f1-8d9a-4c3e-8b5f-3f6c5e7b8b4e",
"merchant_transaction_id": "b1c3e2a6-8e5b-4e8f-9c3f-1a7e5e9b2a3b"
})
headers = {
'Content-Type': 'application/json',
'x-token': '${API_KEY}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
{
"amount": 1000000,
"hook_uri": "string",
"type": "account",
"tag_code": "account",
"bank": "SBER",
"banks": [
"string"
],
"types": [
"string"
],
"bank_detail_number": "5500123456789010",
"bank_detail_bank": "SBER",
"bank_detail_name": "Ivanov Ivan",
"merchant_payer_id": "a5b9e8f1-8d9a-4c3e-8b5f-3f6c5e7b8b4e",
"merchant_transaction_id": "b1c3e2a6-8e5b-4e8f-9c3f-1a7e5e9b2a3b"
}
response
{
"id": "c1a9e8f5-8d2b-4f3e-9b8f-2c8e1c6d5e4a",
"direction": "outbound",
"amount": 10000000,
"currency_id": "RUB",
"status": "pending",
"create_timestamp": "2024-10-30T11:37:56.692887"
}
{
"id": "c1a9e8f5-8d2b-4f3e-9b8f-2c8e1c6d5e4a",
"direction": "outbound",
"amount": 10000000,
"currency_id": "RUB",
"status": "pending",
"create_timestamp": "2024-10-30T11:37:56.692887"
}
{
"id": "c1a9e8f5-8d2b-4f3e-9b8f-2c8e1c6d5e4a",
"direction": "outbound",
"amount": 10000000,
"currency_id": "RUB",
"status": "pending",
"create_timestamp": "2024-10-30T11:37:56.692887"
}
method POST /merchant/create/pay-out
This method is used to create PAY OUT transaction.
Request body parametrs
Name | Type | Mandatory | Description |
---|---|---|---|
amount |
LONG | YES | Real amount of the transaction* 1 000 000 (it is necessary to transmit to the system exactly in this form (* 1000000) it is necessary for accuracy) |
bank_detail_number |
LONG | YES | The number of phone/card/account details using which the transaction schould be created |
merchant_payer_id |
STRING | YES | Inner client id (we need it to prevent spam)the id must be unique (means that each client has its own unique id) |
merchant_transaction_id |
STRING | YES | Inner transaction id (id set by the merchant) the id must be unique (creating transactions with the same merchant_transaction_id is prohibited and impossible) |
type |
ENUM | YES | card phone account cross-border-phone - for cross-border by using phone The required type schould be selected |
bank_detail_bank |
ENUM | *NO | *Mandatory if type = phone, coordinate the list of banks with the support Contact support to get a list of banks (a list of banks whose details can be issued for the successful creation of a transaction) |
bank_detail_name |
STRING | *NO | The name of the cardholder to whom the transfer is being made. Example: Ivanov Ivan, *mandatory if type = phone |
hook_uri |
STRING | NO | The URL to which our system will send a POST request to display a change in the transaction status (status: pending -> status: accept or status: pending -> status: close*), the current status of the transaction is transmitted to the callback, |
tag_code |
ENUM | YES | default - default fee rate account - fee rate for account deeplink - fee rate for sberpay interbank - fee rate for SBP cross-border - fee rate for cross-border by using phone |
Response body parameters
Name | Type | Description |
---|---|---|
amount |
LONG | Real amount of the transaction* 1 000 000 (it is necessary to transmit to the system exactly in this form (* 1000000) it is necessary for accuracy) |
create_timestamp |
ISO 8601 | Time when it was created |
currency_id |
ENUM | Currency id in our system of the currency for which the transaction is being carried out |
direction |
ENUM | inbound - for pay-in transactions outbound - for pay-out transactions |
id |
UUID | Transaction id in our system |
status |
ENUM | Status of the transaction is always pending After pending status must become close or accept depending on whether the payment was made or not |
Get transaction status
request
# requet by merchant_transaction_id
curl --location 'https://DOMAIN/merchant/get/?merchant_transaction_id=612f7fc3-bfa2-4ad9-9865-f2249381b6bf' \
--header 'accept: application/json' \
--header 'x-token: ${API_KEY}'
# requet by id
curl --location 'https://DOMAIN/merchant/get/?id=a8c3f2e1-5e3c-4c8b-b3f5-e31c8b0e4d2a' \
--header 'accept: application/json' \
--header 'x-token: ${API_KEY}'
# request by merchant_transaction_id
import requests
url = "https://DOMAIN/merchant/get/?merchant_transaction_id=a8c3f2e1-5e3c-4c8b-b3f5-8e1c8b0e4d2a"
payload = ""
headers = {
'x-token': '${API_KEY}'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
# request by id
import requests
url = "https://DOMAIN/merchant/get/?merchant_transaction_id=3f8b1c3e-9e1f-4b6e-9b4a-56f2c2e7c7b1"
payload = ""
headers = {
'x-token': '${API_KEY}'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
response
{
"id": "3f8b1c3e-9e1f-4b6e-9b4a-56f2c2e7c7b1",
"merchant_transaction_id": "a8c3f2e1-5e3c-4c8b-b3f5-8e1c8b0e4d2a",
"direction": "inbound",
"amount": 0,
"status": "pending",
"merchant_trust_change": 0,
"create_timestamp": "2024-10-30T11:37:56.692887",
"tag_id": null,
"currency_id": "RUB",
"exchange_rate": 94275000
}
{
"id": "3f8b1c3e-9e1f-4b6e-9b4a-56f2c2e7c7b1",
"merchant_transaction_id": "a8c3f2e1-5e3c-4c8b-b3f5-8e1c8b0e4d2a",
"direction": "inbound",
"amount": 0,
"status": "pending",
"merchant_trust_change": 0,
"create_timestamp": "2024-10-30T11:37:56.692887",
"tag_id": null,
"currency_id": "RUB",
"exchange_rate": 94275000
}
{
"id": "3f8b1c3e-9e1f-4b6e-9b4a-56f2c2e7c7b1",
"merchant_transaction_id": "a8c3f2e1-5e3c-4c8b-b3f5-8e1c8b0e4d2a",
"direction": "inbound",
"amount": 0,
"status": "pending",
"merchant_trust_change": 0,
"create_timestamp": "2024-10-30T11:37:56.692887",
"tag_id": null,
"currency_id": "RUB",
"exchange_rate": 94275000
}
method GET /merchant/get
It is important that it can be done only by query
in this case, you can make a request in two ways by merchant_transaction_id
or id
:
Query parametrs
Name | Type | Mandatory | Description |
---|---|---|---|
id |
UUID | *NO | Transaction id, *one and exactly one of the two fields must be in the request |
merchant_transaction_id |
UUID | *NO | Inner transaction id, *one and exactly one of the two fields must be in the request |
Response body parameters
Name | Type | Description |
---|---|---|
amount |
LONG | Real amount of the transaction * 1 000 000 (for accuracy) |
create_timestamp |
ISO 8601 | Time when transaction was created |
currency_id |
ENUM | Currency id in our system of the currency for which the transaction is being carried out |
direction |
ENUM | inbound - for pay-in transactions outbound - for pay-out transactions |
exchange_rate |
LONG | This is the rate at which the amount is converted to usdt multiplied by 1 000 000 |
id |
UUID | Transaction id in our system |
merchant_transaction_id |
UUID | Merchant transaction id |
merchant_trust_change |
LONG | Merchant's balance change, merchant_trust_change = amount / exchange_rate * ( 1 - comissions) |
status |
ENUM | pending close - status occurs if the client does not pay, or if he pays late accept - if the client has paid status of the transaction |
tag_id |
ENUM | default - default fee rate account - extra fee rate for account if needed deeplink - extra fee rate for deeplink if needed interbank - extra fee rate for interbank if needed |
status close* occurs if the customer does not pay, or if they pay
later than needed. In this case, you will have to wait for the transfer from
the close to accept status manually (if it is possible to determine that
it was this client who made the payment, otherwise wait
for the appeal)
Receive callback
request
curl --location --request POST 'https://DOMAIN/your-url-for-callback' \
--header 'x-token: ${API_KEY}' \
--header 'Content-Type: application/json' \
--data '{
"id": "034edc63-f14d-4dbb-b1b3-55908d736fc4",
"status": "accept",
"amount": 1000000,
"merchant_transaction_id": "728s93jf-f14d-4dbb-b1b3-55908gggghhj",
"merchant_trust_change": 120000000,
"currency_id": "currency id",
"exchange_rate": 9649
}'
{
"id": "034edc63-f14d-4dbb-b1b3-55908d736fc4",
"status": "accept",
"amount": 1000000,
"merchant_transaction_id": "728s93jf-f14d-4dbb-b1b3-55908gggghhj",
"merchant_trust_change": 120000000,
"currency_id": "1",
"exchange_rate": 9649
}
import requests
import json
url = "https://DOMAIN/your-url-for-callback"
payload = json.dumps({
"id": "034edc63-f14d-4dbb-b1b3-55908d736fc4",
"status": "accept",
"amount": 1000000,
"merchant_transaction_id": "728s93jf-f14d-4dbb-b1b3-55908gggghhj",
"merchant_trust_change": 120000000,
"currency_id": "currency id",
"exchange_rate": 9649
})
headers = {
'Content-Type': 'application/json',
'x-token': '${API_KEY}'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
method POST /your-url-for-callback
After any change in the transaction status (pending -> close for example) we send post request to your server
- You need to use API_KEY to make requests secure
- You need to pass callback url as “hook_uri” to transaction when create it
Request body parameters
Name | Type | Description |
---|---|---|
amount |
LONG | Real amount * 1 000 000 (for accuracy) |
currency_id |
STRING | Currency id in our system of the currency for which the transaction is being carried out |
exchange_rate |
LONG | Amount of the transaction in USDT * 1 000 000 (for accuracy) |
id |
UUID | Transaction id in our system |
merchant_transaction_id |
UUID | Merchant transaction id |
merchant_trust_change |
LONG | Merchant's balance change, merchant_trust_change = amount / exchange_rate * ( 1 - comissions) |
status |
ENUM | Current status of the transaction, where pending - nothing has happened to the transaction yet,accept - the client has paid in timeclose - the client does not pay, or if he pays late |
status close* occurs if the customer does not pay, or if they pay
later than needed. In this case, you will have to wait for the transfer from
the close to accept status manually (if it is possible to determine that
it was this client who made the payment, otherwise wait
for the appeal)
Balance
Get usdt balance
request
curl --location 'https://DOMAIN/merchant/balances' \
--header 'accept: application/json' \
--header 'x-token: ${API_KEY}'
import requests
url = "https://DOMAIN/merchant/balances"
payload = ""
headers = {
'x-token': '${API_KEY}'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
response
{
"trust_balance": 59341514528,
"locked_balance": -7171964683
}
{
"trust_balance": 59341514528,
"locked_balance": -7171964683
}
{
"trust_balance": 59341514528,
"locked_balance": -7171964683
}
method GET /merchant/balances
There are NO request body as this info is taken using the authorization Total balance = trust_balacnce+ locked_banalnce
араара
Response body parameters
Name | Type | Description |
---|---|---|
locked_balance |
LONG | How much would be deducted from merchant without commissions (the sum of all pending transactions on pay out * 1 000 000 (for accuracy)) |
trust_balance |
LONG | Total balance * 1 000 000 (for accuracy) of the user, it includes locked_balance (example: 59341514528 - real 59341,514528 USDT) |
Fields that are not specified in the table are not relevant
Real balance is 1 000 000 times smaller
Merchant trust balance should be greater than 0 to create pay out transactions.
trust_balance, locked_balance, profit_balance, fiat_trust_balance, fiat_locked_balance, fiat_profit_balance stored in USDT
Get estimated fiat balance
request
curl --location 'https://DOMAIN/merchant/balances/estimated-fiat-balance' \
--header 'x-token: ${API_KEY}'
import requests
url = "https://DOMAIN/merchant/balances/estimated-fiat-balance"
payload = ""
headers = {
'x-token': '${API_KEY}'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
response
{
"trust_balance": 59341514528,
}
{
"trust_balance": 59341514528,
}
{
"trust_balance": 59341514528,
}
method GET /merchant/balances/estimated-fiat-balance
There are NO request body as this info is taken using the authorization
Response body parameters
Name | Type | Description |
---|---|---|
trust_balance |
LONG | Total balance of the user * 1 000 000 (for accuracy) , it includes locked_balance (example: 59341514528 - real 59341,514528 USDT) |
Real balance is 1 000 000 times smaller
Merchant trust balance should be greater than 0 to create pay out transactions.
trust_balance stored in USDT
Payment page integration
Important varibles:
PASSWORD
- access the graphical interface of the system
API_KEY
- key for callback security
DOMAIN
- backend URL
PAYMENT_PAGE_DOMAIN
- the domain of the payment page where customers make payments
đź’ˇ You should get PASSWORD
, API_KEY
, DOMAIN
, PAYMENT_PAGE_DOMAIN
, two different
lists of banks: for request parameters and for response parameters from support.
Authorisation
To authorize requests, add the following header to your request
x-token
: API_KEY
Transactions
đź’ˇ Each request schould have a tag_code field. It is used to send transactions with different fee rates.
For example, transfers by phone number and card number may have different fee rates for the merchant. In this case, unique tag_code is added to the transaction for each case.
We have 5 types of tag_code
: default
, account
, deeplink
, interbank
, cross-border
, where default
- default fee rate
account
- fee rate for account
deeplink
- fee rate for sberpay
interbank
- fee rate for SBP
cross-border
- fee rate for cross-border-phone and t-pay
Create pay in transaction
request
curl --location 'https://DOMAIN/v2/payment-form' \
--header 'Content-Type: application/json' \
--header 'x-token: ${API_KEY}'\
--data '{
"api_secret": "API KEY",
"merchant_transaction_id": "5f9b32ad-97b8-47fc-9141-c5635d95fcc0",
"hook_uri": "https://example.com",
"payer_id": "bagt32ad-6321-90fc-9pl1-c5635d95fc66",
"amount": 48000000,
"return_url": "https://example.com",
"success_url": "https://example.com",
"fail_url": "https://example.com",
"merchant_website_name": "MyCasino",
"config": [
{
"name": "sberpay",
"options": {
"types": [
"account"
],
"banks": [
],
"tag_code": "deeplink"
}
},
{
"name": "card",
"options": {
"types": [
"card"
],
"banks": null,
"payment_systems": [
"kortimilli"
],
"tag_code": "default"
}
},
{
"name": "phone",
"options": {
"types": [
"phone"
],
"payment_systems": [
"kortimilli"
],
"banks": null,
"tag_code": "interbank"
}
},
{
"name": "t-pay",
"options": {
"types": [
"cross-border-phone" , "phone"
],
"banks": null,
"tag_code": "deeplink"
}
},
{
"name": "cross-border-phone",
"options": {
"types": [
"cross-border-phone"
],
"banks": null,
"tag_code": "cross-border"
}
}
]
}'
{
"api_secret": "API KEY",
"merchant_transaction_id": "5f9b32ad-97b8-47fc-9141-c5635d95fcc0",
"hook_uri": "https://example.com",
"payer_id": "bagt32ad-6321-90fc-9pl1-c5635d95fc66",
"amount": 48000000,
"return_url": "https://example.com",
"success_url": "https://example.com",
"fail_url": "https://example.com",
"merchant_website_name": "MyCasino",
"config": [
{
"name": "sberpay",
"options": {
"types": [
"account"
],
"banks": [
],
"tag_code": "deeplink"
}
},
{
"name": "card",
"options": {
"types": [
"card"
],
"banks": null,
"payment_systems": [
"kortimilli"
],
"tag_code": "default"
}
},
{
"name": "phone",
"options": {
"types": [
"phone"
],
"payment_systems": [
"kortimilli"
],
"banks": null,
"tag_code": "interbank"
}
},
{
"name": "t-pay",
"options": {
"types": [
"cross-border-phone" , "phone"
],
"banks": null,
"tag_code": "deeplink"
}
},
{
"name": "cross-border-phone",
"options": {
"types": [
"cross-border-phone"
],
"banks": null,
"tag_code": "cross-border"
}
}
]
}
import requests
import json
url = "https://DOMAIN/v2/payment-form"
payload = json.dumps({
"api_secret": "API KEY",
"merchant_transaction_id": "5f9b32ad-97b8-47fc-9141-c5635d95fcc0",
"hook_uri": "https://example.com",
"payer_id": "bagt32ad-6321-90fc-9pl1-c5635d95fc66",
"amount": 48000000,
"return_url": "https://example.com",
"success_url": "https://example.com",
"fail_url": "https://example.com",
"merchant_website_name": "MyCasino",
"config": [
{
"name": "sberpay",
"options": {
"types": [
"account"
],
"banks": [],
"tag_code": "deeplink"
}
},
{
"name": "card",
"options": {
"types": [
"card"
],
"banks": None,
"payment_systems": [
"kortimilli"
],
"tag_code": "default"
}
},
{
"name": "phone",
"options": {
"types": [
"phone"
],
"payment_systems": [
"kortimilli"
],
"banks": None,
"tag_code": "interbank"
}
},
{
"name": "t-pay",
"options": {
"types": [
"cross-border-phone" , "phone"
],
"banks": None,
"tag_code": "deeplink"
}
},
{
"name": "cross-border-phone",
"options": {
"types": [
"cross-border-phone"
],
"banks": None,
"tag_code": "cross-border"
}
}
]
})
headers = {
'x-token': '${API_KEY}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
response
{
"id": "03e5e3df-477d-49eb-bfe7-f9e383e01901",
"merchant_transaction_id": "5f9b32ad-97b8-47fc-9141-c5635d95fcc0"
}
{
"id": "03e5e3df-477d-49eb-bfe7-f9e383e01901",
"merchant_transaction_id": "5f9b32ad-97b8-47fc-9141-c5635d95fcc0"
}
{
"id": "03e5e3df-477d-49eb-bfe7-f9e383e01901",
"merchant_transaction_id": "5f9b32ad-97b8-47fc-9141-c5635d95fcc0"
}
method POST /v2/payment-form
This method is used to create PAY IN transaction for paymnt form option.
Request body parametrs
Name | Type | Mandatory | Description |
---|---|---|---|
amount |
LONG | yes | Real amount of the transaction* 1 000 000 (it is necessary to transmit to the system exactly in this form (* 1000000) it is necessary for accuracy) |
api_secret |
LONG | YES | API_KEY (ask support) - uniq key of your token |
config |
LIST[*CONFIG] | YES | List of payment method configurations. Get config data from support! And see the example in the table config data below |
hook_uri |
STRING | YES | The URL to which our system will send a POST request to display a change in the transaction status(status: pending -> status: accept or status: pending -> status: close*), the current status of the transaction is transmitted to the callback. |
merchant_transaction_id |
STRING | YES | Inner transaction id (id set by the merchant) the id must be unique (creating transactions with the same merchant_transaction_id is prohibited and impossible) |
fail_url |
STRING | NO | The url that is redirectedin case of transaction failure |
merchant_website_name |
STRING | NO | Merchant's name displayed on the form |
payer_id |
ENUM | NO | Inner client id (we need it to prevent spam)the id must be unique (means that each client has its own unique id) |
return_url |
URL | NO* | This is a link to return to your site |
success_url |
STRING | NO | The url that is redirected in case of transaction success |
đź’ˇstatus close* occurs if the customer does not pay, or if they pay
later than needed. In this case, you will have to wait for the transfer from
the close to accept status manually (if it is possible to determine that
it was this client who made the payment, otherwise wait
for the appeal)
*CONFIG - payment data model, nested structure
CONFIG MODEL
Name | Type | Mandatory | Description |
---|---|---|---|
name |
ENUM | YES | The name of the payment method that will be displayed on the form card phone account sberpay t-pay cross-border-phone |
options.types |
LIST[ENUM] | YES | Types of payment method card phone - (phone can be used also for t-pay) account cross-border-phone - for t-pay or cross-border by using phone |
options.banks |
STRING | *NO | Ask the support for a list of banks |
options.tag_code |
LIST[ENUM] | YES | default - default fee rate account - fee rate for account deeplink - fee rate for sberpay interbank - fee rate for SBP cross-border - fee rate for cross-border by phone or t-pay |
options.payment_systems |
ENUM | NO | visa - both KGS and TJS mastercard - both KGS and TJS elcart - only KGS kortimilli - only TJS Name of the provider of electronic payment systems for transactions (available only for TJS and KGS) |
Response body parameters
Parametr | Type | Description |
---|---|---|
id |
UUID | Transaction id in our system, This id is required to use the payment form (used this way: https://PAYMENT_PAGE_DOMAIN/id) |
merchant_transaction_id |
UUID | Inner transaction id (id set by the merchant) the id must be unique (creating transactions with the same merchant_transaction_id is prohibited and impossible) |
Next, you need to provide the client with the following url for payment:
https://PAYMENT_PAGE_DOMAIN/id
đź’ˇThere is a functionality in our system (it is optional): the amount from the request may differ from the amount in the response, since if there are transactions for the same amount at one time, our system offers the user to transfer bigger, close free amount, (for example: When creating a transaction for 1000, 1001 may be returned, since there are no details for 1000, then the client definitely needs to transfer 1001). This functionality will increase the conversion rate, for this you need to display the amount from the response to the user so that he can see exactly that the amount has changed to avoid errors with disputes. (if you are interested in using this functionality, please contact us)
Get transaction status
request
# requet by merchant_transaction_id
curl --location 'https://DOMAIN/merchant/get/?merchant_transaction_id=612f7fc3-bfa2-4ad9-9865-f2249381b6bf' \
--header 'accept: application/json' \
--header 'x-token: ${API_KEY}'
# requet by id
curl --location 'https://DOMAIN/merchant/get/?id=a8c3f2e1-5e3c-4c8b-b3f5-e31c8b0e4d2a' \
--header 'accept: application/json' \
--header 'x-token: ${API_KEY}'
# request by merchant_transaction_id
import requests
url = "https://DOMAIN/merchant/get/?merchant_transaction_id=a8c3f2e1-5e3c-4c8b-b3f5-8e1c8b0e4d2a"
payload = ""
headers = {
'x-token': '${API_KEY}'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
# request by id
import requests
url = "https://DOMAIN/merchant/get/?merchant_transaction_id=3f8b1c3e-9e1f-4b6e-9b4a-56f2c2e7c7b1"
payload = ""
headers = {
'x-token': '${API_KEY}'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
response
{
"id": "3f8b1c3e-9e1f-4b6e-9b4a-56f2c2e7c7b1",
"merchant_transaction_id": "a8c3f2e1-5e3c-4c8b-b3f5-8e1c8b0e4d2a",
"direction": "inbound",
"amount": 0,
"status": "pending",
"merchant_trust_change": 0,
"create_timestamp": "2024-10-30T11:37:56.692887",
"tag_id": null,
"currency_id": "RUB",
"exchange_rate": 94275000
}
{
"id": "3f8b1c3e-9e1f-4b6e-9b4a-56f2c2e7c7b1",
"merchant_transaction_id": "a8c3f2e1-5e3c-4c8b-b3f5-8e1c8b0e4d2a",
"direction": "inbound",
"amount": 0,
"status": "pending",
"merchant_trust_change": 0,
"create_timestamp": "2024-10-30T11:37:56.692887",
"tag_id": null,
"currency_id": "RUB",
"exchange_rate": 94275000
}
{
"id": "3f8b1c3e-9e1f-4b6e-9b4a-56f2c2e7c7b1",
"merchant_transaction_id": "a8c3f2e1-5e3c-4c8b-b3f5-8e1c8b0e4d2a",
"direction": "inbound",
"amount": 0,
"status": "pending",
"merchant_trust_change": 0,
"create_timestamp": "2024-10-30T11:37:56.692887",
"tag_id": null,
"currency_id": "RUB",
"exchange_rate": 94275000
}
method GET /merchant/get
It is important that it can be done only by query
in this case, you can make a request in two ways by merchant_transaction_id
or id
:
Query parametrs
Name | Type | Mandatory | Description |
---|---|---|---|
id |
UUID | *NO | Transaction id in our system, *one and exactly one of the two fields must be in the request |
merchant_transaction_id |
UUID | *NO | Inner transaction id (id set by the merchant), *one and exactly one of the two fields must be in the request |
Response body parameters
Name | Type | Description |
---|---|---|
id |
UUID | Transaction id in our system |
status |
ENUM | current status of the transaction, where pending - nothing has happened to the transaction yet, accept - the client has paid in time, close - the client does not pay, or if he pays late |
merchant_transaction_id |
UUID | Merchant transaction id |
create_timestamp |
ISO 8601 | Time when transaction was created |
direction |
ENUM | inbound - for pay-in transactions outbound - for pay-out transactions |
amount |
LONG | Real amount of the transaction * 1 000 000 (for accuracy) |
merchant_trust_change |
LONG | Merchant's balance change, merchant_trust_change = amount / exchange_rate * ( 1 - platform_comission) |
tag_id |
ENUM | default - default fee rate account - fee rate for account deeplink - fee rate for sberpay interbank - fee rate for SBP cross-border - for cross-border by using phone or t-pay |
currency_id |
ENUM | Currency id in our system of the currency for which the transaction is being carried out |
exchange_rate |
LONG | This is the rate at which the amount is converted to usdt multiplied by 1 000 000 |
status close* occurs if the customer does not pay, or if they pay
later than needed. In this case, you will have to wait for the transfer from
the close to accept status manually (if it is possible to determine that
it was this client who made the payment, otherwise wait
for the appeal)
Receive callback
request
curl --location --request POST 'https://DOMAIN/your-url-for-callback' \
--header 'x-token: ${API_KEY}' \
--header 'Content-Type: application/json' \
--data '{
"id": "034edc63-f14d-4dbb-b1b3-55908d736fc4",
"status": "accept",
"amount": 1000000,
"merchant_transaction_id": "728s93jf-f14d-4dbb-b1b3-55908gggghhj",
"merchant_trust_change": 120000000,
"currency_id": "currency id",
"exchange_rate": 9649
}'
{
"id": "034edc63-f14d-4dbb-b1b3-55908d736fc4",
"status": "accept",
"amount": 1000000,
"merchant_transaction_id": "728s93jf-f14d-4dbb-b1b3-55908gggghhj",
"merchant_trust_change": 120000000
}
import requests
import json
url = "https://DOMAIN/your-url-for-callback"
payload = json.dumps({
"id": "034edc63-f14d-4dbb-b1b3-55908d736fc4",
"status": "accept",
"amount": 1000000,
"merchant_transaction_id": "728s93jf-f14d-4dbb-b1b3-55908gggghhj",
"merchant_trust_change": 120000000,
"currency_id": "currency id",
"exchange_rate": 9649
})
headers = {
'Content-Type': 'application/json',
'x-token': '${API_KEY}'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
method POST /your-url-for-callback
After any change in the transaction status (pending -> close for example) we send post request to your server
- You need to use API_KEY to make requests secure
- You need to pass callback url as “hook_uri” to transaction when create it
Request body parameters
Name | Type | Description |
---|---|---|
amount |
LONG | Real amount * 1 000 000 (for accuracy) |
currency_id |
STRING | Currency id in our system of the currency for which the transaction is being carried out |
exchange_rate |
LONG | Amount of the transaction in USDT * 1 000 000 (for accuracy) |
id |
UUID | Transaction id in our system |
merchant_transaction_id |
UUID | Merchant transaction id |
merchant_trust_change |
LONG | Merchant's balance change, merchant_trust_change = amount / exchange_rate * ( 1 - comissions) |
status |
ENUM | Current status of the transaction, where pending - nothing has happened to the transaction yet,accept - the client has paid in timeclose - the client does not pay, or if he pays late |
status close* occurs if the customer does not pay, or if they pay
later than needed. In this case, you will have to wait for the transfer from
the close to accept status manually (if it is possible to determine that
it was this client who made the payment, otherwise wait
for the appeal)
Balance
Get usdt balance
request
curl --location 'https://DOMAIN/merchant/balances' \
--header 'accept: application/json' \
--header 'x-token: ${API_KEY}'
import requests
url = "https://DOMAIN/merchant/balances"
payload = ""
headers = {
'x-token': '${API_KEY}'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
response
{
"trust_balance": 59341514528,
"locked_balance": -7171964683
}
{
"trust_balance": 59341514528,
"locked_balance": -7171964683
}
{
"trust_balance": 59341514528,
"locked_balance": -7171964683
}
method GET /merchant/balances
There are NO request body as this info is taken using the authorization Total balance = trust_balacnce+ locked_banalnce
Response body parameters
Name | Type | Description |
---|---|---|
locked_balance |
LONG | How much would be deducted from merchant without commissions (the sum of all pending transactions on pay out * 1 000 000 (for accuracy)) |
trust_balance |
LONG | Total balance * 1 000 000 (for accuracy) of the user, it includes locked_balance but does not include blocked balance (example: 59341514528 - real 59341,514528 USDT) |
Fields that are not specified in the table are not relevant
Real balance is 1 000 000 times smaller
Merchant trust balance should be greater than 0 to create pay out transactions.
trust_balance, locked_balance, profit_balance, fiat_trust_balance, fiat_locked_balance, fiat_profit_balance stored in USDT
Get estimated fiat balance
request
curl --location 'https://DOMAIN/merchant/balances/estimated-fiat-balance' \
--header 'x-token: ${API_KEY}'
import requests
url = "https://DOMAIN/merchant/balances/estimated-fiat-balance"
payload = ""
headers = {
'x-token': '${API_KEY}'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
response
{
"trust_balance": 59341514528,
}
{
"trust_balance": 59341514528,
}
{
"trust_balance": 59341514528,
}
method GET /merchant/balances/estimated-fiat-balance
There are NO request body as this info is taken using the authorization
Response body parameters
Name | Type | Description |
---|---|---|
trust_balance |
LONG | Total balance of the user * 1 000 000 (for accuracy) , it includes locked_balance (example: 59341514528 - real 59341,514528 USDT) |
Real balance is 1 000 000 times smaller
Merchant trust balance should be greater than 0 to create pay out transactions.
trust_balance stored in USDT
Errors
Error Code | Meaning | to do |
---|---|---|
400 | Appeal decision already made | |
400 | Either transaction_id or merchant_transaction_id must be provided | |
400 | Uploaded file has invalid type | |
400 | Uploaded file has exceed maximum file size | |
400 | Mutual exclusive filter params provided | |
403 | Wrong user role | |
404 | Appeal not found | |
430 | Not enough trust balance | Not enough trust balance. |
431 | Not enough profit balance | Not enough profit balance. |
432 | User not enabled. Enable user, if it is impossible, deposit trust balance |
it is needed to check if the switches are on |
433 | Wrong request external transaction status | |
434 | Wrong existing external transaction current status | |
435 | Wrong request internal transaction status | |
436 | Wrong existing internal transaction current status | |
437 | Wrong existing external transaction direction | |
439 | No external transactions candidates for this amount | |
440 | Cannot parse amount from message | |
441 | Min withdraw limit is currently | |
442 | Cannot find bank detai | |
443 | Cannot find currency | |
444 | Cannot find external transaction | the transaction was not created |
445 | Cannot find internal transaction | |
445 | Cannot find transaction | |
446 | Cannot find user | |
447 | Cannot find contract | |
448 | Cannot find contract | |
450 | cannot find enabled team. The teams do not have enough details for a certain number of transactions | There are no suitable details/There are no details for a suitable amount - contact the support responsible for the bank details |
451 | Internal transaction already processing | |
452 | Payment expired | |
453 | Fraud detected | |
454 | User or team contract not found | |
455 | Unable to transfer external transaction | |
456 | Unable to find economic model | |
457 | Wrong transaction amount | |
458 | Blocked card exception | |
459 | Wallet not found | |
460 | No outbound transactions in pool | |
461 | Pay the existing payments, then ask for the next ones! | |
463 | balance_id not found by user_id | |
464 | Bank detail is duplicated | |
465 | Only one merchant and one team should be | |
466 | Wrong trc20 address | |
467 | Wrong type | |
468 | Internal transaction can't be accept without hash | |
469 | Title length not more than | |
470 | Already existing hash | |
471 | Not valid hash | |
472 | User with such name already exists | |
Could not validate credentials, token expired or not yet valid | you need to update the token (this is done every 2-3 days, but not more often, so as not to overload the system) |
FAQ
Question | Answer |
---|---|
1) In what format do the dates come in response to the authorization request? | In Epoch format (i.e. in seconds) |
2) In which case does the callback come? | The callback is triggered when a transaction is created, or when its status changes to accept or close. You can also ask the admin to resend the callback. |
3) When should tag_id/tag_code be used? How to determine the values of these parameters? | Required field, intended for separating payment methods: default – from card to card (type = card) account – by account number (type = account) deeplink – SberPay (types = [account, phone]) or T-Pay (types = [cross-border-phone, phone]), only available in payment forms interbank – interbank (type = phone) cross-border – cross-border (type = cross-border-phone) |
4) How can you get status "accept" on a test environment? | To change the transaction status to accept or close, it is necessary to contact the admin. |
5) What is meant by interbank? How do we determine it at the stage of request formation? | Interbank means a transaction between 2 different banks, you should use type = phone and tag_id = interbank. 1. for inbound transactions: you will be given the details of any bank for transaction by phone number from any bank. 2. for outbound transactions: the transaction will be made using the phone number details to the bank from any available details that you specify during creating the transaction. This means that if type = phone, you need to use tag_id = interbank, and if it is an outbound transaaction, you must to specify bank |
6) Is it possible to automatically send a transactional list with statuses for the past day to the mail? | It is not sent to the email. The export is available in the personal account under the "Main" section, where you can select the required dates and export the transaction list. You can also request the list from the admin. |
7) The balance from the deposits immediately goes to the payouts and can be used | The balance for deposits and pay out is the same, and it can be used immediately (it is calculated in USDT) |
8) Can the user change the payment amount to a higher/lower amount during the transfer process? | No, user cannot. If the user sends the wrong amount, you will submit a dispute, and we will adjust the amount on our side. After that, you will receive a callback with the new amount. On our side, this is a manual process, while you will receive an automatic response. The response time from the moment you submit the dispute to our reply is 30 minutes, provided no further investigation is needed. |
9) At the request of the balance: in the documentation, one parameter is specified in the response, and a whole set comes in the postman . do we need to process them all or only trust_balance? | You only need to process the trust_balance. |
10) List of banks | You should ask SUPPORT for the list of banks |
11) Is there an anti-fraud and what are its conditions? | blocking by payer_id in case of 8 pending orders |
12) Commission | usdt without commission = amount / exchange_rate usdt with commission = merchant_trust_change |
13) Is it possible for a merchant to request a payment to the sbp for personal use | You can only make withdrawals using USDT in the personal account. |
14) To avoid 450 at the beginning of integration | There are no suitable details/There are no details for a suitable amount - contact the support responsible for the bank details |
15) Where to apply for a deposit? | in the wallet section |
16) What IP addresses can callbacks come from? | You should ask SUPPORT for the list of addresses |
17) What does a minus mean in the merch balance window? | the limit of trust by which the merchant can go into negative territory |
18) When is the balance recalculated? | After the first transaction with a final status (accept or close) |
19) What is the list of geo | RUB/AZN/UZS/KGS/TJS/KZT |
20) Is it possible to split the balance of two tokens that currently have a shared balance? | Yes, if the balance is 0 |
21) What do the statuses 'accept' and 'close' mean? | Status of the transaction is always pending After pending status must become close -(status occurs if the client does not pay, or if he pays late) or accept ( if the client has paid in time) |
22) Are the values of PASSWORD and API_KEY used for both the Payment Page and H2H, or will they be different? | The same ones are used |