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

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

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

Когда дубли писем появляются чаще всего

Сценарии обычно повторяются. После обновления плагина или темы письма начинают уходить дважды. На сайте с кастомной оплатой уведомления дублируются только для части заказов. Иногда проблема проявляется не сразу, а только при повторной смене статуса заказа через админку или через внешний webhook.

Чаще всего причина одна из трёх:

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

Диагностика: где искать источник дублей

Начинать лучше не с правки кода, а с фиксации факта повторного вызова. Если у вас есть доступ к логам WooCommerce и к серверным логам PHP, проверьте, не совпадают ли время отправки и повторного срабатывания обработчика.

Что проверить в админке и логах

  • Настройки уведомлений WooCommerce: не включены ли одновременно штатное письмо и письмо от стороннего плагина.
  • Кастомные сниппеты в functions.php, mu-plugins и плагинах для магазина.
  • Логи почтового плагина, если отправка идёт через SMTP.
  • Историю изменения статуса заказа: иногда письмо дублируется из-за цепочки pendingprocessingcompleted.

Минимальная проверка через логирование

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

add_action( 'woocommerce_order_status_processing', function( $order_id ) {
    if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
        error_log( 'Processing status fired for order: ' . $order_id );
    }
}, 10, 1 );

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

Как исправить дубли отправки: рабочая схема

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

Шаг 1. Уберите повторную подписку на хук

Иногда проблема банальна: один и тот же add_action() добавлен в двух местах. Это особенно часто случается после переноса кода из темы в мини-плагин, когда старый фрагмент забывают удалить.

remove_action( 'woocommerce_order_status_completed', 'my_send_custom_email', 10 );

add_action( 'woocommerce_order_status_completed', 'my_send_custom_email', 10, 1 );
function my_send_custom_email( $order_id ) {
    // ваша логика
}

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

Шаг 2. Защититесь от повторного запуска

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

add_action( 'woocommerce_order_status_processing', 'my_send_once_email', 10, 1 );
function my_send_once_email( $order_id ) {
    $order = wc_get_order( $order_id );
    if ( ! $order ) {
        return;
    }

    if ( $order->get_meta( '_my_custom_email_sent' ) ) {
        return;
    }

    // Отправка письма или вызов вашей функции уведомления.
    wp_mail( get_option( 'admin_email' ), 'Заказ в обработке', 'Заказ #' . $order_id . ' перешёл в статус processing.' );

    $order->update_meta_data( '_my_custom_email_sent', time() );
    $order->save();
}

Такой вариант особенно полезен, если письмо отправляется не через штатные email-шаблоны WooCommerce, а через собственную бизнес-логику.

Шаг 3. Не вызывайте wp_mail() там, где нужен email WooCommerce

Если задача — изменить содержимое стандартного письма, лучше использовать фильтры и шаблоны WooCommerce, а не отправлять отдельное письмо вручную. Иначе вы получите два уведомления: штатное и кастомное.

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

Сравнение подходов: плагин, код или настройка

ПодходКогда подходитПлюсыМинусы
Настройки WooCommerceЕсли дубли вызваны включёнными уведомлениямиБыстро, без кодаНе решает проблему кастомных хук-обработчиков
Код с флагом в metaЕсли письмо должно уходить один разКонтроль, предсказуемостьНужно поддерживать код
Сторонний SMTP-плагинЕсли проблема в доставке, а не в дубляхУлучшает отправкуНе устраняет повторный запуск логики

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

После исправления важно не ограничиваться одним тестовым заказом. Проверьте несколько сценариев: новый заказ, смена статуса вручную, повторное сохранение заказа в админке, тестовый webhook от платёжного шлюза.

  • Создайте тестовый заказ и убедитесь, что письмо приходит один раз.
  • Измените статус заказа вручную и проверьте, не уходит ли повторное уведомление.
  • Посмотрите логи PHP и почтового плагина: количество событий должно совпадать с количеством реальных действий.
  • Если используется флаг в meta, убедитесь, что он записывается после первой отправки.

Полезно также проверить, не ломается ли логика для администраторских писем и писем клиенту отдельно. Иногда дубли появляются только в одном из каналов.

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

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

Обычно это значит, что обработчик подписан на несколько событий сразу, например на woocommerce_order_status_processing и woocommerce_order_status_completed. Если нужен только один триггер, оставьте один хук.

Дубли появляются только при оплате через внешний шлюз

Проверьте, не делает ли шлюз повторный callback. У платёжных интеграций это встречается при повторной доставке webhook, если сервер долго отвечает или возвращает ошибку. В таком случае защита через meta-флаг обязательна.

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

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

После удаления дублей перестали приходить нужные письма

Частая причина — слишком жёсткая защита. Если флаг в meta ставится раньше фактической отправки, повторный запуск будет заблокирован даже при ошибке SMTP. В таком случае записывайте флаг только после успешного вызова отправки или обрабатывайте ошибку отдельно.

Что сделать для безопасности и стабильности

Если вы правите уведомления кодом, не вносите изменения прямо в тему, которая обновляется. Лучше использовать мини-плагин или mu-plugin, чтобы логика не пропала после апдейта. Это особенно важно для магазинов, где письма связаны с оплатой и статусами заказов.

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

Если нужен дополнительный контроль за состоянием сайта и ошибками PHP, удобно держать под рукой мониторинг вроде WPCheck, а для чистки лишнего кода и дублей в проекте — инструменты наподобие Clearfy Pro. Но саму проблему дублей писем всё равно решает не плагин «для галочки», а точная проверка хука и точки отправки.

В итоге рабочая схема простая: найти, где именно запускается отправка, убрать повторную регистрацию, добавить защиту от повторного выполнения и проверить несколько сценариев заказа. Это быстрее и надёжнее, чем пытаться «лечить» дубли переустановкой SMTP или сменой почтового сервиса.

Добавь в закладки и поделись с друзьями:

⭐⭐⭐⭐⭐
Как отключить autoload для плагинов в WordPress и улучшить производительность
01.03.2026
Как защитить WordPress от ботов и спама в 2024 году
22.02.2026
Диагностика и решение проблемы с неработающими webhook в WooCommerce
24.06.2026
Диагностика и решение проблем с неработающими AJAX-запросами в WooCommerce
07.05.2026
Как удалить заблокированные плагины в WordPress: практическое решение
23.03.2026
×

AI-плагин от WPShop.ru

анализирует конкурентов

пишет статьи

готовит SEO

генерирует изображения

и еще кое-что...
WPGPT
Плагин, который наполняет ваш сайт WordPress
Узнать больше