# Payouts
TESTING
To test payouts to cards and/or via the Fast Payment System (FPS), use the data from the Testing.
# Payments to card
IMPORTANT!
The orderId value must be unique within successful payout operations.
In case you did not receive a synchronous response with the HTTP code 200 and id of the operation when you sent the payout request, or received a response with an HTTP code different from 200 (for example, 502 or 504) and want to request the same payout again, the same orderId number must be used.
This way, if the original request was still successful, or is in progress, you will receive a response with an HTTP code of 400 and a "Duplicate order id" error, and no re-payout will be made. In case the initial request was not successful - the operation will be carried out in the standard mode.
Following these instructions will allow you to avoid double payout operations on the card in case of any network problems between your application server and Mandarin server.
We also recommend you to set the timeout in 600 seconds when sending requests via API.
For example, the original payout request contained an orderId equal to "5f2fdcf6-0b78-4dd7-be9f-212c7c058001".
If it completed successfully, a second request for payout with the same orderId value will return an error in the synchronous response. The payout will not be created again.
Response in case of an attempt to create a payout with an already existing orderId value (400 Bad Request)
{
"error": "Duplicate order id 5f2fdcf6-0b78-4dd7-be9f-212c7c058001 found for incomplete payout transaction",
"errorCode": -2
}
# Card token payout
As part of this API call, the target block is added to the standard call, where id of the previously successful [full-card-data] tokenization(./api_tokenization.md#tokenization-of-full-card-data) or card number is passed as the card value.
The transaction is performed in asynchronous mode. As a result of the request, you will get a payment id synchronously, and then you will get a callback-notification asynchronously.
| Parameter | Mandatory | Parameter | Mandatory |
|---|---|---|---|
| payment | Yes | target | Yes |
| payment.action | yes | target.card | yes |
| payment.orderId | Yes | customValues[] | No |
| payment.price | Yes | customValues[].name | No |
Synchronous response and asynchronous callback-notification can contain a wider set of parameters compared to the example.
Request
POST https://secure.mandarinpay.com/api/transactions
{
{ "payment": {
{ "action": { "payout",
"orderId": "your_unique_order_id",
"price": "1000.00"
},
{ "customerInfo": {
{ "email": "user@example.com",
"phone": "+79001234567"
},
{ "target": {
"card": "0eb51e74-e704-4c36-b5cb-8f0227621518"
},
{ "customValues": [
{ "name": "first parameter to save and show", "value": "p1"},
{ "name": "second parameter to save and show", "value": "p2"}
],
{ "metadata": {
"first_parameter_to_callback_and_not_to_show": "p1",
"second_parameter_to_callback_and_not_to_show": "p2"
},
{ "urls": {
{ "callback": "http://...",
"return": "http://..."
}
}
Response in case of successful transaction creation (200 OK)
{
"id": "43913ddc000c4d3990fddbd3980c1725"
}
Response in case the transaction was not created (400 Bad request)
{
"error": "Invalid request"
}
Response in case of an attempt to create a payout with an already existing orderId value (400 Bad Request)
{
"error": "Duplicate order id 5f2fdcf6-0b78-4dd7-be9f-212c7c058001 found for incomplete payout transaction",
"errorCode": -2
}
# Payout using a card number
As part of this query, a block target is added to the standard call, where as a value of knownCardNumber the number of the card to which the transfer is made.
The orderId value must be unique within successful withdrawal transactions. If you did not receive a successful callback and want to request the same payout again, we recommend using the same orderId number. This will prevent a duplicate payout if the original payout was made but the successful callback did not reach you.
The transaction is performed in asynchronous mode. As a result of the request, you will get a payment id synchronously, and then you will get a callback-notification asynchronously.
| Parameter | Mandatory | Parameter | Mandatory |
|---|---|---|---|
| payment | Yes | target | Yes |
| payment.action | Yes | target.knownCardNumber | Yes |
| payment.orderId | Yes | customValues[] | No |
| payment.price | Yes | customValues[].name | No |
| customerInfo | Yes | customValues[].value | No |
| customerInfo.email | Yes | metadata | No |
| customerInfo.phone | Yes | urls | No |
Synchronous response and asynchronous callback-notification can contain a wider set of parameters compared to the example.
Request
POST https://secure.mandarinpay.com/api/transactions
{
{ "payment": {
{ "action": { "payout",
"orderId": "your_unique_order_id",
"price": "1000.00"
},
{ "customerInfo": {
{ "email": "user@example.com",
"phone": "+79001234567"
},
{ "target": {
"knownCardNumber": "4012888888881881"
},
{ "customValues": [
{ "name": "first parameter to save and show", "value": "p1"},
{ "name": "second parameter to save and show", "value": "p2"}
],
{ "metadata": {
"first_parameter_to_callback_and_not_to_show": "p1",
"second_parameter_to_callback_and_not_to_show": "p2"
},
{ "urls": {
{ "callback": "http://...",
"return": "http://..."
}
}
Response in case of successful transaction creation (200 OK)
{
"id": "43913ddc000c4d3990fddbd3980c1725"
}
Response in case the transaction was not created (400 Bad request)
{
"error": "Invalid request"
}
Response in case of an attempt to create a payout with an already existing orderId value (400 Bad Request)
{
"error": "Duplicate order id 5f2fdcf6-0b78-4dd7-be9f-212c7c058001 found for incomplete payment transaction",
"errorCode": -2
}
# Payout with card entry on the payment page
The transaction is performed in asynchronous mode. As a result of the request, you will get a payment id synchronously, and then you will get a callback-notification asynchronously.
| Parameter | Mandatory | Parameter | Mandatory |
|---|---|---|---|
| payment | Yes | customValues[] | No |
| payment.action | yes | customValues[].name | no |
| payment.orderId | Yes | customValues[].value | No |
| payment.price | Yes | metadata | No |
| customerInfo | Yes | urls | No |
| customerInfo.email | Yes | urls.callback | No |
| customerInfo.phone | Yes | urls.return | No |
Synchronous response and asynchronous callback-notification can contain a wider set of parameters compared to the example.
Request
POST https://secure.mandarinpay.com/api/transactions
{
{ "payment": {
{ "action": { "payout",
"orderId": "your_unique_order_id",
"price": "1000.00"
},
{ "customerInfo": {
{ "email": "user@example.com",
"phone": "+79001234567"
},
{ "customValues": [
{ "name": "first parameter to save and show", "value": "p1"},
{ "name": "second parameter to save and show", "value": "p2"}
],
{ "metadata": {
"first_parameter_to_callback_and_not_to_show": "p1",
"second_parameter_to_callback_and_not_to_show": "p2"
},
{ "urls": {
{ "callback": "http://...",
"return": "http://..."
}
}
Response in case of successful transaction creation (200 OK)
{
"id": "43913ddc000c4d3990fddbd3980c1725",
"userWebLink": "https://secure.mandarinpay.com/Pay?transaction=0eb51e74-e704-4c36-b5cb-8f0227621518"
}
Response in case the transaction was not created (400 Bad request)
{
"error": "Invalid request"
}
Response in case of an attempt to create a payout with an already existing orderId value (400 Bad Request)
{
"error": "Duplicate order id 5f2fdcf6-0b78-4dd7-be9f-212c7c058001 found for incomplete payout transaction",
"errorCode": -2
}
# Payments via SBP
PLEASE NOTE!
In accordance with the requirements of NSPK No. 802-P and the Standards of the Financial Security Service (FSPS), it is prohibited to make bulk requests for personal data by sending a borrower's phone number and receiving their full name in response. Therefore, to avoid blocking SBP services by the NSPK, we recommend verifying the borrower's full name and account holder's name after completing scoring procedures and before signing the loan agreement.
Fast Payment System (FPS) is a service that allows you to instantly transfer funds from an account using the recipient’s phone number.
Features of the SBP payment service:
To connect the SBP payment service, you must send a request to Support Service (opens new window) or to the client manager;
Payments are made indicating the phone number and full name of the recipient, as well as selecting a bank from the list of banks;
Data binding for subsequent recurring payments and auto-debits via SBP is not currently provided.
# Getting a list of banks
In order to transfer a bank, it is necessary to obtain its data bankId and bankBic from the list of banks.
[Authorization - XAuth](https://docs.mandarin.io/public/api_principles.html#%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8 %D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE% D1%81%D0%BE%D0%B2).
| Parameter | Type | Mandatory | Description |
|---|---|---|---|
| bankName | string | No | The name of the bank by which you want to filter, you can specify an incomplete name, the method will return all suitable options. Case is ignored when filtering |
Request for a list of banks:
GET https://secure.mandarinpay.com/api/sbp/banks/
Response if the request is successfully created:
{
"banks": [
{
"bankId": "100000000111",
"bankName": "Сбербанк",
"bankBic": "044525225"
},
{
"bankId": "100000000008",
"bankName": "Альфа-Банк",
"bankBic": "044525593"
},
{
"bankId": "100000000010",
"bankName": "Промсвязьбанк",
"bankBic": "044525555"
}
]
}
Request for a specific bank:
GET https://secure.stage.psp.io/api/sbp/banks?bankName=Сбербанк
Response if the request is successfully created:
{
"banks": [
{
"bankId": "100000000111",
"bankName": "Сбербанк",
"bankBic": "044525225"
}
]
}
If banks are not found, the response will be returned:
{
"banks": []
}
# Creating a payment with a full name
As part of this API call, a target block is added to the standard call, where the bank parameters bankId and bankBic are passed as the sbp value.
The transaction is carried out asynchronously. As a result of the request, you will receive payment id synchronously, and then callback-notification will be sent asynchronously.
| Parameter | Mandatory |
|---|---|
| customerInfo | Yes |
| customerInfo.phone | Yes |
| customerInfo.email | Yes |
| customerInfo.firstName | Yes |
| customerInfo.lastName | Yes |
| customerInfo.middleName | Yes, if the recipient's passport contains a middle name |
| payment | Yes |
| payment.action | Yes |
| payment.orderId | Yes |
| payment.price | Yes |
| target | Yes |
| target.sbp | Yes |
| target.sbp.bankId | Yes |
| target.sbp.bankBic | Yes |
Synchronous response and asynchronous callback-notification can contain a wider set of parameters compared to the example.
Request
POST https://secure.mandarinpay.com/api/transactions
{
"customerInfo": {
"phone": "+79111111111",
"email": "test@test.com",
"firstName": "Peter",
"lastName": "Ivanov",
"middleName": "Sergeyevich"
},
"payment": {
"orderId": "your_unique_order_id",
"price": "10.00",
"action": "payout"
},
"target": {
"sbp": {
"bankId": "100000000111",
"bankBic": "044525225"
}
}
}
Response in case of successful transaction creation (200 OK)
{
"id": "43913ddc000c4d3990fddbd3980c1725"
}
Response if the transaction is not created (400 Bad request)
{
"error": "Invalid request"
}
Response in case of an attempt to create a payment with an already existing orderId value (400 Bad Request)
{
"error": "Duplicate order id 5f2fdcf6-0b78-4dd7-be9f-212c7c058001 found for incomplete payout transaction",
"errorCode": -2
}
# Creating a payout without a Full name
Within the framework of this API call, a target block is added to the standard call, where the bank parameters bankId and bankBic are passed as the value of sbp.
The transaction is carried out in asynchronous mode. As a result of the request, you will receive a synchronous id of the payment, and then an asynchronous callback-notification.
Payments without a Full name require confirmation or cancellation after the transaction is created and the bank confirms the successful status.
| Parameter | Mandatory |
|---|---|
| customerInfo | Yes |
| customerInfo.phone | Yes |
| customerInfo.email | Yes |
| payment | Yes |
| payment.action | Yes |
| payment.orderId | Yes |
| payment.price | Yes |
| target | Yes |
| target.sbp | Yes |
| target.sbp.bankId | Yes |
| target.sbp.bankBic | Yes |
A synchronous response and an asynchronous callback notification can contain a wider set of parameters than the example.
Request
POST https://secure.mandarinpay.com/api/transactions
{
"customerInfo": {
"phone": "+79111111111",
"email": "test@test.com"
},
"payment": {
"orderId": "your_unique_order_id",
"price": "10.00",
"action": "payout"
},
"target": {
"sbp": {
"bankId": "100000000111",
"bankBic": "044525225"
}
}
}
Response in case of successful transaction creation (200 OK)
{
"id": "43913ddc000c4d3990fddbd3980c1725"
}
Response if the transaction is not created (400 Bad request)
{
"error": "Invalid request"
}
Response in case of an attempt to create a payment with an already existing orderId value (400 Bad Request)
{
"error": "Duplicate order id 5f2fdcf6-0b78-4dd7-be9f-212c7c058001 found for incomplete payout transaction",
"errorCode": -2
}
# Checking the request status without full name
Status verification request
After creating a payment without a full name, you must check the status and confirm the payment only after the status is success.
GET https://secure.mandarinpay.com/api/sbp/43913ddc000c4d3990fddbd3980c1725/status
Response in case of successful transaction creation (200 OK)
{
"status": "success",
"fio": "Peter Ivanovich S."
}
Response in case the recipient is being verified by the bank
{
"status": "pending",
"fio": null
}
# Payment confirmation without full name
Request for payment confirmation
After receiving a successful status, you must confirm the payment in order for the funds to be transferred to the recipient.
POST https://secure.mandarinpay.com/api/sbp/43913ddc000c4d3990fddbd3980c1725/confirm
Response in case of successful transaction creation (200 OK)
{
"id": "43913ddc000c4d3990fddbd3980c1725"
}
# Check balance for payouts
This request allows you to check the balance of the account from which mass payouts are made.
Request
GET https://secure.mandarinpay.com/api/account/channels/{name}/balance
You must pass the parameter from the table below as the value of {name}:
| Parameter | Parameter description |
|---|---|
| openbank_direct | To inquire about the balance of a current account opened with PJSC Bank FC Otkritie (Otkritie) |
| psb_direct | To inquire about the balance of the current account opened in PSB (PSB) |
Sample code to check the balance
<?php
$merchantId=0;
$secret='******';
$reqid = time() ."_". microtime(true) ."_". rand();
$hash = hash("sha256", $merchantId ."-". $reqid ."-". $secret);
$auth= $merchantId ."-".$hash . $reqid;
$url_transaction = "https://secure.mandarinpay.com/api/account/channels/openbank_direct/balance";
$ch = curl_init($url_transaction);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"X-Auth:" . $auth
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
var_dump($result);
?>
# Getting transaction status
The API method makes it possible to obtain its status, as well as information about the card, using the transaction identifier.
Authorization - XAuth (opens new window).
Request:
operationId - payment id (opens new window).
GET https://secure.mandarinpay.com/api/operations/{operationId}
Sample answer:
{
"operationType": "Transaction",
"state": "Success",
"card": {
"cardNumber": "519261XXXXXX3242",
"cardHolder": "CARD HOLDER",
"expireDate": "25/01",
"cardId": "a3a5c49e1385e5096d05075d636f7baf",
"country": "TUR",
"productName": "Standard Mastercard Card",
"productCode": "MCS",
"brand": "mastercard",
"bank": "ODEA BANK A.S.",
"cardType": "Credit"
}
}
Response options:
| Parameter | Description |
|---|---|
| operationType | operation type, transaction/binding |
| state | Operation status: success, failed, payout-only, pendingExecution/none/unknown - the operation has not been completed and is being processed (reconciliation with the acquiring bank may be required). Only the success status clearly indicates the success of the operation! |
| cardNumber | masked card number |
| cardHolder | card holder |
| expireDate | card expiration date |
| cardId | unique hash of the full card number |
| country | country of issue |
| productName | card product/card category |
| productCode | card product/card category code |
| brand | card payment system |
| bank | bank that issued the card |
| cardType | card type (debit/credit) |