Документация / WordPress

Отправка почты в WordPress через SMTP

Все уведомления WordPress — восстановление пароля, регистрация, комментарии, заявки из форм, письма о заказах WooCommerce — идут через одну функцию, wp_mail(). По умолчанию она передаёт письмо в PHP mail(), и именно поэтому на множестве сайтов письма молча пропадают или попадают в спам. Ниже — как направить wp_mail() в SMTP-релей fmailer с авторизацией.

Почему письма из WordPress не доходят

Проблем на самом деле две, и обе решаются одной настройкой:

  • Отправлять некому. PHP mail() вызывает локальный sendmail. На большинстве хостингов почтового сервера там нет: вызов проходит успешно, wp_mail() возвращает true, письмо исчезает.
  • Письмо не подписано. Там, где локальный сервер всё же есть, письмо уходит без подписи DKIM и с IP-адреса, которого нет в вашей записи SPF. Для Яндекс.Почты, Mail.ru и Gmail это выглядит как подделка — письмо отправляется в спам или отклоняется.

Отправка через SMTP с авторизацией закрывает оба вопроса: релей подписывает каждое письмо ключом DKIM подтверждённого домена и отправляет с адресов, которые уже перечислены в SPF, поэтому DMARC сходится.

Логин и пароль можно получить на странице управления токенами домена.

Параметры подключения

ПараметрЗначение
SMTP-хостsmtp.fmailer.ru
Порт587
ШифрованиеSTARTTLS (соединение переводится в TLS до авторизации)
ЛогинЛогин SMTP-токена вашего домена
ПарольПароль этого токена — показывается один раз, при создании
Каждый режим доступен и на высоком порту: 8465 (SSL/TLS), 8587 (STARTTLS) и 8025 (без шифрования). Многие хостинги и облака блокируют исходящие 25, 465 и 587 — если соединение отваливается по таймауту, используйте соответствующий высокий порт

Способ 1 — плагин WP Mail SMTP

Самый распространённый вариант, со встроенной проверкой подключения. Установите его в разделе Плагины → Добавить новый, затем откройте WP Mail SMTP → Настройки:

ПолеЗначение
От (E-mail)noreply@mail.example.ru — на подтверждённом домене
Принудительно использовать этот адресВключено
От (Имя)Название сайта
Отправщик почтыOther SMTP
SMTP-хостsmtp.fmailer.ru
ШифрованиеTLS — несмотря на название, это STARTTLS
SMTP-порт587
АвторизацияВключена
Имя пользователяЛогин SMTP-токена вашего домена
ПарольПароль этого токена

Затем откройте вкладку Тест email, отправьте письмо себе и убедитесь, что оно пришло.

Уберите пароль из базы данных

Введённый через админку пароль SMTP хранится в базе в восстановимом виде. Определите его в wp-config.php — WP Mail SMTP читает эти константы и делает соответствующие поля в интерфейсе недоступными:

wp-config.phpphp
/* Добавьте ВЫШЕ строки "That's all, stop editing!" в wp-config.php */

define( 'WPMS_ON', true );                       // константы важнее настроек в админке
define( 'WPMS_MAILER', 'smtp' );

define( 'WPMS_SMTP_HOST', 'smtp.fmailer.ru' );
define( 'WPMS_SMTP_PORT', 587 );
define( 'WPMS_SSL', 'tls' );                     // 'tls' = STARTTLS, 'ssl' = порт 465
define( 'WPMS_SMTP_AUTH', true );
define( 'WPMS_SMTP_USER', '<логин токена>' );
define( 'WPMS_SMTP_PASS', '<пароль токена>' );

define( 'WPMS_MAIL_FROM', 'noreply@mail.example.ru' );
define( 'WPMS_MAIL_FROM_NAME', 'Магазин' );
define( 'WPMS_MAIL_FROM_FORCE', true );          // перебить плагины со своим отправителем

Способ 2 — плагин FluentSMTP

Полностью бесплатный, с поддержкой резервных подключений. Перейдите в Настройки → FluentSMTP → Add Another Connection, выберите Other SMTP и укажите тот же хост, порт 587, шифрование TLS и доступы токена. Отметьте пункт о хранении пароля в wp-config.php.

WP Mail SMTP, FluentSMTP и Post SMTP используют один и тот же хук phpmailer_init. Если активны два, побеждает тот, что загрузился позже, — а это выглядит как плавающая ошибка доставки.

Способ 3 — без плагина

WordPress даёт доступ к объекту PHPMailer через действие phpmailer_init, поэтому достаточно небольшого mu-плагина. Так обновление стороннего плагина никогда не изменит настройки почты:

wp-content/mu-plugins/smtp-mailer.phpphp
<?php
/**
 * Plugin Name: SMTP для wp_mail
 * Description: Отправляет все письма wp_mail() через SMTP с авторизацией.
 *
 * Сохраните как wp-content/mu-plugins/smtp-mailer.php — mu-плагины
 * подключаются автоматически и их нельзя случайно отключить из админки.
 */

