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

Диагностика проблемы повторной отправки писем в WooCommerce

Одной из частых проблем при работе с WooCommerce является повторная отправка уведомлений клиентам при изменении статуса заказа. Это может привести к недопониманию, раздражению клиентов и излишнему трафику к почтовому серверу.

Для диагностики проблемы выполните следующие шаги:

  • Проверьте логи почты (если ведутся) или используйте плагин WP Mail Logging для отслеживания всех отправленных писем.
  • Отследите цепочку изменений статусов заказа в админке WooCommerce (Раздел «Заказы» → конкретный заказ → История изменений).
  • Убедитесь, что не используются сторонние плагины, которые могут автоматически повторно отправлять письма при каждом обновлении заказа.
  • Проверьте код вашей темы и подключенных плагинов на наличие кастомных хуков, которые могут триггерить отправку писем.

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

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

Ниже приведён пример кода, который предотвращает повторную отправку письма при повторном переключении заказа в один и тот же статус:

add_filter('woocommerce_email_enabled_customer_completed_order', 'disable_repeated_completed_order_email', 10, 2); 
function disable_repeated_completed_order_email($enabled, $order) {
    if (!$order instanceof WC_Order) {
        return $enabled;
    }

    $sent_flag = $order->get_meta('_completed_email_sent');
    if ($sent_flag) {
        // Письмо уже отправлялось
        return false;
    }

    return $enabled;
}

add_action('woocommerce_order_status_completed', 'mark_completed_email_sent');
function mark_completed_email_sent($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) {
        return;
    }
    // Отметим факт отправки письма
    $order->update_meta_data('_completed_email_sent', 'yes');
    $order->save();
}

В данном примере мы предотвращаем повторную отправку письма «Завершённый заказ» при повторном переходе в статус completed. Аналогично можно реализовать для других статусов, изменив хуки и мета ключи.

Общие шаблоны для других статусов

add_filter('woocommerce_email_enabled_customer_processing_order', 'disable_repeated_processing_email', 10, 2);
function disable_repeated_processing_email($enabled, $order) {
    if (!$order instanceof WC_Order) {
        return $enabled;
    }
    if ($order->get_meta('_processing_email_sent')) {
        return false;
    }
    return $enabled;
}

add_action('woocommerce_order_status_processing', 'mark_processing_email_sent');
function mark_processing_email_sent($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) {
        return;
    }
    $order->update_meta_data('_processing_email_sent', 'yes');
    $order->save();
}

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

После добавления кода:

  1. Создайте или обновите заказ, переводя его в нужный статус (например, completed).
  2. Убедитесь, что письмо отправляется один раз, проверяя почтовый ящик и логи отправки.
  3. Повторно измените статус на тот же — письмо не должно отправляться второй раз.
  4. Для полной проверки можно очистить метаполя заказа (через базу или админку), чтобы сбросить флаг отправки и проверить повторную отправку.

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

  • Письма продолжают отправляться несколько раз: возможно, не все статусы обрабатываются, или код не добавлен в файл, который загружается в WooCommerce (например, functions.php дочерней темы).
  • Метаполя не сохраняются: убедитесь, что вызывается $order->save() после обновления метаданных.
  • Используются кастомные плагины с собственными отправками писем: проверьте, не дублируется ли отправка в них.
  • Кэширование мешает обновлению: очистите кэш сайта и браузера, отключите кэширование на время тестов.

Практические советы по производительности и безопасности

  • Храните флаги отправки письма в метаполях заказа – это быстро и без нагрузки на базу.
  • Используйте строгие проверки типов при работе с объектом WC_Order.
  • Добавляйте код в дочернюю тему или отдельный плагин, чтобы избежать потери изменений при обновлении WooCommerce или темы.
  • Регулярно проверяйте логи почты и статистику отправленных писем для своевременного выявления проблем.
  • Если ваши письма включают чувствительные данные, убедитесь, что доступ к метаполям ограничен и не выводится в публичных местах.

Сравнение вариантов решения

ВариантОписаниеПлюсыМинусы
Отключение через хуки и метаполяДобавление проверки метаполя для отправки письмаГибко, не требует плагинов, легко кастомизируетсяТребует ручного кода, можно забыть про другие статусы
Использование плагина управления письмамиПлагины типа WooCommerce Email Customizer с опциями отключенияПростота настройки, визуальный интерфейсДополнительная нагрузка, может быть платным
Отключение всех писем и кастомная отправкаВыключение стандартных писем и создание своих через SMTPПолный контроль над письмамиСложно, требует больше времени и знаний
Как отключить AJAX пагинацию в WordPress: практические решения
07.12.2025
WooCommerce: как отключить удаление заказа после изменения заказа программно
02.06.2026
Как удалить или изменить правила перезаписи (rewrite rules) в WordPress
03.12.2025
WooCommerce: как отключить повышение суммы платежа при изменении заказа
23.04.2026
WooCommerce: как исключить повторную отправку письма при изменении статуса заказа
20.05.2026