WooCommerce: как исключить повторную отправку письма при изменении статуса заказа

Проблема повторной отправки писем при смене статуса заказа в WooCommerce

В WooCommerce при изменении статуса заказа часто автоматически отправляются уведомления на email клиента. При частых изменениях статусов письма могут дублироваться, что раздражает покупателей и увеличивает нагрузку на почтовый сервер. Это происходит из-за повторного срабатывания хуков, отвечающих за отправку писем. В статье разберём, как диагностировать эту проблему, и покажем, как исключить повторную отправку писем без отключения уведомлений полностью.

Диагностика проблемы: как понять, что письма отправляются повторно

Для начала убедитесь, что действительно происходит повторная отправка письма при изменении статуса. Для этого:

  • Перейдите в админку WooCommerce → Заказы;
  • Выберите любой заказ и измените статус, например, со «В обработке» на «Выполнен»;
  • Проверьте почтовый ящик клиента — должно прийти одно письмо с уведомлением;
  • Повторите изменение статуса обратно и снова вперёд;
  • Если письма приходят каждый раз и вы подозреваете, что они дублируются, проблема налицо.

Также можно включить логирование почтовых событий через плагин WP Mail Logging. Это позволит увидеть, сколько писем и при каких событиях отправляется.

Пошаговое решение: отключаем повторную отправку писем при смене статуса

WooCommerce отправляет письма с помощью класса WC_Email. Чтобы исключить повторную отправку, нам нужно контролировать, чтобы письмо отправлялось только при первом изменении нужного статуса, а при повторных изменениях не отправлялось.

Пример кода, который можно добавить в functions.php вашей темы или в свой плагин:

add_filter('woocommerce_email_enabled_customer_completed_order', 'disable_duplicate_completed_order_email', 10, 2);

function disable_duplicate_completed_order_email($enabled, $order) {
    // Получаем ID заказа
    $order_id = $order->get_id();

    // Используем transient для хранения факта отправки письма
    $transient_key = 'completed_email_sent_' . $order_id;

    if (get_transient($transient_key)) {
        // Письмо уже отправлялось, отключаем повторную отправку
        return false;
    }

    // Устанавливаем флаг на 24 часа
    set_transient($transient_key, true, DAY_IN_SECONDS);

    return $enabled;
}

Этот фильтр отключает повторную отправку письма «Заказ выполнен» клиенту. Аналогично можно добавить для других статусов, меняя фильтр:

  • woocommerce_email_enabled_customer_processing_order — для статуса «В обработке»;
  • woocommerce_email_enabled_customer_on_hold_order — для «Ожидает оплаты»;
  • и так далее.

Важный момент: get_transient и set_transient применяются для хранения флага отправки письма на стороне сервера, что исключает повторную отправку в течение указанного времени.

Альтернативный способ: отмена отправки в момент смены статуса

Если нужно точечно контролировать отправку, можно использовать хук woocommerce_order_status_changed и отключать письмо в зависимости от условий:

add_action('woocommerce_order_status_changed', 'custom_prevent_duplicate_email', 10, 4);

function custom_prevent_duplicate_email($order_id, $old_status, $new_status, $order) {
    if ($new_status === 'completed') {
        // Удаляем флаг, если нужно сбросить ограничение
        delete_transient('completed_email_sent_' . $order_id);
    }
}

Этот код удаляет флаг при смене статуса, позволяя отправить письмо заново, если это действительно нужно.

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

  • Сделайте несколько смен статусов заказа с теми, для которых вы отключили повторную отправку;
  • Проверьте почтовый ящик — письма должны приходить только при первом переходе в статус, а повторно — не приходить;
  • Включите логирование почты и убедитесь, что количество отправленных писем соответствует ожидаемому;
  • Проверьте, что другие уведомления WooCommerce продолжают работать без сбоев.

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

  • Письма продолжают дублироваться: возможно, вы не применили фильтр к нужному событию или используете кастомные статусы без поддержки в коде. Проверьте все статусы и хуки.
  • Письма не отправляются вовсе: проверьте, не возвращаете ли вы false в фильтре всегда, а не только при дубликате.
  • Транзиенты не работают: убедитесь, что на вашем сервере настроен корректный кеш, или замените транзиенты на пользовательские опции в базе данных.
  • Конфликты с плагинами SMTP или кэширования: временно отключите их, чтобы проверить влияние на отправку писем.

Практические советы по оптимизации и безопасности

  • Используйте транзиенты для минимизации нагрузки на базу данных и уменьшения количества отправляемых писем.
  • Внедряйте логи почты (например, с помощью WP Mail Logging) для мониторинга отправки и быстрого выявления проблем.
  • Для кастомных статусов создавайте свои фильтры по аналогии с WooCommerce, чтобы полностью контролировать почтовые уведомления.
  • Перед изменениями на рабочем сайте тестируйте код на локальной или staging-среде.
  • Следите за обновлениями WooCommerce — иногда меняется логика отправки писем и хуки.

Сравнение способов решения проблемы повторной отправки писем

МетодПримерПреимуществаНедостатки
Фильтр включения писемИспользование woocommerce_email_enabled_customer_completed_orderПростота, минимальное вмешательство, легко расширятьТребует добавления фильтров для каждого типа письма
Обработка события смены статусаХук woocommerce_order_status_changed и удаление транзиентовГибкость, можно сбрасывать флаги и контролировать отправку динамическиСложнее в поддержке, требует аккуратности
Отключение уведомлений плагиномПлагины типа Disable EmailsПростота для начинающихПолное отключение, отсутствие гибкости
WooCommerce: как исключить повторную отправку письма при изменении статуса заказа
03.05.2026
Как удалить все комментарии в WordPress: пошаговое руководство
19.11.2025
Как изменить метод AJAX обработки формы на REST API в WordPress
30.03.2026
Как удалить неактуальные метаданные в WordPress: оптимизация базы данных
04.01.2026
Как создать автоматический отзыв в WordPress на основе плагина Quizle
30.03.2026