# Basic principles

# Pattern of interaction

Diagram

# 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).

Transaction ID

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:

  1. To use the payment page
    Redirect the user to the link received as userWebLink (detail)
  2. To use Mandarin Custom Pay inline form
    Use value from jsOperationId as operationId (detail)

  3. In this case only id 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.

Sign Calculator UI

  • 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.
email 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).