Форма на сайте не отправляет письма: 7 причин и как починить
· 8 мин чтения · Даниил Федулов
Если заявки с сайта перестали приходить, дело почти всегда в одной из семи причин: письма падают в спам, отправка через mail() происходит без нормальной аутентификации, хостинг блокирует порт или саму функцию отправки, посетитель не заполнил обязательное поле, вебхук или обработчик не привязан к форме, письма уходят не на тот адрес или ящик переполнен, либо мешает ошибка JavaScript. Хорошая новость: большинство из них можно проверить самостоятельно за пару минут, без разработчика. Разбираю по порядку — для каждой причины: как проверить и как починить.
1. Письмо в спам: «не пришло» ≠ «не отправлено»
Самая частая причина, и её проверяют в последнюю очередь — все сразу подозревают форму, хотя письмо уже давно ушло, просто не в ту папку.
Как проверить: отправьте тестовую заявку и загляните в папку «Спам» — и в почте, куда должны приходить заявки, и в той, что указана в копии. Если письмо там — оно отправляется, проблема не в форме, а в доверии почтового сервиса к письму.
Почему так происходит: сайт часто отправляет письма «от вашего же адреса» (например, от info@vashsajt.ru на этот же ящик), а домен не подтверждён для отправки почты — нет SPF- и DKIM-записей. Почтовые сервисы считают такие письма подделкой и прячут их подальше от входящих.
Как починить: добавить SPF-запись в DNS домена. Она явно разрешает конкретным серверам отправлять почту от вашего имени:
Тип записи: TXT
Хост: @ (корень домена)
Значение: v=spf1 include:_spf.<провайдер почты> ~allВместо <провайдер почты> подставьте реального провайдера, через который уходит почта — Yandex, Mail.ru, собственный SMTP-сервер и так далее; точный include-домен указан в его документации. Вместе с SPF настройте DKIM (цифровую подпись писем) и, если возможно, DMARC — это резко снижает шанс попасть в спам. Синтаксис записей у разных провайдеров время от времени меняется, поэтому конкретные значения сверяйте с их актуальной документацией, а не с этим примером.
2. mail() без SMTP-аутентификации — письма режутся или улетают в спам
Функция mail() в PHP просто передаёт письмо локальному почтовому агенту сервера — без логина, пароля и шифрования. Часть почтовых сервисов такие письма принимает через раз, часть режет сразу же на подходе.
Как проверить: посмотрите код обработчика формы. Если там напрямую вызывается mail(...) — это и есть вероятная причина, особенно если сайт молодой или переезжал на новый хостинг.
Как починить: перейти на отправку через SMTP с аутентификацией. Для PHP-проектов для этого обычно берут библиотеку PHPMailer — вот минимальная рабочая настройка (пароль ниже — только плейсхолдер, никогда не храните реальный пароль в коде открытым текстом, тем более в репозитории):
require 'vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->Host = 'smtp.example.com'; // адрес SMTP-сервера
$mail->SMTPAuth = true;
$mail->Username = 'no-reply@vashsajt.ru'; // логин почтового ящика
$mail->Password = 'ЗАМЕНИТЕ_НА_РЕАЛЬНЫЙ_ПАРОЛЬ';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
$mail->setFrom('no-reply@vashsajt.ru', 'Название сайта');
$mail->addAddress('you@vashsajt.ru');
$mail->Subject = 'Новая заявка с сайта';
$mail->Body = 'Текст заявки из формы';
$mail->send();
} catch (Exception $e) {
// залогировать $mail->ErrorInfo — не просто показать «Спасибо»
}Для сайтов на WordPress переписывать код обычно не нужно: ту же задачу закрывает готовый плагин WP Mail SMTP — он подставляет настройки SMTP вместо стандартной mail() через настройки в админке, письма начинают доходить без единой строчки собственного кода. Обычно это быстрее, чем чинить самописный обработчик формы вручную.
3. Хостинг блокирует порт 25/587 или саму функцию mail()
Часть недорогих хостингов отключает исходящую почту целиком или режет нестандартные порты — это защита от спама с виртуальных серверов, но задевает и легитимные формы.
Как проверить: попросите написать (или напишите сами) простейший тестовый скрипт, который просто пытается отправить одно письмо, и посмотрите результат по факту — доходит ли письмо, а не по «экрану Спасибо» на сайте. Если письмо не приходит вообще нигде, даже в спам, — вероятная причина здесь.
Как починить: уточните у поддержки хостинга, какой порт и способ отправки разрешён — иногда доступен только внешний SMTP-relay. Если встроенная почта заблокирована принципиально, подключите внешний SMTP: почтовый ящик на вашем домене или транзакционный сервис рассылки писем. Это же решение, по сути, закрывает и причину №2 — отправка идёт уже не через mail().
4. Обязательное поле не заполнено — форма молчит
Коварная причина: некоторые формы при пустом обязательном поле не показывают ошибку — просто молча не отправляются. Посетитель жмёт кнопку, ничего не происходит, он уходит и больше не возвращается.
Как проверить: заполните форму полностью, потом — пропуская каждое поле по очереди. Если форма «зависает» без сообщения об ошибке — проблема найдена.
Как починить: обязательные поля должны явно подсвечиваться при попытке отправки, а необязательные — не блокировать её вовсе. Заодно проверьте, что список обязательных полей соответствует реальности: часто «обязательным» помечено поле, без которого заявку и так можно нормально обработать.
5. Вебхук или обработчик не привязан к форме
Если заявки должны идти в CRM или мессенджер через вебхук, он мог отвалиться: сменили CRM или тариф, «протух» токен, переехал адрес приёмника, а на конструкторах вроде Tilda — приёмник просто не подключён к конкретной форме. Форма при этом выглядит рабочей.
Как проверить: важный нюанс — журнал отправок на стороне сайта может быть пустым и чистым, и это не значит, что всё хорошо. Непривязанный обработчик не делает попыток отправки, а значит, и ошибок не создаёт. Единственная надёжная проверка — сквозная: отправьте тестовую заявку с опубликованной страницы и убедитесь, что она появилась в конечной точке — почте, CRM или мессенджере.
Как починить: если пользуетесь Tilda — там есть своя специфика с привязкой приёмника к каждой форме отдельно, я разобрал её в отдельной инструкции про связку Tilda и CRM. Для самописных сайтов — проверьте адрес вебхука и актуальность токена доступа в настройках интеграции.
6. Неверный адрес получателя или переполненный ящик
Как проверить: сверьте адрес в настройках формы (или прямо в коде обработчика) с реальным рабочим почтовым ящиком — за годы жизни сайта адрес иногда «наследуется» от старого сотрудника или тестового домена, о котором все давно забыли. Отдельно проверьте, не переполнен ли ящик получателя: сервер может молча отклонять входящие письма без уведомления отправителю, если превышена квота места.
Как починить: исправьте адрес получателя на актуальный, освободите место в ящике или увеличьте квоту у почтового провайдера. Полезно продублировать заявки на второй, резервный адрес — если один ящик выйдет из строя, вторая копия всё равно дойдёт и заявка не потеряется бесследно.
7. Ошибка JavaScript мешает отправке
Если форма отправляется скриптом, любая ошибка JavaScript на странице может её заблокировать — например, упал сторонний виджет чата или счётчик аналитики. Кнопка нажимается, но ничего не происходит.
Как проверить: откройте страницу в Chrome, нажмите F12 → вкладка Console — и отправьте тестовую заявку. Красные строки с ошибками укажут на виновника; часто помогает временно убрать последний добавленный на сайт скрипт. Отдельно откройте вкладку Network: найдите запрос отправки формы и посмотрите код ответа — должен быть 200. Любой другой код (400, 500, статус «failed») значит, что запрос до сервера не дошёл или был отклонён, даже если на экране показалось «Спасибо».
Как починить: это и есть противоядие от «обработчика, который всегда зелёный» — экран «Спасибо» должен показываться только тогда, когда сервер реально подтвердил успех, а не просто потому, что запрос был отправлен:
fetch('/send-form', { method: 'POST', body: formData })
.then((res) => {
if (!res.ok) {
throw new Error('Форма ответила кодом ' + res.status);
}
return res.json();
})
.then(() => showSuccessMessage())
.catch((err) => {
console.error('Отправка не удалась:', err);
showErrorMessage();
});Чек-лист: как проверить за 5 минут
- Отправьте тестовую заявку сами — с телефона и с компьютера.
- Проверьте папку «Спам» получателя.
- Откройте DevTools → Network и посмотрите код ответа запроса отправки — должен быть 200.
- Заполните форму с пропуском полей — убедитесь, что ошибки видны.
- Проверьте конечную точку: письмо в ящике, лид в CRM, сообщение в Telegram. Не верьте экрану «Спасибо».
Если сайт — на российском хостинге
Отдельная и самая коварная причина, которая не входит в семёрку выше, но встречается именно на части российских хостингов: сервер не может достучаться до внешнего сервиса. С вашего компьютера сервис доступен, а с сервера хостинга — нет: исходящие запросы блокирует файрвол или сетевые ограничения провайдера. Классический пример — отправка уведомлений в Telegram или на внешний SMTP: запрос к API просто «висит» до таймаута. Симптом — форма отправляется очень долго (5–15 секунд), а уведомление так и не приходит.
Диагностируется только проверкой прямо с сервера — например, тестовым запросом к внешнему адресу из консоли хостинга, а не с вашего компьютера или через VPN, где результат может быть куда более оптимистичным, чем в реальности. Лечится обычно через промежуточный прокси-сервер или сменой способа доставки уведомлений. Прежде чем обещать клиенту «форма и уведомления подключены», стоит проверить именно серверный исходящий доступ.
Если причина не нашлась или нашлась, но чинить некому — это моя типовая задача: починка форм и почты — от 1 000 ₽, обычно за час-день.