add_action( 'phpmailer_init', function ( $phpmailer ) {
    $phpmailer->isSMTP();
    $phpmailer->Host       = 'smtp.fmailer.ru';
    $phpmailer->Port       = 587;
    $phpmailer->SMTPSecure = 'tls';       // STARTTLS; для порта 465 — 'ssl'
    $phpmailer->SMTPAuth   = true;
    $phpmailer->Username   = SMTP_USER;   // определены в wp-config.php
    $phpmailer->Password   = SMTP_PASS;
    $phpmailer->Timeout    = 10;
    $phpmailer->CharSet    = 'UTF-8';
} );

// Отправляем со своего домена, а не с wordpress@имя-сервера
add_filter( 'wp_mail_from', fn() => 'noreply@mail.example.ru' );
add_filter( 'wp_mail_from_name', fn() => 'Магазин' );

Константы SMTP_USER и SMTP_PASS определите рядом, в wp-config.php.

Проверка

У каждого плагина есть своя кнопка проверки, но WP-CLI вызывает настоящий wp_mail() — тот самый, который используют темы и плагины:

bash
# Тестовое письмо прямо через wp_mail()
wp eval "var_dump( wp_mail( 'you@example.ru', 'Тест SMTP', 'Работает.' ) );"

# Показать причину, если вернулось false
wp eval "add_action('wp_mail_failed', fn(\$e) => print_r(\$e->get_error_message())); wp_mail('you@example.ru','Тест','Работает.');"

Если не работает, включите подробный лог SMTP-диалога:

php
// Временно записать весь SMTP-диалог в лог, чтобы найти причину.
add_action( 'phpmailer_init', function ( $phpmailer ) {
    $phpmailer->SMTPDebug   = 2;
    $phpmailer->Debugoutput = 'error_log';
}, 100 );
SMTPDebug пишет в журнал ошибок PHP всю сессию целиком, включая обмен при авторизации. Уберите его сразу, как подключение заработает.

Разбор ошибок

СимптомПричина и решение
SMTP connect() failed Хостинг блокирует порт. Укажите 8587 (TLS) или 8465 (SSL).
SMTP Error: Could not authenticate Неверные доступы токена или выключена авторизация в плагине.
Тест проходит, а форма обратной связи — нет Плагин формы ставит свой адрес отправителя. Включите принудительную замену.
Письма приходят в спам Адрес отправителя не на подтверждённом домене — проверьте, что это не wordpress@….
Настройки верные, но ничего не изменилось Активен второй SMTP-плагин, либо кэш opcache отдаёт старый wp-config.php.
Код ответа 550 Домен отправителя не подтверждён или не покрывается токеном.

Частые вопросы

Почему WordPress вообще не отправляет письма?

По умолчанию wp_mail() передаёт письмо функции PHP mail(), а та — локальному sendmail. На большинстве современных хостингов почтового сервера за ней нет, поэтому письмо просто исчезает. Даже там, где он есть, письмо уходит без авторизации и не проходит проверки SPF, DKIM и DMARC у получателя. Отправка через SMTP решает обе проблемы сразу.

Какой плагин SMTP выбрать для WordPress?

WP Mail SMTP — самый распространённый, с понятным мастером настройки и кнопкой проверки. FluentSMTP полностью бесплатный, без платных тарифов, и умеет резервные подключения. Post SMTP — хороший третий вариант с подробным журналом. Главное — включать только один: два плагина одновременно борются за хук phpmailer_init.

Какой порт указывать — 587 или 465?

587 вместе с шифрованием TLS — в плагинах это означает STARTTLS. SSL выбирайте только вместе с портом 465. Несовпадение порта и типа шифрования — самая частая причина, по которой проверка подключения в плагине не проходит.

Почему письма всё равно попадают в спам после настройки SMTP?

Обычно потому, что адрес отправителя не на том домене, который подтверждён. Если WordPress отправляет от wordpress@имя-сервера-хостинга, а записи DKIM и SPF опубликованы на вашем домене, DMARC не сходится. Поставьте адрес на подтверждённом домене и включите принудительную замену отправителя.

Безопасно ли хранить пароль SMTP в wp-config.php?

Это безопаснее, чем поле в админке: оттуда пароль попадает в базу, а значит в любой её дамп и к любому, кто получил доступ к админке. Файл wp-config.php лежит вне базы и не отдаётся веб-сервером. Ещё лучше подставлять в константу значение из переменной окружения хостинга.

Можно ли настроить SMTP в WordPress без плагина?

Да. Перед каждой отправкой WordPress вызывает действие phpmailer_init, поэтому достаточно небольшого mu-плагина, переводящего объект PHPMailer в режим SMTP. Так обновление плагина никогда не изменит настройки почты — но не будет ни интерфейса, ни кнопки проверки, ни журнала.

Почему подключение отваливается по таймауту?

Многие хостинги блокируют исходящие подключения на порты 25, 465 и 587, чтобы ограничить спам со взломанных сайтов. Укажите порт 8587 для STARTTLS или 8465 для SSL — соединение установится.

Что дальше