# Основные принципы

# Схема взаимодействия

Diagram

# Запросы

# Точки входа

Точки входа для тестового (sandbox) и боевого (production) окружения одинаковы. Mandarin определяет окружение по аутентификационным данным (а именно, по значению секретного ключа Secret).

Важно использовать TLS не ниже 1.2 (запросы с TLS 1.0 или 1.1 будут отклоняться).

Точка входа для создания транзакций

Используется для всех основных операций (например, для приема платежей и выплат на карту).

POST https://secure.mandarinpay.com/api/transactions

Точка входа для токенизации карт

Используется только для токенизации карт.

POST https://secure.mandarinpay.com/api/card-bindings

Точка входа для упрощенной идентификации

Процесс идентификации значительно отличается от остальных и описан на отдельной странице. При этом используется стандартный для Mandarin способ аутентификации.

POST https://secure.mandarinpay.com/api/personidentification

# Аутентификация запросов

Аутентификация запросов происходит за счет авторизационной строки, которая передается в параметре заголовка X-Auth.

Значение X-Auth формируется по следующему шаблону:
merchantId-SHA256(merchantId-requestId-secret)-requestId, где:

  • merchantId – MID, указанный в личном кабинете.

  • requestId – уникальный номер запроса. Для обеспечения уникальности рекомендуем использовать текущий таймстамп в миллисекундах, либо набор байт, сгенерированный криптографически-надёжным генератором случайных чисел.

  • secret – Secret, указанный в личном кабинете.

API-запросы без заголовка или с некорректным заголовком, в том числе c некорректным X-Auth, будут отклонены без создания транзакций.

Примеры расчета X-Auth

<?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

Альтернативный способ аутентификации - Basic auth (opens new window). Не рекомендуем использовать его, особенно для запросов по выплатам на карту. В качестве логина используется значение merchantId, в качестве пароля - значение Secret.

# Параметры запросов

Content-Type для запросов принимает значение application/json.

Параметры запросов для приема платежей, токенизации и выплат на банковские карты описаны в отдельном разделе.

# Синхронные ответы

# HTTP-коды

Mandarin использует стандартные HTTP-коды статуса для индикации успешности или неуспешности API-запросов.

Код Описание
2хх Запрос обработан.
4хх Параметры, переданные клиентом, некорректны (отсутствие нужного формата, неверно сформированный заголовок и т.д.). Например, 401 при ошибке авторизации.
5хх Внутренняя ошибка на стороне Mandarin (довольно редкий случай).

# Параметры ответов

Параметр Обязателен Описание
id Да Идентификатор созданной операции или токен карты
userWeblink Нет Ссылка для перенаправления пользователя при работе с платежной страницей
jsOperationId Нет Идентификатор операции для использования с Mandarin Custom Pay
error Нет Текстовое описание ошибки

Каждый вызов API имеет ассоциируемый с ним идентификатор, который называется ID транзакции и передается в синхронном ответе как значение параметра id. Для запроса токенизации он является токеном карты, а для запроса платежа/выплаты его называют ID транзакции. Он также присутствует в составе callback-уведомления в качестве значения поля transaction (для платежей/выплат) или card_binding (для токенизаций).

ID транзакции (его также называют ID платежа) также доступен в таблице транзакций по ссылке в личном кабинете (opens new window) и в интерфейсе HeartBeat.

Transaction ID

СОВЕТ

При обращении в Cлужбу поддержки (opens new window) по вопросам с конкретной транзакцией, сообщите ее ID транзакции! Это существенно ускорит получение ответа.

После получения синхронного ответа могут быть три варианта действий:

  1. Для использования платежной страницы
    Перенаправить пользователя по ссылке, полученной в качестве userWebLink (подробнее)
  2. Для использования встраиваемой формы Mandarin Custom Pay
    Использовать значение из jsOperationId в качестве operationId (подробнее)
  3. Дальнейшие действия не требуются
    В этом случае в синхронном ответе будет получен только id.

Ответ в случае успешного создания транзакции (200 ОК)

{
	"id": "43913ddc000c4d3990fddbd3980c1725",
	"userWebLink": "https://secure.mandarinpay.com/Pay?transaction=0eb51e74-e704-4c36-b5cb-8f0227621518",
	"jsOperationId": "9874694yr87y73e7ey39ed80"
}

