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

Почему WooCommerce отправляет повторные письма при изменении статуса заказа

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

Частая причина — использование стандартных хуков woocommerce_order_status_{$status}_notification, которые срабатывают при каждом изменении. Если заказ переводится в один и тот же статус несколько раз, письмо уйдет повторно.

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

  • Проверьте логи почты (если настроены через SMTP-плагин или WP Mail Logging) на повторяющиеся уведомления со схожим временем и содержанием.
  • Просмотрите статус заказа в админке WooCommerce: если он меняется несколько раз в один и тот же статус, вероятность повторной отправки высока.
  • Оцените, используются ли кастомные скрипты или плагины, которые программно меняют статус и вызывают уведомления.

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

Основная идея — использовать мета-данные заказа для фиксации факта отправки письма и проверять это перед повторной отправкой.

Шаг 1. Добавьте проверку перед отправкой письма

В functions.php вашей темы или в кастомном плагине добавьте следующий код:

add_filter('woocommerce_email_enabled_customer_processing_order', 'disable_duplicate_processing_email', 10, 2);
add_filter('woocommerce_email_enabled_customer_completed_order', 'disable_duplicate_completed_email', 10, 2);

function disable_duplicate_processing_email($enabled, $order) {
    return prevent_duplicate_email($enabled, $order, 'processing_email_sent');
}

function disable_duplicate_completed_email($enabled, $order) {
    return prevent_duplicate_email($enabled, $order, 'completed_email_sent');
}

function prevent_duplicate_email($enabled, $order, $meta_key) {
    if (!$enabled || !$order instanceof WC_Order) {
        return $enabled;
    }

    // Проверяем, отправлялось ли письмо
    if ($order->get_meta($meta_key)) {
        return false; // Блокируем повторную отправку
    }

    // Сохраняем метаданные после успешной отправки
    add_action('woocommerce_email_after_send', function($email_sent, $email, $order_obj) use ($meta_key, $order) {
        if ($email_sent && $order->get_id() === $order_obj->get_id()) {
            $order->update_meta_data($meta_key, 'yes');
            $order->save();
        }
    }, 10, 3);

    return $enabled;
}

Этот пример отключает повторную отправку писем для статусов "processing" и "completed". При первой отправке сохраняется мета-данное, которое служит флагом.

Шаг 2. Удаление мета-данных для повторной отправки при необходимости

Если нужно повторно отправить письмо (например, после исправления ошибки), можно удалить мета-данные через консоль или вручную:

$order = wc_get_order(123); // ID заказа
$order->delete_meta_data('processing_email_sent');
$order->delete_meta_data('completed_email_sent');
$order->save();

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

  • Создайте тестовый заказ и переведите его в статус "Обработка" (processing). Убедитесь, что письмо уходит.
  • Переведите заказ снова в "Обработка" — письмо повторно не должно отправиться.
  • Повторите для статуса "Выполнен" (completed).
  • Проверьте логи почты и убедитесь, что уведомления не дублируются.

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

  • Письма продолжают отправляться повторно: возможно, мета-данные не сохраняются из-за конфликтов в коде или кэширования. Проверьте права на запись в базу и отключите кэширование при тестах.
  • Код не работает для других статусов: добавьте новые фильтры для нужных статусов, например woocommerce_email_enabled_customer_on-hold_order.
  • Ошибка «Call to undefined function»: убедитесь, что код добавлен в правильное место (functions.php или плагин), и что WooCommerce активен.

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

  • Используйте конкретные хуки WooCommerce для управления почтовыми уведомлениями, чтобы не влиять на другие процессы.
  • Кэширование мета-данных заказа снижает нагрузку на базу, но при работе с почтой лучше кэш временно отключать.
  • Тестируйте изменения на staging-сайте, чтобы избежать сбоев в рабочем магазине.

Таблица сравнения решений для исключения повторной отправки писем

СпособПреимуществаНедостатки
Кастомный фильтр с мета-даннымиГибкий, не требует сторонних плагинов, легко расширяетсяНужно писать код, возможно конфликт с другими кастомизациями
Плагины для управления письмамиПростота настройки, готовые функцииМогут замедлять сайт, не всегда гибкие под уникальные задачи
Отключение писем полностьюПростой способ избежать дублированияПотеря информирования клиентов, неудобно
WooCommerce: как использовать хуки для изменения статей оплаты
07.05.2026
Как изменить автоматический slug в WordPress: практические решения и примеры кода
29.12.2025
Как создать автоматический отзыв в WordPress на основе плагина Quizle
30.03.2026
Как удалить изображения и медиафайлы в WordPress без ошибок и потери данных
19.01.2026
WordPress: как исправить отсутствие изображения в превью и постах
09.04.2026