Сайт на WordPress не отправляет почту: письма с формы не приходят, уведомлений нет, пароль не сбросить. В 2016 году я чинил это у очередного заказчика и записал рецепт. За десять лет причина не изменилась: хостинг не даёт сайту отправлять почту сам или почтовые службы не доверяют письмам с его сервера. Не изменилось и решение — отправлять письма через настоящий почтовый ящик по SMTP, как это делает почтовая программа.
Изменилось всё вокруг: плагин из первой версии поста заброшен, а Gmail и Яндекс больше не пускают по обычному паролю. Ниже — как настроить сейчас, с плагином и без, и какие ошибки встречаются по дороге. Код проверил на WordPress 7.1.3.
mu-plugins (код ниже). Адрес отправителя — тот же ящик. Если не уверены, что дело в отправке, сначала пройдите четыре проверки, почему не приходит почта с сайта.Почему WordPress не может отправить письмо сам
По умолчанию WordPress отдаёт письмо функции PHP mail(), а та — почтовому серверу хостинга. Самый простой способ рассылать спам — залить скрипт на PHP на какой-нибудь хостинг. Если с сервера пошёл спам, его адрес попадает в чёрные списки, и письма перестают доходить у всех клиентов хостера. Поэтому многие хостеры mail() ограничивают или отключают совсем.
Но даже если mail() работает, письмо уходит от имени wordpress@ваш-домен с сервера, которого нет в SPF вашего домена. Gmail и Яндекс таким письмам не доверяют и кладут в спам или не принимают.
SMTP решает обе проблемы: сайт входит в настоящий ящик по логину и паролю и отправляет письмо через почтовую службу, как обычная почтовая программа.
1. Ящик для писем сайта
Лучший вариант — ящик на своём домене, например site@ваш-домен, в Яндекс 360, Mail.ru для бизнеса или у хостинга. Почтовая служба сама подскажет, какие записи SPF и DKIM добавить в DNS, и письма будут выглядеть солидно.
Подойдёт и обычный бесплатный ящик на Яндексе, Mail.ru или Gmail. Заведите отдельный, технический: писать с него будет только сайт, а пароль от него будет лежать на сервере. Личный ящик для этого не используйте.
2. Пароль приложения
Обычный пароль от ящика для SMTP не подойдёт: почтовые службы пускают сторонние программы только по паролю приложения — отдельному паролю, который даёт доступ к почте, но не к аккаунту. Его можно отозвать в любой момент, не меняя основной.
- Яндекс: Яндекс ID → «Безопасность» → «Пароли приложений», тип — почта. В настройках почты разрешите доступ почтовым программам.
- Mail.ru: настройки аккаунта → «Безопасность» → «Пароли для внешних приложений».
- Gmail: сначала включите двухэтапную аутентификацию, без неё пароли приложений недоступны. Потом аккаунт Google → «Безопасность» → «Пароли приложений».
Параметры серверов:
- Яндекс:
smtp.yandex.ru, порт 465, SSL; - Mail.ru:
smtp.mail.ru, порт 465, SSL; - Gmail:
smtp.gmail.com, порт 587, TLS (или 465, SSL).
Логин — полный адрес ящика.
3. Вариант с плагином: WP Mail SMTP
В первой версии поста был плагин Configure SMTP. Он заброшен: последний раз обновлялся летом 2024 года и проверен только с WordPress 6.5. Сейчас я бы взял WP Mail SMTP: он живой, обновления выходят постоянно. Похожие по возможностям — FluentSMTP и Post SMTP.
В WP Mail SMTP выбираете почтовую службу «Other SMTP», вписываете сервер, шифрование, порт, логин и пароль приложения. «From Email» — тот же адрес ящика, галочка «Force From Email» — включить. Сохраняете и в разделе «Tools → Email Test» отправляете пробное письмо.
3. Вариант без плагина: файл в mu-plugins
Если не хочется ставить ещё один плагин с рекламой платной версии, хватит двадцати строк. Пароль при этом хранится в wp-config.php, а не в базе данных.
В wp-config.php перед строкой «Это всё, дальше не редактируем» (That’s all, stop editing!):
define( 'SMTP_HOST', 'smtp.yandex.ru' );
define( 'SMTP_PORT', 465 );
define( 'SMTP_USER', 'site@example.ru' );
define( 'SMTP_PASS', 'пароль-приложения' );
Файл wp-content/mu-plugins/smtp.php (папки mu-plugins может не быть — создайте):
<?php
/*
* Plugin Name: SMTP
* Description: Почта WordPress через SMTP. Настройки — константы SMTP_* в wp-config.php.
*/
add_action( 'phpmailer_init', function ( $mail ) {
$mail->isSMTP();
$mail->Host = SMTP_HOST;
$mail->Port = SMTP_PORT;
$mail->SMTPSecure = 465 == SMTP_PORT ? 'ssl' : 'tls';
$mail->SMTPAuth = true;
$mail->Username = SMTP_USER;
$mail->Password = SMTP_PASS;
} );
// Отправитель должен совпадать с ящиком, иначе SMTP-сервер откажет.
add_filter( 'wp_mail_from', function () {
return SMTP_USER;
} );
// Причина отказа — в журнал ошибок PHP.
add_action( 'wp_mail_failed', function ( $error ) {
error_log( 'wp_mail: ' . $error->get_error_message() );
} );
Плагины из mu-plugins включаются сами и не отключаются из админки — случайно не выключишь. Как это работает: перед каждой отправкой WordPress вызывает хук phpmailer_init и даёт поменять настройки встроенной библиотеки PHPMailer. Мы переключаем её с mail() на SMTP.
4. Проверка
С WP-CLI — из папки сайта:
wp eval 'var_dump( wp_mail( "вы@example.ru", "Проверка", "Письмо с сайта" ) );'
bool(true) и письмо во входящих — готово. bool(false) — причина в журнале ошибок PHP (или в wp-content/debug.log, если включён WP_DEBUG_LOG), разбор ниже. Без WP-CLI — отправьте письмо с формы на сайте или сбросьте пароль тестовому пользователю.
Грабли
@домена.SMTP_USER, даже если плагин формы попросил другой, — в WP Mail SMTP за это отвечает галочка «Force From Email». Особенно это касается старых форм обратной связи, где в поле «От» стоит адрес посетителя: в настройках формы впишите туда адрес ящика, а адрес посетителя перенесите в «Ответить» (Reply-To), чтобы на письмо можно было ответить одной кнопкой.Как это было в 2016 году
Я заводил транзитный ящик на Gmail, ставил плагин Configure SMTP, включал в нём галочку «Send e-mail via GMail?» — половина полей заполнялась сама — и вписывал логин и обычный пароль от ящика:
Схема та же, что и сейчас. Но с мая 2022 года Gmail не принимает обычный пароль от сторонних программ, а сам плагин давно не обновляется. Так что повторять один в один уже не получится — берите вариант из этого поста.
smtp.beget.com, порт 465, SSL, полный адрес ящика и пароль от него.