Вебхуки Exode доставляют подтверждённые события в ваши внешние сервисы почти в реальном времени и используют повторные попытки с экспоненциальной задержкой (11 → 22 → 44 → 88 → 176 минут), поэтому приёмщик должен быть идемпотентным и быстро отвечать кодами 200-202.
Как Exode доставляет вебхуки
1
Фиксация события
События
UserSignedUp, PaymentCompleted и другие генерируются ядром Exode и попадают в очередь Bull с таймстэмпом и параметрами инициатора.2
Поиск активных эндпоинтов
Затем ядро Exode ищет до пяти активных эндпоинтов в рамках школы/продавца, фильтруя их по выбранному событию.
3
Сбор полезной нагрузки
Для каждого события собираются связанные сущности (пользователь, платеж, доступ и т.д.), формируется
data, общий idempotencyKey и timestamp.4
Отправка и повторные попытки
Тело отправляется POST-запросом с заголовком
signature (HMAC-SHA256) и повторяется до пяти раз, если приёмник не ответил 200-202.Чтобы остановить доставку, установите
active = false у эндпоинта или удалите его.Ограничения и требования
- Для одного продавца/школы можно создать не более пяти эндпоинтов, каждый со своим набором событий.
- Url должен поддерживать HTTPS, принимать
Content-Type: application/jsonи возвращать ответ не позднее 15 секунд. - Секретный ключ генерируется автоматически при создании и хранится в зашифрованном виде.
- Всегда проверяйте
idempotencyKey, чтобы отфильтровать дубликаты при повторной доставке. - Используйте разные эндпоинты для независимых систем, чтобы изолировать сбои и управлять разными наборами событий.
Формат webhook-сообщения
Имя события. Используйте значения из раздела «Поддерживаемые события».
Момент возникновения события в ISO 8601 UTC.
Общий ключ для всех попыток доставки конкретного события. Сохраняйте его, чтобы выполнять идемпотентную обработку.
Объект с доменными сущностями. Состав зависит от события и описан ниже.
Поддерживаемые события
UserSignedUp
UserSignedUp
Триггер: новый пользователь самостоятельно завершил регистрацию.
data.user содержит полный профиль, data.profile — карточку профиля, data.states.utmSignupParams — исходные UTM-метки.UserAcquainted
UserAcquainted
Триггер: пользователь прошёл онбординг в приложении. Полезная нагрузка идентична
UserSignedUp.UserTgConnected
UserTgConnected
Триггер: пользователь связал Telegram.
data.user и data.profile содержат текущие данные, data.prevTgId помогает отследить перепривязку.CourseProgressChanged
CourseProgressChanged
Триггер: изменился статус урока.
data.user дополнен профилем, data.course включает продукт и продавца. Событие содержит идентификаторы урока и статус (CourseProgressLessonStatus).CourseCompleted
CourseCompleted
Триггер: пользователь завершил курс. Набор данных тот же, что и для
CourseProgressChanged.PaymentCompleted
PaymentCompleted
Триггер: оплата успешно списана.
data.payment содержит платеж, инвойс, пользователя, продукты, скидки и способ оплаты.ProductEnrolledToFree
ProductEnrolledToFree
Триггер: пользователю выдан бесплатный доступ.
data.access описывает доступ, data.product и data.course — продукт и курс, data.user и data.profile — пользователя.Проверка подписи
Подпись передаётся в заголовкеsignature и формируется как HMAC-SHA256 от полного JSON тела вебхука и секретного ключа эндпоинта.
Диагностика и повторные попытки
Повторные попытки
Повторные попытки
Каждая попытка использует ту же нагрузку и
idempotencyKey. Если все пять попыток завершаются ошибкой, задача помечается как failed и отображается в очереди Bull (раздел Monitoring). Отправьте успешный ответ, чтобы остановить дальнейшие попытки.Временное отключение
Временное отключение
Чтобы сохранить конфигурацию, установите
active = false. События будут игнорироваться до повторного включения, но секретный ключ и статистика останутся.Трассировка
Трассировка
Добавляйте логирование прихода события с
event, timestamp, idempotencyKey и статусом проверки подписи. Это поможет быстро сопоставить ваши логи с внутренними логами Exode.