# Основные принципы
# Схема взаимодействия

# Запросы
# Точки входа
Точки входа для тестового (sandbox) и боевого (production) окружения одинаковы.
Mandarin определяет окружение по аутентификационным данным (а именно, по значению секретного ключа Secret).
Точка входа для создания транзакций
Используется для всех основных операций (например, для приема платежей и выплат на карту).
POST https://secure.mandarinpay.com/api/transactions
Точка входа для токенизации карт
Используется только для токенизации карт.
POST https://secure.mandarinpay.com/api/card-bindings
Точка входа для упрощенной идентификации
Процесс идентификации значительно отличается от остальных и описан на отдельной странице. При этом используется стандартный для Mandarin способ аутентификации.
POST https://secure.mandarinpay.com/api/personidentification
Точка входа для Роутинга
Решение для маркетплейсов Mandarin Роутинг также значительно отличается от остальных.
Для тестового и боевого окружения используются различные точки входа. При этом нужно использовать соответствующие аутентификационные данные (значения секретного ключа Secret для тестового и боевого окружений разные).
Боевое окружение (prod)
POST https://api.mandarinpay.com/v1/...
Тестовое окружение (stage)
POST https://api-sandbox.mandarinpay.com/v1/...
Способ аутентификации при этом тоже стандартный для продуктов Mandarin.
# Аутентификация запросов
Аутентификация запросов происходит за счет авторизационной строки, которая передается в параметре заголовка 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хх | Параметры, переданные клиентом, некорректны (отсутствие нужного формата, неверно сформированный заголовок и т.д.). |
5хх | Внутренняя ошибка на стороне Mandarin (довольно редкий случай). |
# Параметры ответов
| Параметр | Обязателен | Описание |
|---|---|---|
| id | Да | Идентификатор созданной операции или токен карты |
| userWeblink | Нет | Ссылка для перенаправления пользователя при работе с платежной страницей |
| jsOperationId | Нет | Идентификатор операции для использования с Mandarin Custom Pay |
| error | Нет | Текстовое описание ошибки |
Каждый вызов API имеет ассоциируемый с ним идентификатор, который называется ID транзакции и передается в синхронном ответе как значение параметра id. Для запроса токенизации он является токеном карты, а для запроса платежа/выплаты его называют ID транзакции. Он также присутствует в составе callback-уведомления в качестве значения поля transaction (для платежей/выплат) или card_binding (для токенизаций).
ID транзакции (его также называют ID платежа) также доступен в таблице транзакций в личном кабинете (opens new window) и в интерфейсе HeartBeat.

СОВЕТ
При обращении в Cлужбу поддержки (opens new window) по вопросам с конкретной транзакцией, сообщите ее ID транзакции! Это существенно ускорит получение ответа.
После получения синхронного ответа могут быть три варианта действий:
- Для использования платежной страницы
Перенаправить пользователя по ссылке, полученной в качествеuserWebLink(подробнее) - Для использования встраиваемой формы Mandarin Custom Pay
Использовать значение изjsOperationIdв качествеoperationId(подробнее) - Дальнейшие действия не требуются
В этом случае в синхронном ответе будет получен только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).

