Webhook в форме Tilda даёт прямой способ забрать заявку и обработать её собственной логикой, а не только через готовые интеграции с CRM и почтой, которые тоже есть в конструкторе. Среди приёмщиков данных в настройках сайта есть отдельный тип подключения: Webhook. При отправке формы Tilda делает POST-запрос на URL, который вы укажете, и передаёт поля заявки обычными парами «имя=значение», а дальше ваш сервер сам решает, что делать с данными: записать заявку в базу, отправить уведомление в Telegram, посчитать стоимость или передать данные в свою систему. Ниже показываю, как принять такой webhook на обычном PHP-хостинге, без выделенного сервера и без посредников.
По теме статьи
Готовое решение
Запрет прошедших дат в календаре формы Tilda
Одно правило на все поля «Дата» сайта: прошедшие дни бледнеют и не выбираются, можно закрыть сегодня и ближайшие N дней. Вписанная руками прошедшая дата стирается.
Бесплатно
Кастомный скрипт
Когда стандартных блоков не хватает
Доработка сайтов на Тильде: скрипты для корзины, промокоды, зоны доставки, интеграции с CRM и Telegram. Простой скрипт от 3 000
от3 000 ₽
Как включить приём вебхука в настройках сайта Tilda
Адрес обработчика задаётся не в блоке с формой, а в настройках сайта: Настройки сайта, раздел Формы, пункт Webhook. Указываю адрес своего скрипта, например https://mysite.ru/tilda-webhook.php, при необходимости ставлю галочку отправки куки и сохраняю. После этого открываю страницу с формой, в меню «Контент» блока отмечаю сервис приёма данных Webhook, сохраняю и публикую страницу заново, иначе новый получатель заявки не подключится.
Требования к скрипту в справке заданы жёстко: адрес должен быть доступен, скрипт обязан ответить в течение пяти секунд и работать по HTTPS. Если ответа нет, система сделает ещё две попытки, каждую через минуту.
Отдельной кнопки тестовой отправки у поля URL нет. Тестовый запрос Tilda отправляет сама: сразу после подключения Webhook на указанный адрес уходит POST с данными test=test, и от скрипта ожидается ответ 200 OK. По логам сервера в этот момент уже видно, доходит ли запрос вообще, а состав полей настоящей заявки смотрю на первой живой отправке формы.
Webhook не отменяет остальные интеграции формы. Уведомление на почту, передача в CRM и вебхук на свой сервер работают параллельно: Tilda рассылает данные заявки всем подключённым получателям после каждой успешной отправки формы.
На одном сайте обычно несколько форм: заявка с лендинга, форма подбора товара, форма подписки на рассылку. Для каждой формы вебхук настраивается отдельно, и можно указать либо один общий обработчик, либо развести формы по разным URL, если логика заметно отличается, например заявка идёт в таблицу лидов, а подписка сразу добавляет адрес в список рассылки.
Что приходит на ваш URL: структура запроса
Tilda делает обычный POST формы, а не JSON: все поля приходят в $_POST парами «имя=значение», где имена совпадают с именами полей, которые вы задали в настройках формы, например Name, Phone, Email. Если «имя переменной» у поля не менять, оно придёт с первой буквой в верхнем регистре. Кроме полей заявки приходят служебные tranid (уникальный номер заявки из раздела «Заявки») и formid (номер блока, с которого была отправка). Часть символов в значениях экранирована: вместо @ приходит %40, вместо двоеточия %3a, поэтому значения прогоняю через urldecode. Точный набор ключей зависит от того, какие поля добавлены в конструкторе и как они названы, поэтому на практике я всегда сначала смотрю реальный запрос: логирую его целиком при первом тесте, а уже потом пишу код под конкретные названия полей.
Пример того, что обычно прилетает на сервер (реальные ключи будут отражать поля именно вашей формы):
Name=test+name
Phone=0123456789
Email=test%40email.com
Comments=example+comment
tranid=467251%3A8442970
formid=form48844953
PHP-обработчик вебхука на обычном хостинге
Для приёма вебхука не нужен отдельный сервер, VPS или процесс на Node.js, который постоянно крутится в фоне: обычный PHP-скрипт на хостинге, где уже лежит сайт, справляется полностью, потому что Tilda делает один HTTP-запрос и ждёт от него быстрый ответ.
<?php
$data = array_map(static function ($value) {
return is_string($value) ? urldecode($value) : $value;
}, $_POST);
if (!$data) {
http_response_code(400);
exit;
}
$name = trim($data['Name'] ?? '');
$phone = trim($data['Phone'] ?? '');
$email = trim($data['Email'] ?? '');
$payload = json_encode($data, JSON_UNESCAPED_UNICODE);
$pdo = new PDO('mysql:host=localhost;dbname=site;charset=utf8mb4', 'db_user', 'db_pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('INSERT INTO leads (name, phone, email, payload, created_at) VALUES (?, ?, ?, ?, NOW())');
$stmt->execute([$name, $phone, $email, $payload]);
http_response_code(200);
Скрипт читает данные из $_POST, а не из php://input, потому что Tilda присылает обычную форму, а не JSON. Значения прогоняю через urldecode: в справке Тильды сказано, что часть символов перед передачей экранируется, например вместо @ приходит %40. Весь набор полей сохраняю в отдельную колонку: если в конструкторе изменится название поля или добавится новое, данные не потеряются, их можно будет перечитать из лога уже после правки кода. Ответ 200 нужен и на тестовый запрос test=test, который Tilda отправляет сразу после подключения приёмщика.
Тяжёлую логику лучше не запускать внутри самого обработчика вебхука. Если после заявки нужно дёрнуть внешний API, посчитать что-то небыстрое или сходить в другую систему, надёжнее сначала быстро сохранить сырые данные и ответить Tilda, а уже отдельным шагом обрабатывать сохранённые записи, читая их из базы.
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Секретный токен вместо доверия по умолчанию
Подписи запроса вроде HMAC-подписи у вебхука Tilda нет, поэтому обработчик должен сам убедиться, что запрос пришёл именно от вашей формы, а не от кого попало, кто узнал адрес скрипта. Фильтровать по IP ненадёжно: адреса серверов Tilda нигде не зафиксированы как постоянные и могут меняться, а обработчик, который перестанет принимать заявки после такой смены, заметят не сразу.
Проще добавить в сам адрес вебхука произвольный секретный параметр, например https://mysite.ru/tilda-webhook.php?token=a91f7c3e, и на сервере первым делом сверить его со значением из конфига:
<?php
$expectedToken = 'a91f7c3e';
if (($_GET['token'] ?? '') !== $expectedToken) {
http_response_code(403);
exit;
}
Токен не виден в теле заявки и не попадает в публичный код страницы, он живёт только в настройках приёмщика Webhook внутри Tilda, куда доступ есть только у вас. Если логика обработки вебхука сложнее, чем запись в таблицу и уведомление, например нужно свериться с остатками, посчитать скидку по промокоду или дёрнуть по очереди несколько внешних API, такую кастомную доработку Тильды обычно беру в работу отдельно, а не собираю из тестового скрипта.
Сохраняю заявку и уведомляю в Telegram
После проверки токена и записи заявки в базу отправляю короткое уведомление в Telegram, проверять таблицу лидов руками неудобно, а сообщение приходит за пару секунд. Для одного уведомления не нужен полноценный бот на aiogram с обработкой команд, достаточно прямого запроса к Bot API.
<?php
$botToken = 'BOT_TOKEN';
$chatId = 'CHAT_ID';
$text = "Новая заявка: {$name}, {$phone}";
file_get_contents(
"https://api.telegram.org/bot{$botToken}/sendMessage?chat_id={$chatId}&text=" . urlencode($text)
);
Если позже понадобится не разовое уведомление, а бот с командами и кнопками, например чтобы менеджер отвечал клиенту прямо из Telegram, это уже отдельная задача под aiogram или похожий фреймворк: там нужен процесс, который постоянно слушает обновления, а не разовый вызов из PHP-скрипта.
Когда вебхук лучше принимать через n8n, а не свой скрипт
Свой PHP-обработчик хорош, когда логика простая и укладывается в десяток строк: записать, проверить, уведомить. Если вебхук должен разойтись сразу в несколько систем, в CRM, в таблицу, в мессенджер и во внешний сервис аналитики, писать это руками дольше, чем собрать сценарий в n8n: нода Webhook принимает POST от Tilda, а дальше данные расходятся по нужным сервисам без кода.
За удобство приходится платить инфраструктурой: n8n нужно где-то развернуть, значит завести отдельный сервер, следить за обновлениями и сертификатом, либо оплачивать облачную версию сервиса. PHP-скрипт в этом смысле проще: он живёт на том же хостинге, что и сам сайт на Tilda, и отдельных расходов на сервер не требует.
Если через вебхук в сценарий попадают контакты клиентов, имя, телефон, почта, храню их на сервере в России, а не в облачном сервисе с зарубежными дата-центрами: для персональных данных это требование 152-ФЗ, а не вопрос удобства.
| Способ | Нужен ли отдельный сервер | Когда выбираю |
|---|---|---|
| PHP-обработчик на хостинге сайта | Нет, работает на том же хостинге, где лежит сайт на Tilda | Логика простая: записать заявку, проверить токен, отправить уведомление |
| Сценарий в n8n | Да, self-hosted версия требует своего сервера, либо нужна подписка облачного сервиса | Заявка должна разойтись сразу в несколько сервисов без написания кода |
| Готовая интеграция Tilda (CRM, почта) | Не нужен, всё настраивается в самой Tilda | Достаточно передать заявку в CRM или на почту без кастомной обработки |
Если разово настраиваю такой сценарий клиенту, автоматизация в n8n у меня стоит от 25 000 ₽, в эту сумму входит сама логика сценария, а не аренда сервера под него.
Условия и возможности Тильды меняются, поэтому перед запуском я уточняю их у самого сервиса.
Частые вопросы
Как проверить, что вебхук Тильды действительно доходит до сервера?
Сразу после того как приёмщик Webhook сохранён в Настройках сайта, Tilda сама отправляет на указанный адрес POST с данными test=test и ждёт от скрипта ответ 200 OK. На своей стороне логирую весь $_POST в файл или отдельную таблицу перед всей остальной обработкой: так сразу видно, доходит ли запрос вообще и какие поля в нём лежат, ещё до того как код начнёт с ним что-то делать.
Почему обработчик не получает данные с формы?
Чаще всего страницу не опубликовали заново после того, как отметили Webhook в меню «Контент» блока с формой: список получателей обновляется только после публикации. Ещё стоит проверить, что адрес скрипта открыт снаружи без пароля и без блокировки в .htaccess, что скрипт ждёт именно POST, а не GET, и что сама заявка вообще успешно отправляется с формы, например обязательные поля заполнены и капча пройдена.
Нужен ли отдельный сервер для приёма вебхука Тильды?
Нет, обычный PHP-скрипт на том же хостинге, где лежит сайт, справляется полностью: Tilda делает один короткий HTTP-запрос, и хостинга с поддержкой PHP и MySQL для этого достаточно. Отдельный сервер понадобится, только если вебхук нужно передать в более тяжёлый инструмент вроде self-hosted n8n или в процесс, который постоянно слушает обновления, например в бота на aiogram.
Как защитить скрипт от чужих запросов на тот же адрес?
Добавляю в сам URL вебхука секретный параметр, например ?token=…, и первым делом на сервере сверяю его значение, прежде чем читать и сохранять тело запроса. Фильтрация по IP-адресам Tilda для этого подходит хуже, потому что адреса серверов платформы нигде не зафиксированы как постоянные.