Webhook vs Callback. Различия и почему их путают

Каждый раз, когда я объясняю тему асинхронных интеграций, у слушателей возникает один и тот же вопрос: «А в чём разница между webhook и callback, разве это не одно и то же?». Давайте разбираться.

Короткий ответ

Callback — это общий термин в программировании, обозначающий паттерн «вызову тебя позже». В роли callback может выступать функция (переданная как аргумент) или URL‑адрес, который будет вызван после завершения некоторой операции. Важно: callback бывает синхронным (например, функция обратного вызова в Array.map вызывается сразу) и асинхронным (когда вызов откладывается до окончания длительной задачи). В контексте интеграций и API мы говорим именно об асинхронном callback, обычно реализованном через HTTP‑запрос на указанный URL.

Webhook — это частный случай асинхронного callback, но реализованный через HTTP между двумя независимыми системами. Сервис заранее регистрирует URL, и сторонний сервис сам, по своей инициативе, присылает туда POST‑запрос при наступлении события. Простыми словами, webhook — это HTTP‑callback между сервисами, а не любой callback вообще.

Оба механизма решают одну задачу — «сообщить о результате позже, не блокируя вызывающего», — но у них разная область применения, разный жизненный цикл и разный уровень связности.

Откуда путаница

Путаница возникает из‑за того, что webhook часто называют «callback URL», и оба используют похожий синтаксис (передача URL). Однако их назначение и способ настройки кардинально отличаются. Ниже таблица, которая поможет разобраться.

КритерийCallbackWebhook
УровеньВнутри кода / внутри кода приложенияМежду независимыми системами по HTTP
Что передаетсяФункция или URL, привязанный к конкретному запросуЗаранее зарегистрированный URL, привязанный к событию/подписке
Кто инициирует повторный вызовТот же процесс/API, что обрабатывал исходный запросВнешняя система, независимо от того, кто и когда ее “спросил”
Количество срабатыванийОбычно один раз, на конкретный запросМногократно, каждый раз при событии, пока подписка активна
НастройкаУказывается при каждом вызове API (в теле запроса)Настраивается один раз при интеграции (подписка на событие)
Язык/платформаЧасто завязан на конкретный язык и окружение (например, функция в коде)Языко-независим — просто HTTP-запрос
ПримерPOST /transfer с полем callbackUrl, куда придет статус переводаПодписка на событие invoice.paid от YooKassa — уведомления приходят сами

Обратите внимание: в строке «Количество срабатываний» речь идет именно об асинхронных callback‑URL, передаваемых в запросе. Обычные callback‑функции в коде могут вызываться многократно (например, обработчик кликов) — важно не путать эти понятия.

Webhook как один из способов асинхронного взаимодействия

Webhook — это не единственный способ организовать асинхронную связь между сервисами. Вместе с ним используются:

  • Polling (клиент периодически опрашивает сервер на предмет готовности результата)
  • Long‑polling (клиент открывает запрос и ждёт, пока сервер ответит, когда появится событие)
  • WebSockets (постоянное двунаправленное соединение)
  • Message queues (брокеры сообщений, например, RabbitMQ или Kafka)

Webhook хорош тем, что он push‑ориентирован — сервис сам отправляет данные, когда они готовы, и не требует постоянного соединения. Это экономит ресурсы и упрощает архитектуру, особенно при интеграции с внешними провайдерами.

Аналогия для понимания

Callback — это когда вы заводите тикет в поддержку, оставляете номер телефона, и вам звонят один раз, когда очередь подошла. Webhook — это как установленный на двери звонок, срабатывает каждый раз, когда кто-то приходит, независимо от того, ждете вы гостя или нет.

Еще пример: пользователь нажал «Оплатить» и вы передали callbackUrl конкретно для этой транзакции — это callback, привязанный к одному действию. А если вы один раз настроили у платежного провайдера подписку «присылай мне уведомление на этот URL каждый раз, когда на мой счет приходит платеж» — это webhook, который будет работать постоянно, без повторной настройки.

Схема: Callback (в рамках одного запроса)

Callback-URL привязан к конкретному вызову API и срабатывает один раз, когда операция завершена.

Callback: результат конкретного запроса

