Уведомления по Callback URL
Мерчант будет получать уведомления на Callback URL с окончательным ответом по платежу, который содержит статус транзакции и соответствующие детали (например, qrStatus
, payId
, amount
, etc).
На основании этих уведомлений мерчант должен обеспечить доставку услуги или товара покупателю.
Уведомление считается успешно полученным, если сервер мерчанта отвечает кодом HTTP 200 OK.
Структура уведомления (Пример)
{
"result": {
"qrId": "789e0123-f456-7890-a123-456789012345",
"extensionId": "40e6ba44-7dff-48cc-91ec-386a38318c68",
"qrStatus": "Paid",
"payId": "123e4567-e89b-12d3-a456-426614174000",
"referenceId": "QR000123456789",
"orderId": "789e0123-e89b-45d6-b789-426614174111",
"amount": 100.50,
"commission": 2.50,
"currency": "MDL",
"payerName": "John D.",
"payerIban": "MD24AG000225100013104168",
"executedAt": "2029-10-22T10:32:28+03:00",
"terminalId": "P011111"
},
"signature": "5wHkZvm9lFeXxSeFF0ui2CnAp7pCEFSNmuHYFYJlC0s="
}
Параметры уведомления
result
object
Объект результата ответа
result.qrId
string(guid)
Уникальный идентификатор QR
result.extensionId
string(guid)
Идентификатор расширения QR
result.qrStatus
string(enum)
Статус QR. Возможные значения: Активен, Оплачен
result.payId
string(guid)
Уникальный идентификатор платежа
result.referenceId
string(15)
RRN сервиса мгновенных платежей
result.orderId
string(100)
Идентификатор заказа со стороны продавца.
result.amount
number(decimal)
Сумма платежа
result.commission
number(decimal)
Комиссия платежа
result.currency
string(enum)
Валюта платежа. Возможные значения: MDL Формат: ISO 4217
result.payerName
string(200)
Аббревиатура имени плательщика. Например: "John D."
result.payerIban
string(200)
IBAN плательщика (Международный номер банковского счета)
result.executedAt
string(datetime)
Метка времени выполнения платежа Формат: ISO 8601-1:2019 (например, "2029-10-22T10:32:28+03:00")
result.terminalId
string(100)
Идентификатор терминала, предоставленный банком
signature
string
Подпись проверки уведомления
Проверка подписи
Для проверки целостности и подлинности полученных данных необходимо проверить подпись (signature
) из объекта result
, используя следующий алгоритм:
Все поля в объекте
result
должны быть отсортированы в алфавитном порядке, за исключением поляsignature
. Сортировка должна быть нечувствительной к регистру.Поля со значением
null
или пустой строкой (""
) полностью игнорируются при формировании подписи, как будто они отсутствуют.Поля, содержащие суммы (
amount
,commission
), форматируются с точностью до двух знаков после запятой (например:0.50
,2.31
) до объединения.Значения оставшихся параметров объединяются в строку, используя двоеточие (
:
) в качестве разделителя, в отсортированном порядке.В конец полученной строки добавляется ключ подписи (Signature Key), доступный в настройках проекта в платформе maibmerchants.
Из полученной строки формируется бинарный хеш по алгоритму SHA-256.
Полученный хеш кодируется в формате Base64 (или другом, указанном в официальной документации QR MIA).
Сгенерированная подпись сравнивается со значением поля
signature
, полученного в уведомлении.
Если значения совпадают, подпись считается действительной, а данные — подлинными и неизменёнными.
Пример проверки подписи
<?php
$key = "signature-key-from-project-settings"; // Signature Key obtained from maibmerchants
// Get the JSON content received on the Callback URL
$json = file_get_contents('php://input');
$data = json_decode($json, true);
if (isset($data['result']['signature'])) {
$signatureReceived = $data['result']['signature'];
$dataResult = $data['result'];
// Remove the signature from the data to be validated
unset($dataResult['signature']);
// Alphabetically sort the fields in the result object
uksort($dataResult, 'strcasecmp');
// Recursive function to concatenate values with ':' separator
function implodeRecursive($separator, $array) {
$result = '';
foreach ($array as $item) {
if (is_array($item)) {
$result .= implodeRecursive($separator, $item) . $separator;
} else {
$result .= (string)$item . $separator;
}
}
return substr($result, 0, -1); // remove the last separator
}
// Build the signature string
$signString = implodeRecursive(':', $dataResult) . ':' . $key;
// Generate binary SHA256 hash
$hash = hash('sha256', $signString, true);
// Encode the hash in Base64
$signatureCalculated = base64_encode($hash);
// Compare the calculated signature with the received one
if ($signatureCalculated === $signatureReceived) {
http_response_code(200);
echo "Signature is valid.";
// Process the transaction data here
} else {
http_response_code(400);
echo "Signature is invalid.";
}
} else {
http_response_code(400);
echo "No signature provided.";
}
Рекомендации
Убедитесь, что ваш сервер доступен с IP-адресов maib для получения уведомлений.
Отвечайте кодом HTTP 200 OK только после успешной проверки подписи.
В случае ошибок или недействительной подписи отвечайте кодом, отличным от 200, чтобы инициировать повторную отправку уведомления.
Last updated