# События вебхуков

> Обрабатывайте все 18 событий вебхуков Paymos с явным состоянием ресурса и понятной терминальностью.

Paymos публикует 18 типов событий: 9 для инвойсов, 6 для выводов и 3 для платёжных каналов. Подписка настраивается по категории endpoint'а; отдельные события внутри категории не выбираются.

## События инвойсов

| Событие | Значение | Терминальное |
|---------|----------|--------------|
| `invoice.awaiting_payment` | Глубокий реорг удалил все учтённые переводы, и инвойс вернулся к ожиданию оплаты. Первичный переход в ожидание оплаты это событие не создаёт | Нет |
| `invoice.confirming` | Платёж обнаружен и ожидает требуемой финальности блокчейна | Нет |
| `invoice.underpaid_waiting` | Получено меньше ожидаемой суммы, но инвойс ещё может принять доплату | Нет |
| `invoice.paid` | Ожидаемая сумма оплачена | Да |
| `invoice.paid_over` | Получено больше ожидаемой суммы; мерчанту зачисляется вся полученная сумма | Да |
| `invoice.underpaid` | Инвойс перешёл в финальное состояние недоплаты | Да |
| `invoice.expired` | Инвойс истёк без подходящей оплаты | Да |
| `invoice.cancelled` | Мерчант отменил инвойс | Да |
| `invoice.paid_late` | Деньги набрали полную сумму инвойса после того, как он уже закрылся истёкшим или недоплаченным. `data.status` сохраняет терминальное значение, `data.paid_late_at` несёт время отметки (Unix-секунды). Это факт-заметка, а не переход | Нет |

## События выводов

| Событие | Значение | Терминальное |
|---------|----------|--------------|
| `withdrawal.created` | Вывод принят и создан | Нет |
| `withdrawal.processing` | Исходящая транзакция обнаружена в блокчейне, доступен её хеш | Нет |
| `withdrawal.completed` | Исходящая транзакция завершена в блокчейне | Да |
| `withdrawal.failed` | Вывод завершился ошибкой и перешёл в финальное состояние | Да |
| `withdrawal.cancelled` | Вывод отменён до завершения | Да |
| `withdrawal.completion_rewound` | Реорг откатил завершённый вывод, и он снова в пути в статусе `signed`; завершение или ошибку принесёт последующее событие | Нет |

## События платёжных каналов

| Событие | Значение | Терминальное |
|---------|----------|--------------|
| `payment_channel.deposit.confirming` | На адрес канала пришёл перевод, он ждёт требуемой финальности блокчейна | Нет |
| `payment_channel.deposit.reorged` | Реорганизация цепочки отменила транзакцию. Тот же депозит вернётся в confirming, если транзакция снова попадёт в блок | Нет |
| `payment_channel.deposit.confirmed` | Депозит рассчитан, сумма `net` зачислена на баланс | Да |

События об ошибке нет: депозит, отменённый реорганизацией и не вернувшийся в цепочку, просто остаётся в `reorged`.

## Правила обработки

- Маршрутизируйте по точному `event_type`; неизвестный будущий тип безопасно пропускайте и отправляйте на разбор.
- Читайте `data.status` и `data.is_final` из payload, не восстанавливайте состояние только по названию события.
- Не полагайтесь на порядок доставки. Параллельная доставка и retry могут привести более новый снимок ресурса раньше старого.
- Терминальное событие завершает state machine ресурса. Повторная доставка того же `event_id` остаётся дублем, а не новым переходом.
- Дедуплицируйте бизнес-состояние по идентификатору ресурса внутри `data` (`inv_…`, `wdr_…`, `pcd_…`): он одинаков для всех переходов и всех endpoint'ов. `event_id` идентифицирует одну доставку, а не один платёж.

Общая оболочка события и поля ресурсов описаны в [Контракте тела события](/ru/docs/webhooks/payloads.md).
- `invoice.paid_late` — факт рядом с терминальным решением, не переход: по нему нельзя отметить заказ оплаченным, ошибочным или отменённым. Добавьте заметку к заказу (идемпотентно на инвойс) и не меняйте решение.