Ответ в случае успешной токенизации (200 ОК)

{
	"id": "0eb51e74-e704-4c36-b5cb-8f0227621518",
	"userWebLink": "https://secure.mandarinpay.com/CardBindings/New?id=0eb51e74-e704-4c36-b5cb-8f0227621518",
	"jsOperationId": "binding-4994591t5-194t694159t-43t5345"
}

Ответ в случае, если транзакция не создана (400 Bad request)

{
	"error": "Invalid request"
}

# Асинхронные уведомления о статусе (callbacks)

# Аутентификация уведомлений

Для подтверждения того, что уведомление пришло именно от системы Mandarin, а также того факта, что данные, переданные в уведомлении, не были искажены, необходимо проверять значение параметра sign.

Поле sign представляет из себя хэш SHA256 от значений всех параметров уведомления, отсортированных по алфавиту и значения secret, разделённых символом -.

ОБРАТИТЕ ВНИМАНИЕ

Для проверки sign, все параметры уведомления должны быть отсортированы в алфавитном порядке с использованием стандартного алгоритма сортировки вашего языка программирования.

Для проверки корректности расчета значения sign можете воспользоваться специальной утилитой (opens new window).

Sign Calculator UI

  • Вставьте тело callback в поле (1);
  • Вставьте secret в поле (2);
  • Значение sign будет рассчитано автоматически в поле (3).

# Параметры уведомлений

Content-Type для асинхронных уведомлений принимает значение application/x-www-urlencoded.

Уведомления высылаются в виде POST-запроса на адрес, который был передан в соответствующем запросе в опциональном параметре urls.callback. Если параметр не был передан, то для отправки POST-запроса используется адрес, который был указан в личном кабинете на закладке Интеграция.

ВАЖНО!

Количество параметров в callback-уведомлении может меняться. Могут добавляться новые параметры. Кроме того, в каждом уведомлении присутствует "соль" (параметр и значение со случайными данными).
Поэтому важно не хардкодить набор параметров!

Перечень и описание параметров, передаваемых в составе callback-уведомления

Параметр object_type хранит в себе тип: transaction (Платеж / Выплата) или card_binding(Токенизация карты). В зависимости от его значения, меняется набор других параметров!

Параметры в POST-запросе передаются в формате x-www-form-urlencoded.

Параметр Обязателен Описание
16797d04-d688-4a55-8190-861224243701 Да Соль (UUID для названия и для значения параметра генерируются случайным образом).
3dsecure Нет Индикатор подтверждения платежа с помощью ввода кода 3-D Secure.
action Нет Действие (платеж pay, выплата payout, возврат reversal, предавторизация preauth ), актуально только для транзакций.
callbackUrl Нет Адрес для отправки callback.
card_binding Нет Токен карты в системе, актуален только для токенизаций.
card_expiration_month Нет Месяц срока действия карты.
card_expiration_year Нет Год срока действия карты.
card_holder Нет Владелец карты (в формате URL-encoded).
card_id Нет Хэш от полного номера карты (для токенизаций и платежей).
card_info_bank Нет Название банка-эмитента карты (в формате URL-encoded).
card_info_country Нет Страна банка-эмитента карты (в формате ISO 3166-1 alpha-3 (opens new window)). Например, RUS.
card_info_type Нет Название международной платежной системы карты. Например, mastercard.
card_info_card_type Нет Тип карты. Например, Debit.
card_info_product_name Нет Название продукта карты. Например, Visa Rewards.
card_info_product_code Нет Код продукта карты. Например, N1.
card_info_issuing_bank Нет Банк эмитент. Например, Tinkoff Bank.
card_info_iso_country_a3 Нет Страна выпуска карты. Например, RUS.
card_number Нет Номер карты (маскированный).
cb_customer_creditcard_number Нет Номер карты (маскированный), поле будет убрано в следующих версиях.
cb_processed_at Нет Дата и время обработки операции.
customer_fullName Нет ФИО пользователя.
customer_email Нет Адрес email пользователя.
customer_phone Нет Телефон пользователя.
customName0 Нет Имя первого параметра (в формате URL-encoded), переданного в массиве customValues в составе запроса на оплату или токенизацию. Может существовать до 8 параметров: customName0, customName1, ... , customName7.
customValue0 Нет Значение первого параметра (в формате URL-encoded), переданного в массиве customValues в составе запроса на оплату или токенизацию. Может существовать до 8 параметров: customValue0, customValue1, ... , customValue7.
email Нет Email пользователя.
error_code Нет Код ошибки. Отсутствие кода не гарантирует успешность операции!
error_description Нет Описание ошибки.
gw_channel Нет Название канала для перевода средств.
gw_id Нет ID канала для перевода средств.
initial_hold_amount Нет Сумма авторизации, обязательна только для токенизаций.
merchantId Да ID мерчанта.
metadata_* Нет Параметры, переданные в объекте metadata в составе запроса на оплату или токенизацию. Имеют префикс metadata_.
object_type Да Тип объекта (платеж/выплата transaction или токенизация card_binding).
orderActualTill Нет Срок резервирования товара/услуги. После указанной даты оплата будет невозможна.
orderId Да Уникальный номер заказа в вашей системе.
payment_system Нет Константа mandarinpayv1, поле будет убрано в следующих версиях.
price Нет Сумма платежа, обязательна только для транзакций.
returnUrl Нет Адрес магазина для переадресации по окончанию операции.
status Да Статус операции: success, failed, payout-only. Только статус success однозначно указывает на успешность операции!
transaction Нет ID транзакции в системе. Актуален только для транзакций.
transaction_rrn Нет RRN транзакции.
sign Да Подпись для аутентификации (всегда последним).

