Вебхуки

Управление вебхуками магазина.

Структура payload

При наступлении события система отправляет HTTP POST-запрос на зарегистрированный URL с JSON-телом. Конкретный вариант определяется значением поля event:

event Схема payload Описание
ORDER_STATUS_CHANGED WebhookOrderStatusChangedPayload Изменение статуса заказа.
ORDER_PAYMENT_STATUS_CHANGED WebhookOrderPaymentStatusChangedPayload Изменение статуса оплаты заказа.
ORDER_DELIVERY_STATUS_CHANGED WebhookOrderDeliveryStatusChangedPayload Изменение статуса доставки заказа.
CUSTOMER_CHANGED WebhookCustomerChangedPayload Изменение данных клиента.
CART_UPDATED WebhookCartUpdatedPayload Изменение корзины клиента.
WEBHOOK_VALIDATE WebhookValidatePayload Запрос валидации URL при активации.

Поля payload

Поле Тип Описание Обязательное
event_id string (uuid) Уникальный ID события. Используется для идемпотентной обработки. Повторная доставка приходит с тем же event_id. ✓
event string (enum) Тип события: ORDER_STATUS_CHANGED, ORDER_PAYMENT_STATUS_CHANGED, ORDER_DELIVERY_STATUS_CHANGED, CUSTOMER_CHANGED или WEBHOOK_VALIDATE(при вызове POST /v1/webhooks/{webhook_id}/validate?activate=true). ✓
occurred_at string (date-time) Время возникновения события. ✓
data object Данные события.

Поля data для ORDER_STATUS_CHANGED

Поле Тип Описание Обязательное
order_id string (uuid) ID заказа. ✓
customer_id string (uuid) ID клиента, который оформил заказ. Данные клиента — GET /v1/customers/{customer_id}. ✓
new_status OrderStatus Новый статус заказа. Подробнее см. в разделе Заказы. ✓

Поля data для ORDER_PAYMENT_STATUS_CHANGED

Поле Тип Описание Обязательное
order_id string (uuid) ID заказа. ✓
customer_id string (uuid) ID клиента, который оформил заказ. Данные клиента — GET /v1/customers/{customer_id}. ✓
new_payment_status PaymentStatus Новый статус оплаты. Подробнее см. в разделе Заказы. ✓

Поля data для ORDER_DELIVERY_STATUS_CHANGED

Поле Тип Описание Обязательное
order_id string (uuid) ID заказа. ✓
customer_id string (uuid) ID клиента, который оформил заказ. Данные клиента — GET /v1/customers/{customer_id}. ✓
chunk_id integer ID части доставки заказа (у заказа может быть несколько отправлений). ✓
new_delivery_status DeliveryStatus Новый статус доставки. Подробнее см. в разделе Заказы. ✓

Поля data для CUSTOMER_CHANGED

Поле Тип Описание Обязательное
customer_id string (uuid) ID клиента. ✓

Поля data для CART_UPDATED

Поле Тип Описание Обязательное
customer_id string (uuid) ID клиента, чья корзина изменилась. Состав корзины — GET /v1/customers/{customer_id}/cart. ✓

События по одной корзине схлопываются: серия изменений (включая очистку корзины) приходит одним событием, новое событие по одной корзине формируется не чаще раза в окно (по умолчанию 15 минут). Повторная доставка события может прийти позже следующего события по той же корзине. Событие приходит с задержкой до окна после изменения, поэтому актуальный состав корзины запрашивайте в момент обработки события.

Пример payload для ORDER_STATUS_CHANGED:

{
  "event_id": "019b21d9-c5d9-777d-80bd-d67c664bc6d9",
  "event": "ORDER_STATUS_CHANGED",
  "occurred_at": "2024-01-15T10:30:00Z",
  "data": {
    "order_id": "019b21d9-c5d9-777d-80bd-d67c664bc6d9",
    "customer_id": "019b21da-0a3e-7c41-9f2b-5e8d1c7a4b60",
    "new_status": "DELIVERED"
  }
}

Пример payload для ORDER_PAYMENT_STATUS_CHANGED:

{
  "event_id": "019b21d9-c5d9-777d-80bd-d67c664bc6d9",
  "event": "ORDER_PAYMENT_STATUS_CHANGED",
  "occurred_at": "2024-01-15T10:30:00Z",
  "data": {
    "order_id": "019b21d9-c5d9-777d-80bd-d67c664bc6d9",
    "customer_id": "019b21da-0a3e-7c41-9f2b-5e8d1c7a4b60",
    "new_payment_status": "PAYMENT_PAID"
  }
}

