Интеграция сайта с CRM: как не терять заявки, если готового коннектора нет
Рано или поздно почти каждый бизнес с сайтом сталкивается с одной и той же проблемой: заявки приходят на почту или падают в общий чат, менеджеры их теряют, а в CRM попадает в лучшем случае половина реальных лидов. Логичное решение — настроить автоматическую передачу заявок напрямую в CRM. Но что делать, если между вашим сайтом (или конструктором сайтов) и вашей CRM “нет готового коннектора“?
В этой статье — пошаговый разбор, как я подхожу к таким задачам, на основе реального проекта: связка конструктора сайтов с отраслевой CRM для агентства недвижимости, где готовой интеграции не существовало в принципе.
Почему “просто вставить API-ключ” часто не работает
Первое, что приходит в голову — зайти в настройки сайта, найти поле “API-ключ CRM”, вставить и забыть. На практике это работает только для пары десятков самых популярных связок (например, Tilda ↔ amoCRM). Во всех остальных случаях всплывает одна и та же проблема:
– Площадка (конструктор сайта, лендинг, форма) умеет отправлять данные наружу только по собственному формату — либо генерирует свой вебхук с фиксированным набором параметров, либо вообще не поддерживает произвольные API-ключи сторонних сервисов.
– CRM, в свою очередь, готова принимать данные только через свой API — со своим форматом авторизации, своими обязательными полями и своей структурой запроса.
Эти два формата почти никогда не совпадают напрямую. Получается разрыв: площадка не умеет говорить на языке CRM, а CRM не умеет слушать площадку. Готового переводчика между ними нет — вставлять ключи некуда.
Решение — сервис-посредник (middleware)
Единственный надёжный способ закрыть такой разрыв — написать небольшой сервис-мост между двумя системами. Логика простая:
Площадка (событие “новая заявка”)
→ POST-запрос на ваш сервер
→ Скрипт-мост: разбирает данные, преобразует в нужный формат
→ POST-запрос в CRM с её ключом и в её формате
Такой сервис можно разместить где угодно — на обычном хостинге, в виде serverless-функции (Vercel, Netlify) или на VPS. Важно только, чтобы у него был стабильный HTTPS-адрес, доступный из интернета.
Минимальный пример на PHP
Вот упрощённый, обезличенный каркас такого моста — идея универсальна для большинства связок “конструктор сайта → CRM”:
<?php
// ==== Настройки ====
$crm_api_key = 'ВАШ_КЛЮЧ_CRM';
$crm_url = 'https://api.example-crm.ru/leads/create';
$log_file = __DIR__ . '/log.txt';
// ==== Приём данных от площадки ====
$data = $_POST['data'] ?? [];
$phone = preg_replace('/\D/', '', $data['phone'] ?? '');
$name = trim($data['name'] ?? '') ?: 'Клиент с сайта';
if ($phone === '') {
http_response_code(200); // площадке нужен 200, чтобы не было бесконечных ретраев
exit;
}
// ==== Формируем запрос в CRM ====
$payload = [
'api_key' => $crm_api_key,
'name' => $name,
'phone' => $phone,
'comment' => 'Источник: сайт',
];
$ch = curl_init($crm_url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// ==== Логируем результат ====
file_put_contents($log_file, date('Y-m-d H:i:s')
. " | HTTP {$httpCode} | Ответ: {$response}\n", FILE_APPEND);
http_response_code(200);
Реальный код почти всегда сложнее — нужно разбирать вложенные структуры данных, собирать текстовые примечания из произвольных полей формы, обрабатывать UTM-метки, определять источник трафика и назначать ответственного менеджера. Но принцип остаётся тем же: **принять → преобразовать → передать**.
Пять вещей, которые ломаются чаще всего
За несколько подобных проектов сложился список типичных проблем, которые стоит проверять сразу, а не через неделю после запуска:
1. Формат данных не JSON, а form-urlencoded.
Многие площадки шлют данные в классическом HTML-формате (`application/x-www-form-urlencoded`), а не JSON. Если скрипт ждёт JSON и пытается его декодировать — данные потеряются молча, без ошибки. Проверяйте реальный вебхук через сервис вроде webhook.site, прежде чем писать логику разбора.
2. CRM требует поля, которых нет в документации явно.
Формальная документация API нередко расходится с реальным поведением сервера. Поле, помеченное как “необязательное”, на практике может быть обязательным — сервер просто вернёт `403` или `422` с понятной текстовой ошибкой. Это нормальная часть процесса: тестируете, читаете код ошибки, добавляете поле, тестируете снова.
3. Кириллица работает, эмодзи — не всегда.
Отдельный неочевидный кейс: некоторые CRM (особенно построенные на старых версиях MySQL с кодировкой `utf8` вместо `utf8mb4`) физически не могут сохранить 4-байтовые символы UTF-8 — а это как раз эмодзи. Текст с эмодзи в таком случае не выдаёт ошибку, а просто сохраняется как пустая строка. Если хочется визуально выделить блоки текста — используйте текстовые разделители (`—`, заглавные буквы) вместо эмодзи.
4. “Заявка создалась” ≠ “заявку видно в интерфейсе”.
API может честно вернуть `”status”:”ok”` и ID новой записи — а сотрудник всё равно не найдёт её в интерфейсе. Причины бывают разные: заявка попала не в тот раздел (например, “аренда” вместо “продажа”), назначен ответственный, под которым сейчас никто не смотрит, или сработал фильтр по дублю телефона. Первое, что нужно проверять в таких случаях — не код, а сам факт создания записи через API (метод получения по ID), это сразу отсекает половину ложных версий.
5. Ключи API имеют свойство “утекать” при тестировании.
Пока идёт отладка, ключи часто оказываются в диагностических скриптах, логах, скриншотах, переписке. Хорошая практика — после завершения тестирования **перевыпустить ключ** в самой CRM, а не полагаться на то, что старый нигде не остался.
Что стоит сделать до запуска в бой
Короткий чек-лист, который экономит время на этапе внедрения:
– Поймать реальный пример вебхука от площадки (через webhook.site или временный echo-скрипт с фейковыми тестовыми данными — не с реальными телефонами клиентов).
– Получить официальную документацию API CRM — часто она лежит не в открытом доступе, а внутри личного кабинета в разделе настроек.
– Написать мост с подробным логированием каждого запроса и ответа — без логов отладка сбоев занимает в разы больше времени.
– Настроить алерты (например, в Telegram) на случай, если CRM вернула ошибку — иначе о сбое узнаете только тогда, когда клиент напишет “заявки не приходят”.
– Закрыть доступ к папке со скриптом через `.htaccess`, убрать листинг директорий, не хранить ключи в файлах, которые сами что-то выводят в браузер.
– Продумать ротацию логов — не хранить телефоны и другие персональные данные клиентов дольше, чем это реально нужно для отладки.
Итог
Отсутствие готового коннектора между сайтом и CRM — не тупик, а типовая инженерная задача с понятным решением. Сервис-мост, который принимает вебхук в одном формате и переупаковывает его в другой, закрывает практически любую связку “площадка → CRM”, даже самую нестандартную. Ключевое — не бояться отладки через реальные тестовые запросы и логи, а не только через документацию: то, что написано в доке, и то, что реально происходит на сервере, иногда заметно отличаются.