# Notifications on Callback Url

The Merchant will receive notifications on the Callback URL with the *final response* containing the status of the transaction.

Notifications are sent as HTTPS POST requests with data in JSON format.

Based on these notifications, the Merchant must provide the service/product to the Customer.

**Callback URL** is a mandatory setting for every project opened in **maibmerchants**, but it can also be sent in the request when initiating a payment (*callbackUrl* parameter).

To receive notifications responses from **maib ecomm** following server IP addresses must be allowed in the merchant server firewall: **91.250.245.70 / 91.250.245.71 / 91.250.245.142**

The notification is considered to be processed successfully by the merchant if HTTP 200 OK status returned. Otherwise **maib ecomm** will repeat notification attempts with such time intervals: **10, 60, 300, 600, 3600, 43200, 86400** seconds.

**Example of receiving notifications on Callback URL (PHP)**

```php
<?php
$json = file_get_contents('php://input');
$data = json_decode($json);
```

### Callback signature

In the notification (*final response*) the *signature* parameter will be present to verify the integrity and authenticity of the data.

Signature algorithm:&#x20;

```
signature = Base64(sha256(Implode(Sort(Params) + SignatureKey, ':'))));
```

The **Signature Key** is available after activating the Project in **maibmerchants**.

**Signature validation:**

Example of notification (*final response*) on Callback URL:

```json
{
"result": {
"payId": "f16a9006-128a-46bc-8e2a-77a6ee99df75",
"orderId": "123",
"status": "OK",
"statusCode": "000",
"statusMessage": "Approved",
"threeDs": "AUTHENTICATED",
"rrn": "331711380059",
"approval": "327593",
"cardNumber": "510218******1124",
"amount": 10.25,
"currency": "MDL"
},
"signature": "5wHkZvm9lFeXxSeFF0ui2CnAp7pCEFSNmuHYFYJlC0s="
}
```

1. Sort the data in the ***result*** object according to the alphabetical order of the parameters. Example:

```json
"amount" => 10.25,
"approval" => "327593",
"cardNumber" => "510218******1124",
"currency" => "MDL",
"orderId" => "123",
"payId" => "f16a9006-128a-46bc-8e2a-77a6ee99df75",
"rrn" => "331711380059",
"status" => "OK",
"statusCode" => "000",
"statusMessage" => "Approved",
"threeDs" => "AUTHENTICATED"
```

2. Concatenate parameter values using the "**:**" sign with the ***Signature Key*** appended to the end. Example:

{% code overflow="wrap" %}

```
10.25:327593:510218******1124:MDL:123:f16a9006-128a-46bc-8e2a-77a6ee99df75:331711380059:OK:000:Approved:AUTHENTICATED:8508706b-3454-4733-8295-56e617c4abcf
```

{% endcode %}

3. Generate the hash of this string using the ***SHA256*** function ([binary format](#user-content-fn-1)[^1]). Example:

```
e701e466f9bd945797c52785174ba2d829c0a7ba4210548d9ae1d81582650b4b
```

4. ***Base64*** encode the received hash. Example:

```
5wHkZvm9lFeXxSeFF0ui2CnAp7pCEFSNmuHYFYJlC0s=
```

5. Compare the generated signature with the value of the *signature* parameter in the notification and if they match the signature will be considered valid (the received data is authentic and intact).

### Example of signature validation (PHP)

```php
<?php
$key = "8508706b-3454-4733-8295-56e617c4abcf"; //Signature Key from Project settings

$json = file_get_contents('php://input');
$data = json_decode($json, true);

if (isset($data['signature'])) {
$data_result = $data['result']; // Data from "result" object

function sortByKeyRecursive(array $array) {
    ksort($array, SORT_STRING);
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $array[$key] = sortByKeyRecursive($value);
        }
    }
    return $array;
}

function implodeRecursive($separator, $array) {
    $result = '';
    foreach ($array as $item) {
        $result .= (is_array($item) ? implodeRecursive($separator, $item) : (string)$item) . $separator;
    }

    return substr($result, 0, -1);
}

$sortedDataByKeys = sortByKeyRecursive($data_result); //Sort an array by key recursively
$sortedDataByKeys[] = $key; //Add Signature Key to the end of data array
$signString = implodeRecursive(':', $sortedDataByKeys); // Implode array recursively
$sign = base64_encode(hash('sha256', $signString, true)); // Generate signature 

if ($sign === $data['signature']) // Compare the generated signature with the received signature on Callback URL
{
  echo "Signature is valid!"; // Signature is valid, process the data
} else {
  echo "Signature is invalid!"; // Signature is invalid, reject the request
}
}
```

[^1]: **Attention!** Make sure that your hash function returns an array of bytes, not their representation in HEX.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.maibmerchants.md/e-commerce/notifications-on-callback-url.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
