# Basic principles
# Pattern of interaction
# Inquiries
# Entry points
The entry points for the sandbox and production environments are the same.
Mandarin determines the environment by the authentication data (the value of the secret key Secret
).
It is important to use TLS 1.2 or higher (requests with TLS 1.0 or 1.1 will be rejected).
Entry point for creating transactions
Used for all basic operations (e.g. accept payments and payouts to card).
POST https://secure.mandarinpay.com/api/transactions
Entry point for card tokenization
Used only for card tokenization.
POST https://secure.mandarinpay.com/api/card-bindings
Entry point for simplified identification
The identification process is significantly different and is described on separate page. This uses the Mandarin standard authentication method.
POST https://secure.mandarinpay.com/api/personidentification
# Request authentication
The authentication of requests is done by the authorization string, which is passed in the header parameter X-Auth
.
The X-Auth
value is formed according to the following pattern:
`merchantId-SHA256(merchantId-requestId-secret)-requestId', where:
merchantId
- the MID specified in personal account.requestId
- unique request number. To ensure uniqueness, we recommend using the current timestamp in milliseconds, or a set of bytes generated by a cryptographically-reliable random number generator.secret
- Secret, specified in personal account.
API requests without a header or with an invalid header, including invalid X-Auth
, will be rejected without creating transactions.
X-Auth calculation examples
<?php
function gen_auth($merchantId, $secret)
{
$reqid = time() ."_". microtime(true) ."_". rand();
$hash = hash("sha256", $merchantId ."-". $reqid ."-". $secret);
return $merchantId ."-".$hash . $reqid;
}
?>
public static string GenerateXAuth(string secret)
{
var requestId = Guid.NewGuid().ToString("N");
string hash;
using (var sha256 = System.Security.Cryptography.SHA256.Create())
hash = BitConverter.ToString(sha256.ComputeHash(Encoding.UTF8.GetBytes($"{merchantId}-{requestId}-{secret}")).ToLower().Replace("-", "");
return $"{merchantId}-{hash}-{requestId}";
}
DEPRECATED
An alternative authentication method is Basic auth (opens new window). We do not recommend to use it, especially for card payment requests. As a login value merchantId
is used, as a password - value Secret
.
# Query parameters
The Content-Type
for requests takes the value application/json
.
Query parameters for accepting payments, tokenization and payments to bank cards are described in separate section.
# Synchronized responses
# HTTP codes
Mandarin uses standard HTTP status codes to indicate successful or unsuccessful API requests.
Code | Description |
---|---|
2xxx | request processed. |
4xxx | Parameters sent by the client are incorrect (lack of the correct format, incorrectly formed header, etc.). For example, 401 for an authorization error. |
5xxx | Internal error on Mandarin side (quite rare case). |
# Answer parameters
Parameter | Mandatory | Description |
---|---|---|
id | Yes | The ID of the created transaction or card token |
userWeblink | No | Link to redirect the user when working with the payment page |
jsOperationId | No | Transaction ID for use with Mandarin Custom Pay |
error | no | text description of the error |
Each API call has an identifier associated with it, which is called ID transaction
and is passed in the synchronous response as the value of the id
parameter. For tokenization request it is a card token, and for payment or payout request it is called transactionID
. It is also present in callback
notification as a value of transaction
(for payments/payouts) or card_binding
(for tokenizations) field.
The TransactionID
(also called PaymentID
) is also available in the transaction table via a link in personal cabinet (opens new window) and in the [HeartBeat] interface(./tools.md#monitoring-queries-and-notification-heartbeat).
WARNING
When contacting Helpdesk (opens new window) with questions about a specific transaction, provide its TransactionID
! This will greatly speed up the response.
After receiving a synchronous response, there can be three options:
- To use the payment page
Redirect the user to the link received asuserWebLink
(detail) - To use Mandarin Custom Pay inline form
Use value fromjsOperationId
asoperationId
(detail)
In this case onlyid
will be received in the synchronous response.
Response in case of successful transaction creation (200 OK
)
{
"id": "43913ddc000c4d3990fddbd3980c1725",
"userWebLink": "https://secure.mandarinpay.com/Pay?transaction=0eb51e74-e704-4c36-b5cb-8f0227621518",
"jsOperationId": "9874694yr87y73e7ey39ed80"
}
Response in case of successful tokenization (200 OK
)
{
"id": "0eb51e74-e704-4c36-b5cb-8f0227621518",
"userWebLink": "https://secure.mandarinpay.com/CardBindings/New?id=0eb51e74-e704-4c36-b5cb-8f0227621518",
"jsOperationId": "binding-4994591t5-194t694159t-43t5345"
}
Response in case the transaction was not created (400 Bad request
)
{
"error": "Invalid request"
}
# Asynchronous status notifications (callbacks)
# Notification Authentication
To confirm that the notification came from the Mandarin system and that the data transmitted in the notification was not corrupted, you must check the sign
parameter.
The sign
field is a SHA256
hash of values of all notification parameters, sorted alphabetically and secret
values, separated by -
.
To check sign
, all notification parameters must be sorted alphabetically using your programming language's standard sort algorithm.
:::
You can use special utility (opens new window) to check if the sign
value is calculated correctly.
- Insert the
callback
body in the field (1); - Insert
secret
in field (2); - The
sign
value will be calculated automatically in field (3).
# Notification parameters
The Content-Type
for asynchronous notifications takes the value application/x-www-urlencoded
.
Notifications are sent as a POST request to the address that was passed in the corresponding request in optional parameter urls.callback
.
If the parameter was not passed, the address used to send the POST request is the one that was specified in the [Integration] tab(./tools.md#authentication-data) in the personal area.
IMPORTANT!
The number of parameters in a callback notification can vary. New parameters can be added. In addition, each notification has a "salt" (a parameter and a value with random data).
That's why it's important not to hardcode the parameter set!
List and description of parameters transmitted as part of the callback
notification
Parameter object_type
stores the type: transaction
(Payment / Payment) or card_binding
(Card Tokenization). Depending on its value, the set of other parameters changes!
Parameters in the POST request are passed in the format x-www-form-urlencoded
.
Parameter | Mandatory | Description |
---|---|---|
16797d04-d688-4a55-8190-861224243701 | Yes | Salt (the UUID for the name and for the parameter value are randomly generated. |
3dsecure | No | Payment confirmation indicator with [3-D Secure] code entry(./glossary.md#3-d_secure). |
action | No | Action (payment pay or payment payout ), relevant only for transactions |
callbackUrl | No | The address to send the callback. |
card_binding | No | card token in the system, relevant only for tokenizations. |
card_expiration_month | No | card expiration month. |
card_expiration_year | No | card expiration year. |
card_holder | No | cardholder (in URL-encoded format). |
card_id | No | Hash of full card number (for tokenizations and payments). |
card_info_bank | No | The name of the card issuing bank (in URL-encoded format). |
card_info_country | No | country of the card issuing bank (in ISO 3166-1 alpha-3 (opens new window) format). For example, RUS . |
card_info_type | No | The name of the international payment system of the card. For example, mastercard . |
card_info_card_type | No | The type of card. For example, Debit . |
card_info_product_name | No | The name of the card product. For example, Visa Rewards . |
card_info_product_code | No | The product code of the card. For example, N1 . |
card_info_issuing_bank | No | The issuing bank. For example, Tinkoff Bank . |
card_info_iso_country_a3 | No | The country of issue of the card. For example, RUS . |
card_number | No | card number (masked). |
cb_customer_creditcard_number | No | card number (masked), field will be removed in future versions |
cb_processed_at | No | date and time of operation processing. |
customer_fullName | No | user name. |
customer_email | No | user email address. |
customer_phone | No | user_phone |
customName0 | No | Name of the first parameter (in URL-encoded format) passed in the customValues array as part of a payment or tokenization request. There can be up to 8 parameters: customName0, customName1, . , customName7. |
customValue0 | No | Value of the first parameter (in URL-encoded format) passed in the customValues array as part of a payment or tokenization request. There can be up to 8 parameters: customValue0, customValue1, . , customValue7. |
no | user's email. | |
error_code | No | error code. The absence of a code does not guarantee the success of the operation! |
error_description | No | error description. |
gw_channel | No | The name of the channel to transfer funds. |
gw_id | No | channel ID to transfer funds. |
initial_hold_amount | No | authorization amount, mandatory only for tokenizations. |
merchantId | Yes | merchant ID. |
metadata_* | No | Parameters passed in the metadata object as part of a payment or tokenization request. They are prefixed with metadata_ . |
object_type | Yes | object type (payment/payment transaction or tokenization card_binding ). |
orderActualTill | No | Term for reserving the product/service. Payment will not be possible after the specified date. |
orderId | Yes | A unique order number in your system. |
payment_system | No | constant mandarinpayv1 , the field will be removed in future versions |
price | no | payment amount, mandatory only for transactions. |
returnUrl | No | Store address for redirecting at the end of the operation. |
status | Yes | operation status: success , failed , payout-only . **Only success status unambiguously indicates the success of the operation! |
transaction | No | Transaction ID in the system. Only valid for transactions. |
transaction_rrrn | No | RRN transaction. |
sign | Yes | Sign for authentication (always last). |
# Parameters in the metadata object
A tokenization or payment request can include a metadata
object that contains a list of your parameters with any names and any values that will be sent in the callback notification.
In this case they will not be shown to the user on the payment page.
For example, for a tokenization request:
POST https://secure.mandarinpay.com/api/card-bindings
{
{ "customerInfo": {
{ "email": "user@example.com",
"phone": "+79001234567"
},
{ "metadata": {
"first_param": "p1",
"second_param": "p2"
}
}
You can read more about using the metadata
object in queries in saving additional information.
The Callback
notification, along with the other parameters, will include the parameters from the request, but with the prefix metadata_
:
metadata_first_param=p1&metadata_second_param=p2
# Examples of notifications
Payment callback notification example
merchantId=1&orderId=e75c444d-22b4-4e1c&email=79691112211%40mail.ru&orderActualTill=2024-01-30%2006%3A59%3A28Z&price=100.00&callbackUrl=https%3A%2F%2test.ru%2Fpayment%2F60e70526%2Fe75c444d-22b4-4e1c%2Fpayment%2F&action=pay&customer_fullName=%20%20&customer_phone=%2B79691112211&customer_email=79691112211%40test.ru&transaction=1a79f7d8122048929299a7ee87aed&object_type=transaction&status=failed&payment_system=mandarinpayv1&card_number=220220XXXXXX1111&cb_customer_creditcard_number=220220XXXXXX1111&gw_channel=psb_direct&transaction_rrn=402822221111&error_code=51&error_description=Not%20sufficient%20funds&gw_id=107211111&card_id=7c5d587672909558a075fd11111111&e72d8031-d96f-4d1f-953d-779cb693ad7d=65ce05ec-f35a-4f1f-b00c&sign=b6c39660225e7e4d22b7ce535edc
Example callback notification about tokenization of full card data
card_binding=a7446082-02a4&card_holder=ALEKSANDR%20IVANOV%20&card_number=427605XXXXXX1111&card_expiration_year=2023&card_expiration_month=2&object_type=card_binding&status=success&merchantId=1&initial_hold_amount=1.00000&3dsecure=true&gw_id=1072811&card_id=99bb78de64def70b063c11111&card_info_country=RUS&card_info_type=visa&card_info_bank=SBERBANK&card_info_product_name=Visa%20Classic&card_info_product_code=F&card_info_card_type=Debit&card_info_issuing_bank=SBERBANK&card_info_iso_country_a3=RUS&9870f8a5=8f5b0fe8-a587-4de0ea9808dc&sign=8eada97da58c5287f4b08a2e75dd0fe1111
Example of a callback notification of tokenization with `payout-only' status
card_binding=9b2980ab-6247&card_holder=HALVA%20CARD&card_number=553609XXXXXX1111&card_expiration_year=27&card_expiration_month=1&object_type=card_binding&status=payout-only&merchantId=1&initial_hold_amount=1.00000&3dsecure=true&gw_id=1111&card_id=3e8dd9d3265221111111&card_info_country=RUS&card_info_type=mastercard&card_info_bank=Sovcombank&card_info_product_name=Mastercard%20World%20Card&card_info_product_code=MNW&card_info_card_type=Credit&card_info_issuing_bank=Sovcombank&card_info_iso_country_a3=RUS&0e5d3ca6-=9317d7e6-6d29-4d34-af62-1&sign=e8867ef06f61ab00465336275c5b1111111
Example of a callback notification of a payment using a card token
merchantId=1&orderId=112244&email=test%40mail.ru&orderActualTill=2024-01-30%2007%3A33%3A39Z&price=100&action=payout&customer_fullName=%20%20&customer_phone=%2B7911111111&customer_email=test%40mail.ru&transaction=3d1d4a7c2f794e479e2cdd351111111&object_type=transaction&status=failed&payment_system=mandarinpayv1&gw_channel=psb_direct&transaction_rrn=4028471111111&error_code=51&error_description=Not%20sufficient%20funds&gw_id=107281111&card_id=811d78e08b41ce51e450eb81111111&fe18a06c-e010-4a07-985e-1111111=3bd5e84b-f3f2-41d7-86ed-e994a7336144&sign=91feebac525892a32d8effe11111111
Example of a callback payment notification using a card number
merchantId=1&orderId=9537D957-AC43-4853-AB47-4E39BCFFF3FC&email=sadukin%40mail.ru&orderActualTill=2021-02-22%2010%3A48%3A17Z&price=2000.0&callbackUrl=http%3A%2F%2Fmail.example.com%3A4000%2Fapi%2Fmandarin%2Fpayout%2Fcallback&action=payout&customName0=manager_id&customValue0=E099D738-CED4-48F2-A21C-36C0EA25A549&customName1=dealer_id&customValue1=BD251868-EACA-483D-91F3-954543576F93&customName2=customer_id&customValue2=A54856FA-3A81-4742-AA73-743389D536A9&customer_fullName=%20%20&customer_phone=%2B79273884129&customer_email=sadukin%40mail.ru&transaction=52f1874b9bd846e7ab14c9f96fb9bc17&object_type=transaction&status=success&payment_system=mandarinpayv1&cb_processed_at=2021-02-20T10%3A48%3A22.7232790Z&card_number=546906XXXXXX1568&cb_customer_creditcard_number=546906XXXXXX1568&gw_channel=open_way4&transaction_rrn=105199356489&error_code=51&error_description=Not%20sufficient%20funds&gw_id=39104021&709b674c-1f5e-424d-841e-1244d7b71041=9ee4b553-f961-4da9-b9dc-0924c0260d33&sign=a63189b75147a8bd2326baaacdd482d902206b5b6fe6de5f0df464e698b47912
Example of callback-notification of authorization at two-stage payment
merchantId=1&orderId=11&email=test%40mail.ru&orderActualTill=2024-01-24%2017%3A22%3A24&price=1&callbackUrl=https%3A%2F%2Fwww.test.ru%2Fother%2Fcompany%2Fpaymenthold.php&action=preauth&customName0=tcustomValue0=test&customer_fullName=test&customer_phone=%2B797881111111&customer_email=test%40mail.ru&metadata_inv_id=36&transaction=3c35c083f7eb4bed8373b9341111111&object_type=transaction&status=failed&payment_system=mandarinpayv1&sandbox=false&error_code=888&error_description=Order%20expired&faeef3a9-1095-4513-b6f9-504cf3920c0a=ae7db577-1fac-4154-9a8e-11111111&sign=b57daf7804f7e252235f6901c435ac8f1e10063aba518d034617db31111111
Examples of sign
checks
<?php
function check_sign($secret, $req)
{
$sign = $req['sign'];
unset($req['sign']);
$to_hash = '';
if (!is_null($req) && is_array($req)) {
ksort($req);
$to_hash = implode('-', $req);
}
$to_hash = $to_hash .'-'. $secret;
$calculated_sign = hash('sha256', $to_hash);
return $calculated_sign == $sign;
}
check_sign("123", $_POST);
?>
public static string Calculate(string secret, IDictionary<string, string> values)
{
using (var sha256 = System.Security.Cryptography.SHA256.Create())
return BitConverter.ToString(sha256.ComputeHash(Encoding.UTF8.GetBytes(string.Join("-", values.OrderBy(x => x.Key, StringComparer.Ordinal).Select(x => x.Value)) + "-" + secret)).ToLower().Replace("-", "");
}
public static bool CheckSign(string secret, HttpRequest request)
{
var sign = request.Form["sign"];
if(string.IsNullOrWhiteSpace(sign))
return false;
return sign ==
Calculate(secret, request.Form.Keys.Where(k => k != "sign").ToDictionary(k => k, k => request.Form[k]);
}
# Resend notifications
As a response indicating that the callback has been successfully processed on your side, you should return a response to Mandarin with the HTTP code 200
and the body OK
.
IMPORTANT!
Any other response will mean that the callback has not been processed. In this case, Mandarin will resend the callback request within 3 days, or until receiving a response on successful processing (whichever comes first).
# Limits for API requests
Restrictions and limits for API requests:
For recurring payments: no more than 10 requests per second, and no more than 300 requests per minute.
For refunds: the maximum amount of refunds, and the maximum number of refunds (set by customer's request).
On payments: purchase limit (set at the request of the client).