- Вставьте тело
callbackв поле (1); - Вставьте
secretв поле (2); - Значение
signбудет рассчитано автоматически в поле (3).
# Параметры уведомлений
Content-Type для асинхронных уведомлений принимает значение application/x-www-urlencoded.
Уведомления высылаются на адрес, который был передан в соответствующем запросе в опциональном параметре urls.callback.
Если параметр не был передан, то используется адрес, который был указан в личном кабинете на закладке Интеграция.
ВАЖНО!
Количество параметров в callback-уведомлении может меняться. Могут добавляться новые параметры. Кроме того, в каждом уведомлении присутствует "соль" (параметр и значение со случайными данными).
Поэтому важно не хардкодить набор параметров!
Перечень и описание параметров, передаваемых в составе callback-уведомления
Параметр object_type хранит в себе тип: transaction (Платеж / Выплата) или card_binding(Токенизация карты). В зависимости от его значения, меняется набор других параметров!
| Параметр | Обязателен | Описание |
|---|---|---|
| 16797d04-d688-4a55-8190-861224243701 | Да | Соль (UUID для названия и для значения параметра генерируются случайным образом). |
| 3dsecure | Нет | Индикатор подтверждения платежа с помощью ввода кода 3-D Secure. |
| action | Нет | Действие (платеж pay или выплата payout), актуально только для транзакций. |
| callbackUrl | Нет | Адрес для отправки callback. |
| card_binding | Нет | Токен карты в системе, актуален только для токенизаций. |
| card_expiration_month | Нет | Месяц срока действия карты. |
| card_expiration_year | Нет | Год срока действия карты. |
| card_holder | Нет | Владелец карты (в формате URL-encoded). |
| card_info_bank | Нет | Название банка-эмитента карты (в формате URL-encoded). |
| card_info_country | Нет | Страна банка-эмитента карты (в формате ISO 3166-1 alpha-3 (opens new window)). Например, RUS. |
| card_info_type | Нет | Название международной платежной системы карты. Например, mastercard. |
| 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. |
| destinationWallet | Нет | id аккаунта получателя. Только для Роутинга. |
| Нет | Email пользователя. | |
| error_code | Нет | Код ошибки. Отсутствие кода не гарантирует успешность операции! |
| error_description | Нет | Описание ошибки. |
| gw_channel | Нет | Название канала для перевода средств. |
| gw_id | Нет | ID канала для перевода средств. |
| initial_hold_amount | Нет | Сумма авторизации, обязательна только для токенизаций. |
| merchantId | Да | ID мерчанта. |
| metadata_* | Нет | Параметры, переданные в объекте metadata в составе запроса на оплату или токенизацию. Имеют префикс metadata_. |
| object_type | Да | Тип объекта (платеж/выплата transaction или токенизация binding). |
| orderActualTill | Нет | Срок резервирования товара/услуги. После указанной даты оплата будет невозможна. |
| orderId | Да | Уникальный номер заказа в вашей системе. |
| payment_system | Нет | Константа mandarinpayv1, поле будет убрано в следующих версиях. |
| price | Нет | Сумма платежа, обязательна только для транзакций. |
| returnUrl | Нет | Адрес магазина для переадресации по окончанию операции. |
| sourceWallet | Нет | id аккаунта отправителя. Только для Роутинга. |
| 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=03917&email=sadukin%40mail.ru&orderActualTill=2021-02-12%2010%3A54%3A23Z&price=11040&action=pay&customName0=%D0%9D%D0%BE%D0%BC%D0%B5%D1%80%20%D0%B4%D0%BE%D0%B3%D0%BE%D0%B2%D0%BE%D1%80%D0%B0&customValue0=AK-247%2F0001-2021%2F1&customName1=%D0%9A%D0%BE%D0%BC%D0%B8%D1%81%D1%81%D0%B8%D1%8F&customValue1=289.15&customer_fullName=%20%20&customer_phone=%2B79189271304&customer_email=sadykin%40mail.ru&transaction=60a186c112e24b90ad839bb7bc65a9ff&object_type=transaction&status=success&payment_system=mandarinpayv1&cb_processed_at=2021-02-11T10%3A56%3A03.5789615Z&card_number=403841XXXXXX6022&cb_customer_creditcard_number=403841XXXXXX6022&card_holder=RUSLAN%20SADYKOV&card_expiration_year=23&card_expiration_month=05&gw_channel=open_way4&3dsecure=true&gw_id=39104278&metadata_first_param=p1&metadata_second_param=p2&transaction_rrn=718791158493&d000d97e-a0db-4e56-9460-6934e4bec050=4d3bb82f-fd4f-43c6-b809-2aec91e0de8a&sign=b53587e838d028cdc702cd5f59c22b8f132325f541181beb56514dd63f0dace9
Пример callback-уведомления о токенизации полных карточных данных
merchantId=1&card_binding=abbd431d-fb01-4bf9-9eb9-773b794c2df9&card_holder=RUSLAN%20MALYGIN&card_number=427638XXXXXX3811&card_expiration_year=2023&card_expiration_month=11&object_type=card_binding&status=success&initial_hold_amount=1&3dsecure=true&gw_id=39104403&card_info_country=RUS&card_info_type=mastercard&card_info_bank=SBERBANK%20OF%20RUSSIA&metadata_first_param=p1&metadata_second_param=p2&orderId=1147710&f9d6c9d1-f4d4-4a3e-8ccf-9421eb483792=0ac5dff9-7aea-4d2f-90ac-c16d730cf2a1&sign=dcc6c824310da7796888497d0537ddf9e320accdb9a00656723dd1f948fbd324
Пример callback-уведомления о токенизации со статусом payout-only
merchantId=1&card_binding=abbd431d-fb01-4bf9-9eb9-773b794c2df9&card_holder=RUSLAN%20MALYGIN&card_number=427638XXXXXX3811&card_expiration_year=2023&card_expiration_month=11&object_type=card_binding&status=payout-only&initial_hold_amount=1&metadata_first_param=p1&metadata_second_param=p2&orderId=1147710&f9d6c9d1-f4d4-4a3e-8ccf-9421eb483792=0ac5dff9-7aea-4d2f-90ac-c16d730cf2a1&sign=bb6d322474e64381f46e3c71c042d3749924a001d4a6ce5b33778ac2e5467072
Пример callback-уведомления о выплате с использованием токена карты
merchantId=1&orderId=8399235e616537a&email=sadukin%40mail.ru&orderActualTill=2021-02-22%2010%3A59%3A48Z&price=5000&action=payout&customer_fullName=%20%20&customer_phone=%2B79316537426&customer_email=sadukin%40mail.ru&transaction=85b79213245143c8a6032ef589a7069d&object_type=transaction&status=success&payment_system=mandarinpayv1&cb_processed_at=2021-02-20T10%3A59%3A52.9419268Z&card_number=220220XXXXXX4398&cb_customer_creditcard_number=220220XXXXXX4398&gw_channel=open_way4&transaction_rrn=199141256754&gw_id=39348488&c9742db9-6c45-4890-9c07-131997788bb7=6cbe0860-a643-43cd-8410-bc8ed6a64811&sign=9c97a77fbd4dbfc63d5862e5947ea11acd3697896df1eb71b4459c14988d5816
Пример 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&gw_id=39104021&709b674c-1f5e-424d-841e-1244d7b71041=9ee4b553-f961-4da9-b9dc-0924c0260d33&sign=a63189b75147a8bd2326baaacdd482d902206b5b6fe6de5f0df464e698b47912
Примеры проверки 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 суток, или до получения ответа об успешной обработке (в зависимости от того, что наступит раньше).