> For the complete documentation index, see [llms.txt](https://help.unitpay.ru/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.unitpay.ru/payments/payment-handler.md).

# Настройка HTTP-уведомлений

Входящие HTTP-уведомления используются при взаимодействии по API UnitPay. Через эти запросы вы можете:

* проверить заказ до оплаты;
* подтвердить, что заказ существует и может быть оплачен;
* автоматически выдать товар, оказать услугу или зачислить баланс после успешного списания;
* получать уведомления об ошибках по платежу.

{% hint style="info" %}
Важно: если URL для уведомлений не указан, callback-запросы не отправляются, а платеж считается успешным автоматически.
{% endhint %}

<figure><img src="/files/s5H150O0ppLESopOdi1c" alt=""><figcaption></figcaption></figure>

## Требования к URL для уведомлений

Партнер может указать любой технически корректный URL. Домен обработчика не обязан совпадать с доменом сайта проекта.

### Что считается корректным URL

URL для уведомлений будет сохранен, если:

* используется протокол `http` или `https`;
* указан валидный домен;

#### Примеры корректных URL

* `https://example.com/payment-handler`
* `https://api.example.com/unitpay/callback`
* `http://merchant-service.net/pay`
* `https://xn--e1afmkfd.xn--p1ai/handler`

#### Примеры некорректных URL

* `ftp://example.com/callback` — недопустимый протокол
* `https://127.0.0.1/callback` — IP-адрес вместо домена
* `https://user:password@example.com/callback` — встроенные данные авторизации

## Как это работает

Обычно сценарий такой:

1. Покупатель начинает оплату.
2. Unitpay может отправить `check`, чтобы проверить заказ до списания.
3. После успешного списания Unitpay отправляет `pay`.
4. Если на одном из этапов возникла ошибка, может прийти `error`.
5. Для платежей с преавторизацией сначала может прийти `preauth`.

{% hint style="success" %}
Важно: при `preauth` деньги только заблокированы. Товар, услугу или баланс нужно выдавать только после успешного списания.
{% endhint %}

{% hint style="warning" %}
Важно: `error` не всегда означает окончательный статус. После `error` в некоторых случаях позже может прийти `pay`.
{% endhint %}

## Что нужно реализовать на своей стороне

Ваш обработчик должен:

* принимать GET-запросы от Unitpay;
* проверять [IP-адрес отправителя](/book-of-reference/ip-addresses.md);
* проверять `signature`;
* сверять `orderSum` и `orderCurrency` с данными заказа;
* на этапе `check` только проверять заказ;
* на этапе `pay` выдавать товар, оказывать услугу или зачислять баланс;
* корректно обрабатывать повторные запросы;
* возвращать JSON в нужном формате.

{% hint style="warning" %}
**Важно:** `unitpayId` — это уникальный идентификатор платежа в Unitpay. Если запрос с тем же `unitpayId` приходит повторно, не обрабатывайте платеж заново: не выдавайте товар повторно, не оказывайте услугу повторно и не зачисляйте баланс еще раз.
{% endhint %}

## Методы

### **`CHECK`**&#x20;

Запрос на проверку заказа до оплаты.

На этом этапе нужно убедиться, что:

* заказ существует;
* сумма и валюта совпадают;
* заказ можно оплатить;
* после успешной оплаты услугу можно оказать.

{% hint style="warning" %}
**Важно:** на этапе `check` не нужно выдавать товар, оказывать услугу или зачислять баланс.
{% endhint %}

{% hint style="info" %}
По умолчанию на новом проекте запрос `CHECK` выключен. Чтобы использовать его, включите эту опцию в настройках проекта.
{% endhint %}

### **`PAY`**&#x20;

Уведомление об успешном списании средств.

Именно на этом этапе нужно:

* выдать товар;
* оказать услугу;
* зачислить баланс;
* сохранить результат обработки платежа.

Если на этом этапе ваш сервер вернет ошибку, платеж получит статус **«Не завершен»**. После устранения проблемы платеж можно повторно провести из интерфейса статистики.

{% hint style="info" %}
Важно: деньги зачисляются на баланс партнера независимо от ответа вашего обработчика.
{% endhint %}

{% hint style="warning" %}
Важно: обработка pay должна быть идемпотентной. Повторный запрос не должен приводить к повторной выдаче товара или повторному зачислению.
{% endhint %}

### **`PREAUTH`**

Уведомление для [платежей с преавторизацией](/payments/pre-authorization-payments.md). Это значит, что деньги успешно заблокированы, но еще не списаны окончательно.

{% hint style="success" %}
Важно: не выдавайте товар и не оказывайте услугу при получении preauth. Делать это нужно только после успешного списания.
{% endhint %}

### **`ERROR`**

Уведомление об ошибке на одном из этапов платежа.

Если ошибка вызвана пустым или некорректным ответом сервера партнера, запрос `error` может не отправляться.

{% hint style="warning" %}
**Важно:** `error` не всегда является конечным статусом. После него иногда может прийти `pay`.
{% endhint %}

## Формат запроса

Unitpay отправляет GET-запрос на URL вашего обработчика.

Пример:

```json
GET https://ваш_url_для_уведомлений

method               = check
params[account]      = userId
params[date]         = 2025-10-01 12:32:00
params[paymentType]  = card
params[projectId]    = 123456
params[payerSum]     = 10.00
params[payerCurrency]= RUB
params[signature]    = 9bdf52a4830779a1383ac24f1b3ed054
params[orderSum]     = 10.00
params[orderCurrency]= RUB
params[unitpayId]    = 1234567890
params[test]         = 0
```

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

<table><thead><tr><th width="190.44441731770831">Параметр</th><th width="150.2222900390625">Значение</th><th>Описание</th></tr></thead><tbody><tr><td><strong>method</strong></td><td>string</td><td>Тип запроса: <code>check</code>, <code>pay</code>, <code>preauth</code>, <code>error</code></td></tr><tr><td><strong>unitpayId</strong> </td><td>число</td><td>Внутренний номер платежа в UnitPay</td></tr><tr><td><strong>projectId</strong> </td><td>число</td><td>ID проекта в UnitPay</td></tr><tr><td><strong>account</strong> </td><td>string</td><td>Идентификатор пользователя или заказа в вашей системе</td></tr><tr><td><strong>payerSum</strong></td><td>число</td><td>Сумма списания с лицевого счета абонента</td></tr><tr><td><strong>sum</strong></td><td>число</td><td>Сумма списания с лицевого счета абонента (дополнительное значение)</td></tr><tr><td><strong>ip</strong></td><td>string</td><td>IP-адрес плательщика (с которого инициировано создание платежа)</td></tr><tr><td><strong>isPreauth</strong></td><td>число</td><td>Признак преавторизации: 1 — да, 0 — нет</td></tr><tr><td><strong>payerCurrency</strong></td><td>string</td><td>Валюта списания с лицевого счета абонента по стандарту ISO 4217 (RUB, BYN, EUR, USD)   </td></tr><tr><td><strong>profit</strong></td><td>число</td><td>Ваш доход с данного платежа, в рублях</td></tr><tr><td><strong>paymentType</strong></td><td>string</td><td><a href="/pages/-M9y0PdOWFK4DxzzyaSC">Код платежной системы</a></td></tr><tr><td><strong>orderSum</strong></td><td>число</td><td><p>Сумма заказа</p><p><strong>Обязательно сверяйте поступившее значение с оригинальной суммой заказа</strong></p></td></tr><tr><td><strong>orderCurrency</strong></td><td>string</td><td><p>Валюта заказа по стандарту ISO 4217 (RUB, BYN, EUR, USD)</p><p><strong>Обязательно сверяйте поступившее значение с оригинальной валютой заказа</strong></p></td></tr><tr><td><strong>date</strong></td><td>string</td><td>Дата платежа в формате YYYY-mm-dd HH:ii:ss (например 2024-10-01 12:32:00)</td></tr><tr><td><strong>errorMessage</strong></td><td>string</td><td>Детализация ошибки (только для метода error)</td></tr><tr><td><strong>test</strong></td><td>число</td><td>Признак тестового режима: 1 — тест, 0 — реальный платеж</td></tr><tr><td><strong>3ds</strong></td><td>число</td><td>Признак наличия 3-DS для операций по карте, флаг присутствует при PAY уведомлениях</td></tr><tr><td><strong>subscriptionId</strong></td><td>число</td><td>Идентификатор подписки, может приходить в <code>preauth</code> и <code>pay</code></td></tr><tr><td><strong>signature</strong></td><td>string</td><td>Цифровая подпись. Образуется как <code>sha256(method + "{up}" + params + "{up}" + secretKey)</code>, <br>где <strong>sha256</strong> - метод шифрования;<br><strong>"{up}"</strong> - разделитель параметров в хеш-функции;<br><strong>method</strong> - тип вызова (check, pay, error);<br><strong>params</strong> - значения параметров из массива params, объединенные разделителем "{up}". Все параметры должны быть предварительно отсортированы по ключу, в склейке не участвует параметр signature;<br><strong>secretKey</strong> - секретный ключ проекта (доступен в личном кабинете);<br><br>Пример расчета подписи для запроса <a href="http://partnerurl/?method=check%20&#x26;%20params[b]=bob&#x26;params[c]=sam&#x26;params[a]=tod"><strong>http://partnerUrl?method=check &#x26; params[b]=bob &#x26; params[c]=sam &#x26; params[a]=tod</strong></a> и секретного ключа <strong>"a1b1c1d1"</strong><br><br><strong><code>sha256</code></strong><code> ("check{up}tod{up}bob{up}sam{up}a1b1c1d1")</code></td></tr></tbody></table>

### Успешный ответ

Если запрос обработан успешно, верните:

```json
{
    "result": {
        "message": "Запрос успешно обработан"
    }
}
```

| Параметр    | Значение | Описание                             |
| ----------- | -------- | ------------------------------------ |
| **message** | string   | Текстовый статус выполнения запроса. |

### Ошибочный ответ

Если запрос не может быть обработан, верните:

```json
{
    "error": {
        "message": "Описание ошибки"
    }
}
```

<table data-header-hidden><thead><tr><th width="200.44441731770831">Парамтер</th><th width="186.3333740234375">Значение</th><th>Описание</th></tr></thead><tbody><tr><td><strong>message</strong></td><td>string</td><td><p>Информация с описанием ошибки формирования платежа.</p><p>При использовании формы оплаты текст из параметра "message" будет показан плательщику. </p></td></tr><tr><td><strong>locale</strong></td><td>string</td><td><p>Настраивает язык вводной части. </p><p><strong>Возможные значения</strong>: "en" или "ru". По умолчанию "ru"</p><p></p><p>Например: "Магазин отклонил платеж: <em>причина блокировки</em>", где "Магазин отклонил платеж:" - вводная часть. "<em>Причина блокировки</em>" - значение параметра message</p></td></tr></tbody></table>

### Частые ошибки интеграции

Чаще всего проблемы возникают из-за того, что:

* не проверяется `signature`;
* не проверяются IP-адреса;
* не сверяются `orderSum` и `orderCurrency`;
* товар выдается на этапе `check`, а не на этапе `pay`;
* сервер возвращает некорректный JSON.
