---
title: Вебхуки
description: Вебхуки Coinetic: настройка, проверка подписи HMAC, дедупликация, повторы, порядок доставки, типы событий и ротация секрета.
url: https://coinetic.money/ru/docs/webhooks/
lang: ru
---

# Вебхуки

Coinetic сообщает вашему серверу об изменениях счёта POST-запросом. Вебхук — сигнал «посмотри счёт», а не доказательство оплаты.

## Настройка

- Кабинет → «Ключи и вебхуки» → «Добавить». URL — только `https://` на публичный адрес и порт 443 (в песочнице — ещё `http://localhost`).
- Секрет endpoint-а показывается один раз. До 5 активных endpoint-ов: каждое событие уходит на все.

## Запрос

```http
POST /webhooks/coinetic HTTP/1.1
Content-Type: application/json
User-Agent: cryptopay-webhooks/1
X-Webhook-Id: evt_3f9c…
X-Webhook-Timestamp: 1760000000
X-Webhook-Signature: v1=5d1e…

{"id":"evt_3f9c…","type":"invoice.paid","created_at":"2026-10-12T15:04:05Z","livemode":true,"data":{"invoice_id":"inv_x7k2…","order_id":"ORDER-1001","status":"paid","paid_amount":"49990000"}}
```

`X-Webhook-Id` одинаков при повторах. При ротации секрета в `X-Webhook-Signature` две подписи через запятую. Технические имена (`cryptopay-webhooks/1`) — исторические, менять их у себя не нужно.

## Проверка подписи

```
expected = "v1=" + hex(HMAC-SHA256(webhook_secret, X-Webhook-Timestamp + "." + raw_body))
```

- Возьмите **сырое тело** — байты до JSON-парсинга.
- Проверьте, что `X-Webhook-Timestamp` отличается от текущего времени не больше чем на 5 минут.
- Разбейте `X-Webhook-Signature` по запятой. Подпись верна, если **любая** часть совпадает с ожидаемой (сравнение за постоянное время).
- Не совпало — ответьте `401` и ничего не делайте.

Эталон: секрет `whsec-0123456789abcdef0123456789abcdef`, timestamp `1760000000`, тело `{"id":"evt_1","type":"invoice.paid"}` → `v1=aceeb56215ba09e7a2923d48f89afb8331f422f2d0a8cf60f76fef69fe06a6a4`.

## Обработка

```
проверить подпись → дедупликация по X-Webhook-Id → GET /v1/invoices/{invoice_id}
→ обновить заказ по статусу из API (выдача — один раз) → ответить 2xx
```

- **Дедупликация.** Одно событие может прийти несколько раз. Храните обработанные `X-Webhook-Id`; флаг «выдано» ставьте в той же транзакции, что и выдачу.
- **Отвечайте быстро** — до 10 секунд. Долгую работу отправьте в очередь.
- **Коды ответа:** `2xx` — принято; `410 Gone` — эту доставку не повторять; любой другой код (включая `3xx` — редиректы не выполняются) или таймаут — повтор.
- Игнорируйте незнакомые поля и типы событий — список будет расти.

Готовые обработчики на четырёх языках — в [быстром старте](https://coinetic.money/ru/docs/quickstart/#webhook).

## Повторы

10 с → 30 с → 2 мин → 10 мин → 30 мин → 1 ч → 3 ч ×7 → 1 ч, с небольшим разбросом. Последняя попытка — примерно через сутки. Неудачную доставку можно отправить снова: кабинет → «Вебхуки» → «Переотправить».

## Порядок

События **одного счёта** доставляются на endpoint по порядку: следующее не уходит, пока предыдущая доставка ещё ждёт повтора. Завершилась она успешно или нет — дальше идут следующие. Поэтому опирайтесь на статус из `GET /v1/invoices/{id}`, а не на последовательность событий. События разных счетов независимы.

## Типы событий

| Событие | Когда |
| --- | --- |
| `invoice.detected` | Платёж виден в сети |
| `invoice.confirming` | Платёж в блоке, идут подтверждения |
| `invoice.paid` | Оплачено и подтверждено — можно выдавать (после перепроверки). `data.late: true` — стейблкоин пришёл после срока и зачтён автоматически |
| `invoice.overpaid` | Оплачено с излишком |
| `invoice.underpaid` | Подтверждено меньше нужного |
| `invoice.awaiting_payment` | Счёт снова ждёт оплату (например, после реорга единственного платежа) |
| `invoice.expired` | Срок вышел без оплаты |
| `invoice.late_payment` | Оплата волатильным активом после срока |
| `invoice.manual_review` | Платёж на проверке AML |
| `invoice.payment_held` | Платёж задержан AML (карантин) |
| `invoice.reorged` | Блок с платежом откатился, статус пересчитан (например, `paid` → `confirming`) |
| `invoice.payment_after_close` | Платёж пришёл на уже закрытый счёт: заказ не оплачивает, доступен к возврату |
| `invoice.cancelled` | Счёт закрыт без оплаты исполнением возврата |
| `refund.sent` | Возврат исполнен, в `data.refund` — сумма, адрес и `tx_hash` |

События биллинга (`billing.*`) — о счетах на комиссию платформы: выставлен, оплачен, просрочен, приостановка и её снятие.

> **Цифровые товары и `invoice.reorged`.** Реорг после `paid` редок, но бывает. Если товар выдаётся мгновенно — подпишитесь на это событие и передавайте такие случаи в поддержку.

## Ротация секрета

Кабинет → «Сменить секрет»: Coinetic начинает подписывать **обоими** секретами.

- Добавьте новый секрет на сервер (принимайте оба).
- Нажмите «Завершить ротацию» — старый удалится.
- Уберите старый секрет с сервера.