Схема: Webhook (подписка на события)

Webhook настраивается один раз (подписка), а срабатывает многократно — каждый раз, когда происходит событие, даже если приложение ничего не запрашивало. Webhook: подписка на события

Схема: как они соотносятся друг с другом

Webhook — это подмножество callback: любой webhook является callback-механизмом, но не любой callback — webhook. Соотношение понятий Webhook и Callback

Практический пример кода

Callback URL (разовый запрос)

POST /api/v1/transfer
{
  "amount": 100,
  "accountTo": "40817...",
  "callbackUrl": "https://bv-dev.ru/ft-callback"
}

Регистрация webhook (подписка, делается один раз)

POST /api/v1/webhooks
{
  "url": "https://bv-dev.ru/webhooks/payments",
  "events": ["payment.succeeded", "payment.failed"]
}

Ключевое отличие: в первом случае URL передаётся вместе с каждым запросом, во втором — URL регистрируется один раз, а данные будут приходить по мере возникновения событий, без привязки к конкретному запросу.

Другие популярные сценарии использования webhook

  • GitHub – уведомления о push, создании pull request, комментариях, релизах
  • Stripe / PayPal / YooKassa – уведомления о платежах, возвратах, подписках
  • CRM-системы – обновление контактов, сделок, задач
  • CI/CD (Jenkins, GitLab) – запуск сборки после коммита, уведомление о результате
  • Мониторинг (Prometheus Alertmanager) – отправка алертов в вашу систему

Безопасность и надежность: о чем нельзя забывать

При работе с webhook‑ами в продакшене недостаточно просто принять запрос. Нужно позаботиться о следующих аспектах:

  • Проверка подлинности – как убедиться, что запрос пришёл именно от провайдера, а не от злоумышленника? Обычно используется подпись (HMAC с секретным ключом, JWT) или проверка IP‑адресов (но IP можно подделать). Всегда проверяйте подпись в заголовках (например, X‑Signature).
  • Идемпотентность – провайдер может дублировать одно и то же событие (например, из‑за сетевых ошибок). Ваш обработчик должен быть идемпотентным: повторная обработка того же события не должна приводить к нежелательным побочным эффектам. Используйте уникальный eventId и храните его в БД, чтобы отсеивать дубли.
  • Повторные попытки (retries) – если ваш endpoint вернул ошибку (4xx или 5xx), провайдер обычно будет повторять запрос с экспоненциальной задержкой. Ваш сервис должен корректно обрабатывать такие повторные попытки и не «падать» от большого количества ретраев.
  • Timeout и асинхронность – обрабатывайте webhook быстро (200 OK), а длительную логику выносите в очередь или фоновые задачи. Иначе провайдер может посчитать ваш сервер недоступным.

Как выбрать: callback URL или webhook?

Небольшой чеклист

СитуацияРекомендация
Нужно получить результат одной конкретной операции (перевод, расчет)Используйте callback URL
Нужно реагировать на все будущие события в системе (платежи, коммиты)Используйте webhook
Интеграция с внешним сервисом, где вы не управляете его внутренней логикойПредпочтительнее webhook
Вы контролируете и клиент, и сервер, и хотите простой синхронный подходМожно обойтись без них (синхронный ответ)

Webhook vs Callback совсем простыми словами

Callback – «перезвони мне, когда закончишь эту конкретную задачу» (один раз).
Webhook – «звони мне каждый раз, когда происходит вот такое событие» (многократно, настройка один раз, работает по HTTP между системами).

Резюме

Главное отличие: callback — это общий паттерн «вызову тебя позже», а webhook — это конкретная реализация этого паттерна по HTTP между сервисами, с многократными срабатываниями и заранее настроенной подпиской.
Выбирайте callback URL для разовых ответов на конкретный запрос, а webhook — для постоянного потока событий. Не забывайте про безопасность: проверяйте подписи, делайте обработчики идемпотентными и корректно работайте с повторными попытками.

Полезные ссылки для углубления

Если вы только начинаете внедрять webhook‑и, рекомендую сначала изучить документацию вашего провайдера и реализовать простой endpoint с логированием — это поможет отладить интеграцию и избежать неприятных сюрпризов на проде.