Как настроить отправку заказов WooCommerce на email без дублей и сбоев

Проблема с письмами WooCommerce обычно всплывает не сразу: заказ в админке есть, клиент оплатил, а уведомление менеджеру не пришло. Или пришло два раза. Или письмо уходит только после ручного обновления страницы. В таких случаях искать причину нужно не в одном месте, а по цепочке: настройки магазина, SMTP, плагины, хуки и логи отправки.

Когда это действительно проблема WooCommerce, а не почты сервера

Сначала важно отделить сбой отправки от обычной задержки почтового сервера. Если письма не доходят только с сайта, но отправка с хостинга работает, чаще всего дело в WordPress-почте, а не в домене или DNS. Если же письма уходят, но попадают в спам, нужно проверять SPF, DKIM и From-адрес, а не код темы.

Типовые симптомы

  • уведомления о новом заказе не приходят на email администратора;
  • письмо клиенту уходит, но без части данных заказа;
  • одно и то же письмо приходит дважды;
  • уведомление отправляется только после повторного сохранения заказа;
  • письма есть в логах WordPress, но отсутствуют у получателя.

Диагностика: что проверить до правки кода

Начинайте с настроек WooCommerce. В разделе WooCommerce → Настройки → Email проверьте, включены ли нужные уведомления и корректно ли указан адрес получателя. Для уведомления Новый заказ часто забывают проверить несколько полей: получатель, заголовок письма и шаблон, который переопределён в теме.

Дальше смотрите, не вмешивается ли в отправку сторонний плагин. Почтовые SMTP-плагины, плагины логирования и антиспам-фильтры могут менять заголовки письма или повторно запускать отправку. Если письмо дублируется, это почти всегда признак того, что один и тот же триггер срабатывает дважды: через WooCommerce-хук и через стороннюю интеграцию.

Полезно временно включить логирование отправки. Если у вас уже установлен плагин для SMTP с журналом, посмотрите, создаётся ли запись на каждую попытку. Если логов нет, а письма не уходят, проблема может быть на уровне wp_mail() или конфигурации сервера.

Рабочая схема: отправка через SMTP и контроль хуков

Для стабильной доставки лучше не полагаться на стандартную отправку PHP mail. На практике безопаснее использовать SMTP через нормальный почтовый сервис и оставить WooCommerce только генерацию события. Это не решает все проблемы, но резко снижает число ложных сбоев.

Если вам нужно добавить собственное письмо менеджеру, не дублируя стандартное уведомление WooCommerce, используйте отдельный хук и проверку статуса заказа. Например, отправляйте письмо только при переходе в processing, а не при каждом сохранении заказа.

<?php
add_action( 'woocommerce_order_status_processing', 'wordpressy_send_manager_email_once', 10, 1 );

function wordpressy_send_manager_email_once( $order_id ) {
    $order = wc_get_order( $order_id );
    if ( ! $order ) {
        return;
    }

    // Защита от повторной отправки.
    if ( $order->get_meta( '_wordpressy_manager_email_sent' ) ) {
        return;
    }

    $to      = get_option( 'admin_email' );
    $subject = sprintf( 'Новый заказ #%s', $order->get_order_number() );
    $message = sprintf(
        "Поступил новый заказ #%s\nСумма: %s\nСтатус: %s",
        $order->get_order_number(),
        $order->get_formatted_order_total(),
        wc_get_order_status_name( $order->get_status() )
    );

    $headers = array( 'Content-Type: text/plain; charset=UTF-8' );

    if ( wp_mail( $to, $subject, $message, $headers ) ) {
        $order->update_meta_data( '_wordpressy_manager_email_sent', time() );
        $order->save();
    }
}

Здесь важны две вещи: отправка привязана к конкретному статусу и есть метка в метаполях заказа. Без этой метки письмо легко улетит повторно, если заказ пересохранится или хук сработает ещё раз из-за интеграции.

Если письмо нужно не менеджеру, а в отдельный сервис

Иногда удобнее не слать письмо напрямую, а передавать данные в почтовый сервис или CRM через HTTP-запрос. Это полезно, когда нужны шаблоны, трекинг открытий или контроль очереди. Но даже в этом случае не отправляйте запрос на каждом сохранении заказа без проверки статуса и без защиты от повторов.

<?php
add_action( 'woocommerce_order_status_completed', 'wordpressy_send_order_to_webhook', 10, 1 );