Пример payload для ORDER_DELIVERY_STATUS_CHANGED:

{
  "event_id": "019b21d9-c5d9-777d-80bd-d67c664bc6d9",
  "event": "ORDER_DELIVERY_STATUS_CHANGED",
  "occurred_at": "2024-01-15T10:30:00Z",
  "data": {
    "order_id": "019b21d9-c5d9-777d-80bd-d67c664bc6d9",
    "customer_id": "019b21da-0a3e-7c41-9f2b-5e8d1c7a4b60",
    "chunk_id": 1,
    "new_delivery_status": "DELIVERED"
  }
}

Пример payload для CUSTOMER_CHANGED:

{
  "event_id": "019b21d9-c5d9-777d-80bd-d67c664bc6d9",
  "event": "CUSTOMER_CHANGED",
  "occurred_at": "2024-01-15T10:30:00Z",
  "data": {
    "customer_id": "019b21d9-c5d9-777d-80bd-d67c664bc6d9"
  }
}

Пример payload для CART_UPDATED:

{
  "event_id": "019b21d9-c5d9-777d-80bd-d67c664bc6d9",
  "event": "CART_UPDATED",
  "occurred_at": "2024-01-15T10:30:00Z",
  "data": {
    "customer_id": "019b21d9-c5d9-777d-80bd-d67c664bc6d9"
  }
}

Верификация подписи

Каждый запрос содержит заголовок X-Webhook-Signature — HMAC-SHA256 от тела запроса, вычисленный с помощью поля secret вебхука. Используйте его для проверки подлинности входящего запроса:

Запрос
expected = HMAC-SHA256(key=secret, data=request_body)
valid = (X-Webhook-Signature == hex(expected))

Повторные попытки доставки

Доставка работает по принципу at-least-once: одно и то же событие может прийти повторно с тем же event_id. Система повторяет доставку с экспоненциальной задержкой при следующих ответах сервера:

  • 5xx — серверные ошибки.
  • 408 Request Timeout, 429 Too Many Requests.
  • 401 Unauthorized, 403 Forbidden (например, во время ротации секрета на стороне приемника).
  • 404 Not Found (например, во время деплоя приемника).
  • 3xx — редиректы не выполняются, доставка повторяется на исходный URL.
  • Сетевые ошибки и таймаут запроса (10 секунд).

Остальные ответы 4xx (включая 410 Gone) считаются окончательным отказом — доставка не повторяется.

Каждая подписка получает событие независимо. Если один из вебхуков не отвечает, повторы поступают только ему, остальные подписки получают событие один раз. Если вебхук удалили, отключили или отписали от события, повторы прекращаются.

Попытка Задержка перед попыткой
1 —
2 5 сек.
3 10 сек.
4 20 сек.
5 40 сек.
6 ~1,3 мин.
7 ~3 мин.
8 ~5 мин.
9 ~11 мин.
10 ~21 мин.
11 ~43 мин.
12 и далее 1 ч.

Задержки указаны без случайного разброса: фактическая задержка отличается от табличной до ±20% и не превышает максимальный интервал. Если приемник на 429 или 503 вернул заголовок Retry-After, следующая попытка повторится не раньше указанного времени, но не позже максимального интервала.

Параметры
  • Начальный интервал — 5 секунд.
  • Коэффициент — 2.
  • Максимальный интервал — 1 час.
  • Случайный разброс задержки — ±20%.
  • Общее окно — 72 часа с момента постановки события в доставку. После окончания окна событие считается недоставленным и больше не отправляется.

Для CART_UPDATED общее окно — 1 час, максимальный интервал — 10 минут.

Порядок доставки

Доставка вебхуков не гарантируется в хронологическом порядке: событие, которое произошло позже, может быть доставлено раньше. Чтобы восстановить правильную хронологию, используйте поле occurred_at из payload

Активация вебхука

После создания вебхук находится в статусе INACTIVE и не отправляет уведомления.

Чтобы активировать вебхук:

  1. Вызовите POST /v1/webhooks/{webhook_id}/validate?activate=true.
  2. Система отправит POST-запрос на ваш URL с телом — {"event_id": "...", "event": "WEBHOOK_VALIDATE", "occurred_at": "..."}.
  3. Ваш сервер должен вернуть HTTP 2xx с телом:
    { "message": "validated_store_{store_id}" }
    
    • {store_id} — идентификатор вашего магазина (доступен через GET /v1/store).
  4. При успешной проверке вебхук автоматически изменит статус на ACTIVE.
  5. При изменении URL вебхука он переходит в статус INACTIVE, после чего требуется повторная валидация.

Endpoints