# Параметры в объекте metadata

Запрос на токенизацию или оплату может включать в себя объект metadata, который содержит список ваших параметров с любыми названиями и любыми значениями, которые будут отправлены в callback-уведомлении. При этом на платежной странице они не будут показаны пользователю.

Например, для запроса на токенизацию:

POST https://secure.mandarinpay.com/api/card-bindings
{
	"customerInfo": {
		"email": "user@example.com",
		"phone": "+79001234567"
	},
	"metadata": {
		"first_param": "p1",
		"second_param": "p2"
	}
}

Подробнее про использование объекта metadata в запросах можно прочитать в главе Сохранение дополнительной информации.

Callback-уведомление, наряду с остальными параметрами, будет включать в себя параметры из запроса, но с префиксом metadata_:

metadata_first_param=p1&metadata_second_param=p2

# Примеры уведомлений

Пример callback-уведомления об оплате

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

Пример callback-уведомления о токенизации полных карточных данных

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

Пример callback-уведомления о токенизации со статусом payout-only

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

Пример callback-уведомления о выплате с использованием токена карты

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

Пример callback-уведомления о выплате с использованием номера карты

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

Пример callback-уведомления об авторизации при двухстадийной оплате

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

Пример callback-уведомления о возврате

merchantId=1&orderId=11&email=test%40mail.ru&orderActualTill=2024-03-10%2004%3A55%3A08Z&price=999.00&action=reversal&customer_fullName=%20%20&customer_phone=%2B79690000099&customer_email=test%40mail.ru&transaction=2f0006a3ed00000fae177e29aba7bb00&object_type=transaction&status=success&payment_system=mandarinpayv1&cb_processed_at=2024-03-08T05%3A01%3A17.7798144Z&gw_channel=psb_direct&transaction_rrn=401117511111&gw_id=111111143&card_id=d8632ed1111148b37a11111010611111&433a288b-de02-461c-aac6-9d328311111=e93e7a57-1111-1111-1111-37ae0da11111&sign=85b5a211111b2b9482111118c5035311111f856a111a83c89ee111116cbfc8

Примеры проверки sign

<?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]));
}

# Повторная отправка уведомлений

В качестве ответа, обозначающего, что callback успешно обработан на вашей стороне, необходимо вернуть в Mandarin ответ с HTTP-кодом 200 и телом OK.

ВАЖНО!

Любой другой ответ будет означать, что callback не обработан. В этом случае Mandarin повторяет отправку callback-запроса в течение 3 суток, или до получения ответа об успешной обработке (в зависимости от того, что наступит раньше).

# Лимиты для запросов к API

Ограничения и лимиты для запросов к API:

  • На рекуррентные платежи: не более 10 запросов в секунду, и не более 300 запросов в минуту.

  • На возвраты: максимальная сумма возврата, и максимальное количество возвратов (устанавливается по заявке клиента).

  • На платежи: лимит на покупку (устанавливается по заявке клиента).