function wordpressy_send_order_to_webhook( $order_id ) {
    $order = wc_get_order( $order_id );
    if ( ! $order || $order->get_meta( '_wordpressy_webhook_sent' ) ) {
        return;
    }

    $response = wp_remote_post( 'https://example.com/webhook/orders', array(
        'timeout' => 10,
        'headers' => array(
            'Content-Type' => 'application/json',
        ),
        'body' => wp_json_encode( array(
            'order_id' => $order->get_id(),
            'number'    => $order->get_order_number(),
            'total'     => $order->get_total(),
            'email'     => $order->get_billing_email(),
        ) ),
    ) );

    if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) >= 200 && wp_remote_retrieve_response_code( $response ) < 300 ) {
        $order->update_meta_data( '_wordpressy_webhook_sent', time() );
        $order->save();
    }
}

Сравнение подходов

ПодходКогда подходитМинус
Стандартный wp_mail()Простые уведомления без внешних сервисовЗависит от конфигурации сервера и часто хуже доставляется
SMTP-плагинНужна нормальная доставка писем и журнал отправкиПоявляется ещё один слой настройки
Webhook/CRMНужно передавать заказ в стороннюю системуНужно отдельно обрабатывать ошибки и повторы

Проверка результата после внедрения

После изменений не ограничивайтесь тестовым заказом в админке. Проверьте весь путь:

  • создайте тестовый заказ в магазине;
  • переведите его в нужный статус вручную, если письмо завязано на статус;
  • проверьте, что письмо пришло один раз;
  • посмотрите заголовки письма и адрес From;
  • откройте журнал SMTP или логи сервера;
  • убедитесь, что повторное сохранение заказа не создаёт дубль.

Если письмо не приходит, но в логах есть успешная отправка, проблема чаще всего в доменной аутентификации почты или фильтрации на стороне получателя. Если письмо приходит дважды, ищите второй триггер: сторонний плагин, кастомный код в теме или повторную отправку через action scheduler.

Частые ошибки и как их исправить

Письмо отправляется дважды

Обычно это происходит, когда один и тот же хук подключён в двух местах: в плагине и в теме. Ещё одна причина — отсутствие проверки метаполя, которое фиксирует факт отправки. Решение простое: оставьте один источник отправки и добавьте защиту от повторов.

Уведомление не приходит после оплаты

Часто письмо привязано к статусу processing, а заказ уходит сразу в completed или наоборот. Проверьте, какой статус выставляет платёжный шлюз. Для некоторых шлюзов логичнее использовать woocommerce_payment_complete, а не хук статуса.

Письмо уходит, но попадает в спам

Здесь кодом проблему не закрыть. Нужны корректные записи SPF и DKIM, совпадение домена в From и реальный SMTP-отправитель. Если отправка идёт с общего хостинга без авторизации, доставляемость почти всегда хуже.

Шаблон письма сломан после обновления темы

Если тема переопределяет шаблоны WooCommerce, обновление может сломать верстку уведомлений. Проверьте папку woocommerce/emails в теме и сравните её с актуальной версией шаблонов WooCommerce. Иногда проще убрать переопределение и настроить письмо через стандартные фильтры.

Что стоит учесть для безопасности и производительности

Не отправляйте письма синхронно в тяжёлых циклах без необходимости. Если заказов много, длинная отправка может замедлять оформление. Для внешних интеграций лучше использовать очередь или хотя бы минимальный таймаут и проверку ответа.

Не храните в коде секреты SMTP и токены вебхуков. Передавайте их через настройки плагина, переменные окружения или конфиг вне репозитория. И не забывайте, что любой кастомный email-код должен быть отключаемым: после обновления магазина его проще диагностировать, если он вынесен в отдельный мини-плагин, а не спрятан в functions.php.

Если нужно быстро убрать лишние дублирующиеся уведомления и подчистить типовые SEO/технические настройки сайта, иногда удобнее сначала пройтись по базовой гигиене проекта с помощью Clearfy Pro: https://wpshop.ru/plugins/clearfy. Но для самой почтовой логики всё равно нужен отдельный разбор настроек и хуков WooCommerce.

Как установить приватный REST API в WordPress
31.01.2026
Автоматическое изменение цены товара при обновлении в WooCommerce
22.04.2026
Как разделить комментарии на страницы в WordPress для улучшения производительности и удобства
14.12.2025
Автоматизация удаления старого кеша WooCommerce для стабильной работы сайта
21.07.2026
Автоматическое отслеживание изменений остатков товаров в WooCommerce
04.05.2026