Notificări pe Callback URL
Merchant-ul va primi notificări pe Callback URL cu răspunsul final al plății, ce conține starea tranzacției și detalii relevante (ex. qrStatus
, payId
, amount
, etc).
Pe baza acestor notificări, Merchant-ul trebuie să asigure livrarea serviciului sau produsului către Cumpărător.
Se consideră că notificarea a fost recepționată cu succes dacă serverul Merchant-ului răspunde cu codul HTTP 200 OK.
Structura notificării (Exemplu)
{
"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="
}
Parametrii notificării
result
object
Obiect rezultat răspuns
result.qrId
string(guid)
Identificator unic QR
result.extensionId
string(guid)
Identificator extensie QR
result.qrStatus
string(enum)
Stare QR. Valori posibile: Activ, Plătit
result.payId
string(guid)
Identificator unic plată
result.referenceId
string(15)
RRN serviciu plăți instant
result.orderId
string(100)
Identificator comandă partea comerciantului
result.amount
number(decimal)
Sumă plată
result.commission
number(decimal)
Comision plată
result.currency
string(enum)
Moneda plată. Valori posibile: MDL Format: ISO 4217
result.payerName
string(200)
Nume prescurtat plătitor. Ex: „John D.”
result.payerIban
string(200)
IBAN plătitor (Număr internațional cont bancar)
result.executedAt
string(datetime)
Marcă temporală executare plată. Format: ISO 8601-1:2019 (ex., „2029-10-22T10:32:28+03:00”)
result.terminalId
string(100)
Id terminal, furnizat de bancă
signature
string
Semnătură validare notificare
Validarea semnăturii
Pentru a verifica integritatea și autenticitatea datelor primite, semnătura (signature
) din obiectul result
trebuie validată utilizând următorul algoritm:
Toate câmpurile din obiectul
result
trebuie sortate în ordine alfabetică, cu excepția câmpuluisignature
. Sortarea trebuie să fie insensibilă la majuscule/minuscule.Câmpurile care au valoarea
null
sau șirul gol (""
) sunt complet ignorate în procesul de generare a semnăturii, ca și cum nu ar exista.Câmpurile de tip sumă (
amount
,commission
) se formatează cu exact două zecimale (ex:0.50
,2.31
) înainte de concatenare.Valorile câmpurilor rămase se concatenează folosind caracterul două puncte (
:
) ca separator, în ordinea sortată.La finalul șirului concatenat se adaugă cheia de semnătură (Signature Key), disponibilă în setările proiectului din platforma maibmerchants.
Din șirul rezultat se generează un hash în format binar folosind algoritmul SHA-256.
Hash-ul binar este apoi codificat în format Base64 (sau alt format specificat în documentația oficială QR MIA).
Semnătura generată se compară cu valoarea câmpului
signature
primit în notificare.
Dacă valorile coincid, semnătura este considerată validă, iar datele sunt autentice și intacte.
Exemplu pentru validarea semnăturii
phpCopyEdit<?php
$key = "signature-key-from-project-settings"; // Signature Key obținută din maibmerchants
// Preluăm conținutul JSON primit pe 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'];
// Scoatem semnătura din datele de validat
unset($dataResult['signature']);
// Sortăm alfabetic câmpurile din obiectul result
uksort($dataResult, 'strcasecmp');
// Funcție recursivă de concatenare a valorilor cu separatorul ':'
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); // eliminăm ultimul separator
}
// Construim șirul de semnătură
$signString = implodeRecursive(':', $dataResult) . ':' . $key;
// Generăm hash SHA256 binar
$hash = hash('sha256', $signString, true);
// Codificăm hash-ul în Base64
$signatureCalculated = base64_encode($hash);
// Comparăm semnătura calculată cu cea primită
if ($signatureCalculated === $signatureReceived) {
http_response_code(200);
echo "Signature is valid.";
// Procesați datele tranzacției aici
} else {
http_response_code(400);
echo "Signature is invalid.";
}
} else {
http_response_code(400);
echo "No signature provided.";
}
Recomandări
Asigurați-vă că serverul vostru este accesibil de pe IP-urile maib pentru a primi notificările.
Răspundeți cu cod HTTP 200 OK doar după ce ați verificat cu succes semnătura.
În caz de erori sau semnătură invalidă, răspundeți cu un cod diferit de 200 pentru a forța retrimiterea notificării.
Last updated