В WooCommerce часто нужно не выключить все письма, а убрать только часть уведомлений: например, не слать клиенту письмо при переходе заказа в processing, но оставить уведомление о completed; или отключить письма менеджеру для тестовых статусов. Делать это через настройки админки получается не всегда: стандартные переключатели покрывают только базовые сценарии, а в реальном магазине статусы и логика оплаты обычно сложнее.
Ниже — рабочий способ отключать email точечно, без правки ядра и без выдуманных хуков. Подход подходит, если вы контролируете тему или используете небольшой mu-plugin.
Когда стандартных настроек WooCommerce уже недостаточно
Проблема обычно проявляется так: заказ меняет статус, а письма уходят не туда, не тем людям или слишком часто. Это особенно заметно, если у вас есть:
- кастомные статусы заказа;
- частичная предоплата и ручная проверка;
- интеграции с CRM, где письмо дублирует другое уведомление;
- тестовый магазин, где лишние письма мешают проверке оплаты.
Если отключить email целиком в WooCommerce → Настройки → Email, вы потеряете и полезные уведомления. Поэтому лучше вмешиваться на уровне конкретного класса письма и конкретного статуса.
Что именно можно отключать
В WooCommerce письма представлены объектами классов, например WC_Email_Customer_Completed_Order или WC_Email_New_Order. Это удобно: можно не трогать шаблоны и не отключать отправку глобально, а убрать только один тип уведомления при определённом условии.
| Подход | Плюсы | Минусы |
|---|---|---|
| Настройки в админке | Без кода, быстро | Не хватает точности для сложных сценариев |
| Фильтр в коде | Можно отключить письмо по статусу, роли, способу оплаты | Нужно аккуратно тестировать |
| Плагин для управления письмами | Удобный интерфейс | Дополнительная зависимость и риск конфликтов |
Диагностика: какое письмо уходит и на каком этапе
Перед изменениями важно понять, что именно срабатывает. Иначе легко отключить не то уведомление и потом долго искать причину. Самый практичный способ — посмотреть, какой статус получает заказ и какое письмо привязано к этому переходу.
Проверьте:
- какой статус у заказа до и после изменения;
- какое письмо приходит клиенту или администратору;
- не отправляет ли письмо сторонний плагин, а не WooCommerce;
- не дублируется ли уведомление через SMTP-плагин, CRM или webhook.
Если письмо приходит дважды, сначала отключите внешние интеграции на тестовом заказе. Иначе вы будете править WooCommerce, а источник дубля останется в другом месте.
Решение: отключаем письмо для конкретного статуса через фильтр
Для большинства задач достаточно фильтра woocommerce_email_enabled_{$email_id}. WooCommerce вызывает его для каждого письма и позволяет вернуть false, если отправку нужно заблокировать.
Ниже пример: отключаем письмо клиенту о выполненном заказе, если заказ перешёл в статус on-hold или processing. Логику можно адаптировать под свои статусы.
<?php
add_filter( 'woocommerce_email_enabled_customer_completed_order', 'wpteam_disable_completed_email_for_specific_status', 10, 2 );
function wpteam_disable_completed_email_for_specific_status( $enabled, $order ) {
if ( ! $order instanceof WC_Order ) {
return $enabled;
}
$status = $order->get_status();
if ( in_array( $status, array( 'on-hold', 'processing' ), true ) ) {
return false;
}
return $enabled;
}
Если нужно отключить письмо администратору о новом заказе только для определённого способа оплаты, можно добавить проверку по payment_method:
<?php
add_filter( 'woocommerce_email_enabled_new_order', 'wpteam_disable_new_order_email_for_test_gateway', 10, 2 );
function wpteam_disable_new_order_email_for_test_gateway( $enabled, $order ) {
if ( ! $order instanceof WC_Order ) {
return $enabled;
}
if ( 'bacs' === $order->get_payment_method() ) {
return false;
}
return $enabled;
}
Оба примера лучше размещать в небольшом mu-plugin, а не в functions.php активной темы. Так вы не потеряете настройку при смене темы.
Если нужен более точный контроль по статусам
Иногда удобнее не отключать письмо по имени email-класса, а проверять сам переход статуса. Для этого можно использовать хук woocommerce_order_status_changed и записывать флаг в мета заказа, а затем читать его в фильтре отправки. Это полезно, если решение зависит от нескольких условий сразу.
<?php
add_action( 'woocommerce_order_status_changed', 'wpteam_mark_order_for_no_email', 10, 4 );
function wpteam_mark_order_for_no_email( $order_id, $old_status, $new_status, $order ) {
if ( 'processing' === $new_status && 'cod' === $order->get_payment_method() ) {
$order->update_meta_data( '_wpteam_skip_completed_email', 'yes' );
$order->save();
}
}
add_filter( 'woocommerce_email_enabled_customer_completed_order', 'wpteam_skip_completed_email_by_meta', 10, 2 );
function wpteam_skip_completed_email_by_meta( $enabled, $order ) {
if ( ! $order instanceof WC_Order ) {
return $enabled;
}
if ( 'yes' === $order->get_meta( '_wpteam_skip_completed_email' ) ) {
return false;
}
return $enabled;
}
Такой вариант полезен, если отключение зависит не только от текущего статуса, но и от истории заказа.
Пошаговая настройка без лишнего риска
- Создайте резервную копию файлов и базы.
- Определите, какое письмо нужно отключить: клиентское, админское или письмо для конкретного статуса.
- Добавьте код в mu-plugin или в отдельный мини-плагин.
- Проверьте условие на тестовом заказе.
- Убедитесь, что другие письма продолжают отправляться.
Если вы не используете mu-plugin, создайте файл wp-content/mu-plugins/disable-woo-emails.php. Это простой способ держать такую логику отдельно от темы:
<?php
/**
* Plugin Name: Disable selected WooCommerce emails
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
add_filter( 'woocommerce_email_enabled_customer_completed_order', function( $enabled, $order ) {
if ( $order instanceof WC_Order && 'processing' === $order->get_status() ) {
return false;
}
return $enabled;
}, 10, 2 );
Как проверить, что решение сработало
Проверка должна быть не только визуальной. После внедрения сделайте тестовый заказ и пройдите по сценарию, который вы отключали.
- Создайте заказ с нужным способом оплаты.
- Переведите его в целевой статус вручную или через оплату.
- Проверьте, что письмо не пришло клиенту или администратору.
- Откройте журнал почты, если используете SMTP-плагин с логированием.
- Убедитесь, что другие уведомления по этому заказу остались активными.
Если письма всё равно уходят, проверьте, не отправляет ли их другой плагин. Часто это видно по теме письма, отправителю или по журналу SMTP.
Частые ошибки и как их исправить
Фильтр написан с неправильным email ID
В WooCommerce имя фильтра зависит от ID письма. Если вы указали несуществующий ID, код просто не сработает. Сверяйте имя класса письма в настройках WooCommerce или в исходниках плагина, если у вас кастомная сборка.
Проверка статуса идёт по неправильному значению
В WC_Order::get_status() статус возвращается без префикса wc-. То есть нужно сравнивать с processing, а не с wc-processing. Это частая причина, почему условие всегда мимо.
Код добавлен в тему и потерялся после обновления
Если логика важна для магазина, не храните её в шаблоне темы. Используйте mu-plugin или отдельный плагин. Это особенно важно для интернет-магазинов, где письма связаны с оплатой и поддержкой клиентов.
Отключили не то письмо
Иногда администратор хочет убрать письмо клиенту, но случайно отключает уведомление менеджеру о новом заказе. Перед публикацией кода проверьте, какой именно email ID вы меняете: new_order, customer_processing_order, customer_completed_order и так далее.
Что учесть для безопасности и производительности
Сама проверка через фильтр почти не нагружает сайт, если не делать тяжёлых запросов к базе в каждом вызове. Не добавляйте внутри фильтра сложные выборки, если можно обойтись статусом заказа или мета-полем.
Если вы используете SMTP-плагин с логированием, периодически чистите старые логи. Иначе отладка писем превращается в лишнюю нагрузку на базу и файловую систему. Для магазинов с высокой активностью лучше хранить такую логику отдельно и документировать, какие письма отключены и почему.
Если нужна не точечная правка, а более удобное управление письмами через интерфейс, можно посмотреть в сторону специализированных плагинов для WooCommerce email-уведомлений. Но даже тогда кодовый фильтр остаётся полезным, когда нужно исключение по условию, а не просто переключатель.