Исходящий вебхук — самый дешёвый способ подружить Битрикс с чем угодно: с сайтом, складом, личным кабинетом, своим сервисом на вайб-коде. Настраивается за десять минут, работает без приложений и посредников. И ровно поэтому его чаще всего делают неаккуратно: события выбраны наугад, ошибки никуда не пишутся, а через неделю выясняется, что часть данных не доехала. Разберу, как устроен исходящий вебхук по-нормальному и что в нём ломается чаще всего.

Что это такое и чем отличается от входящего
Входящий вебхук — это когда внешняя система стучится в Битрикс: создаёт сделку, читает контакт, меняет поле. Исходящий работает наоборот: Битрикс сам сообщает наружу, что у него что-то произошло. Сделка создана, сделка изменена, контакт удалён — портал отправляет короткий пакет на указанный вами адрес.
Важная деталь, которую упускают: в этом пакете нет всей карточки. Приходит идентификатор объекта, тип события и служебные данные для проверки подлинности. Всё остальное принимающая сторона должна запросить сама — обычным вызовом API. Это сделано специально, чтобы данные не гуляли по сети лишний раз и всегда были актуальными на момент чтения, а не на момент отправки события.
Отсюда первое правило: для исходящего вебхука почти всегда нужен ещё и входящий — тот, которым внешняя система пойдёт дочитывать карточку. Если про это забыть на этапе проектирования, потом приходится переделывать схему доступов и объяснять безопаснику, откуда взялся второй ключ.
На каком событии вешать
Самая частая ошибка — подписаться на изменение сделки и радоваться. Событие изменения срабатывает на любое шевеление: менеджер поправил запятую в комментарии, робот проставил служебное поле, прошла массовая правка через импорт. Ваша внешняя система будет получать шквал сообщений, из которых полезны единицы.
Правильнее подписываться на минимально достаточное событие и добавлять фильтр уже на своей стороне. Если наружу нужна информация о выигранных сделках — ловите изменение, но обрабатывайте только те, где стадия стала финальной, а в остальных случаях сразу отвечайте и ничего не делайте. Обработка должна быть дешёвой, потому что вызовов будет много.
Отдельно подумайте, нужен ли вебхук вообще. Иногда задача решается штатным роботом внутри портала или готовым коннектором из маркетплейса, и тогда своя интеграция — лишний код, который придётся поддерживать. Мы разбирали этот выбор в статье про то, когда хватает робота Битрикса, а когда нужен внешний сервис.
Идемпотентность: одно и то же придёт дважды
Главное, к чему надо готовиться сразу: одно и то же событие придёт несколько раз. Так устроены все системы обмена сообщениями — при сетевой ошибке или таймауте отправитель повторяет попытку, не зная, дошло предыдущее или нет. Если ваш обработчик на каждый вызов создаёт новую запись, вы получите дубли, причём выборочные и трудноуловимые.
Лечится это идемпотентностью: обработчик должен давать одинаковый результат независимо от того, вызвали его один раз или пять. Практически — заводите ключ операции из идентификатора объекта и типа события, храните обработанные ключи и на повторе просто отвечайте, что всё в порядке. Никакой магии, но это спасает от дублей навсегда.
Второй слой защиты — сверять состояние, а не применять дельту. Если внешняя система на каждое событие перечитывает карточку из Битрикса и приводит свою запись к этому состоянию, повторный вызов просто ничего не меняет. Это надёжнее, чем пытаться понять, что именно изменилось с прошлого раза.
Ретраи, таймауты и логирование
Принимающая сторона обязана отвечать быстро. Если ваш скрипт сначала лезет в чужой API, потом пишет в базу, потом отправляет письмо и только затем отвечает Битриксу, вы легко упрётесь в таймаут. Правильная схема — принять, положить в очередь, немедленно ответить, а тяжёлую работу делать фоном. Это чуть дороже в разработке, зато интеграция перестаёт зависеть от скорости чужих серверов и не разваливается в первый же час пиковой нагрузки.
Дальше — ретраи на своей стороне. Внешний сервис, в который вы передаёте данные, будет иногда лежать: обновление, перезапуск, просроченный сертификат. Без повторных попыток с нарастающей паузой каждое такое окно превращается в дыру в данных, о которой никто не узнает. Три-четыре попытки с увеличивающимся интервалом закрывают почти все бытовые сбои.
И логирование. Тихая интеграция — самая опасная: она не падает, она просто перестаёт передавать часть записей. Пишите каждое входящее событие, результат обработки и ответ внешней системы, храните хотя бы несколько недель. Без лога разбор любого инцидента превращается в гадание, а с логом занимает пять минут. И заведите себе хотя бы простейший сигнал: если за сутки не пришло ни одного события там, где обычно приходят десятки, кто-то должен об этом узнать раньше клиента.
Что передавать наружу и как это защитить
Первое правило — минимум данных. Наружу уходит только то, без чего принимающая система не сможет сделать свою работу. Не надо выгружать всю карточку клиента в сервис, которому нужен один номер заказа. Чем меньше данных гуляет между системами, тем меньше поверхность для проблем и тем проще потом отвечать на вопросы о персональных данных.
Второе — проверка подлинности. Ваш обработчик доступен из интернета, и постучаться туда может кто угодно. Проверяйте, что запрос действительно от вашего портала: сверяйте служебный токен из пакета, ограничивайте адреса, откуда принимаете вызовы. Без этой проверки посторонний сможет заставить вашу систему что-нибудь сделать, просто отправив похожий запрос.
Третье — сроки жизни ключей. Вебхуки имеют свойство копиться: за пару лет их набирается десяток, часть уже никуда не ведёт, часть создана уволившимися людьми. Заведите себе простой реестр: что за интеграция, кто владелец, куда ходит, зачем. Ревизия раз в полгода занимает час и снимает целый класс неприятных сюрпризов.
Бесконечный цикл и другие грабли
Классика жанра: вебхук на изменение сделки, обработчик что-то пишет обратно в эту же сделку через API, изменение снова вызывает вебхук. Портал начинает молотить сам себя, лимиты выгорают, менеджеры видят тормоза. Ломается это не сразу, а когда объём подрастёт, поэтому на тесте из трёх сделок цикл часто не замечают.
Защита простая. Проверяйте, что именно изменилось, и не реагируйте на собственные правки: помечайте служебным полем записи, изменённые интеграцией, или сравнивайте новое состояние с тем, что вы сами только что записали. Плюс поставьте себе счётчик вызовов за период — резкий рост сразу покажет, что где-то замкнуло.
Ещё два места, где обычно больно. Первое — доступы: вебхук создаётся от имени сотрудника, и если этот человек уволится или потеряет права, интеграция встанет молча. Заводите его от служебной учётной записи. Второе — тест на реальных данных перед запуском на людей. Проектирование и сопровождение таких интеграций мы берём на себя в рамках доработок, но правило проверять до боевого запуска действует всегда.
Частые вопросы
Приходят ли в исходящем вебхуке все поля сделки?
Нет. Битрикс присылает идентификатор объекта, тип события и служебные данные. Полную карточку принимающая сторона запрашивает сама через API — так данные всегда актуальны на момент чтения.
Почему одно и то же событие приходит несколько раз?
Так работает доставка сообщений: при таймауте или сетевой ошибке отправитель повторяет попытку. Обработчик нужно делать идемпотентным, чтобы повтор не создавал дубль.
Как избежать бесконечного цикла с вебхуком?
Не реагировать на собственные изменения: помечать записи, изменённые интеграцией, служебным полем или сверять новое состояние с только что записанным. И следить за счётчиком вызовов за период.