В WooCommerce письма о заказах часто начинают мешать не тогда, когда магазин только запустили, а когда появляются дополнительные статусы, автоматизации, менеджеры и интеграции. Типичный сценарий: заказ переходит в промежуточный статус, а клиенту или администратору уходит лишнее письмо. В итоге почта засоряется, менеджеры путаются, а некоторые уведомления дублируются внешними сервисами.
Ниже — рабочий способ отключить отправку писем для конкретных статусов заказа без выдуманных хуков и без правки ядра. Подход подходит, если нужно оставить WooCommerce как есть, но убрать лишние уведомления точечно.
Когда это действительно нужно
Отключать письма имеет смысл не «на всякий случай», а в конкретных ситуациях:
- заказ переводится в промежуточный статус
on-hold,processingили кастомный статус, но письмо клиенту не нужно; - уведомления уже отправляет CRM, ERP или сервис рассылок, а WooCommerce только дублирует их;
- в магазине много ручных изменений статусов, и администраторы получают слишком много служебных писем;
- нужно оставить только критичные уведомления, например о новом заказе и возврате, а остальные убрать.
Диагностика: какие письма WooCommerce отправляет по статусам
Сначала важно понять, какое именно письмо вы хотите отключить. В WooCommerce письма привязаны не только к статусу, но и к событию. Например, письмо клиенту о заказе в обработке обычно связано с переходом в processing, а письмо о завершении — со статусом completed.
Проверять нужно так:
- Откройте WooCommerce → Настройки → Письма.
- Посмотрите список уведомлений и их включённые/выключенные состояния.
- Проверьте, какой статус меняется в заказе в момент отправки письма.
- Если письмо приходит не из WooCommerce, а из SMTP-плагина, CRM или webhook, отключение в WooCommerce не поможет.
Если нужно быстро понять источник, сделайте тестовый заказ и вручную переведите его в нужный статус. Если письмо приходит сразу после смены статуса, значит задача решается на уровне WooCommerce-хуков.
Как отключить письма для конкретных статусов заказа
Самый надёжный вариант — использовать фильтр woocommerce_email_enabled_{$email_id}. Он позволяет выключать конкретное письмо в зависимости от заказа и его статуса. Это лучше, чем отключать письмо глобально в настройках, потому что вы сохраняете контроль над логикой.
Пример: отключим письмо клиенту о заказе в обработке, если заказ находится в статусе on-hold или в кастомном статусе awaiting-payment.
add_filter( 'woocommerce_email_enabled_customer_processing_order', function( $enabled, $order ) {
if ( ! $order instanceof WC_Order ) {
return $enabled;
}
$blocked_statuses = array( 'on-hold', 'awaiting-payment' );
if ( in_array( $order->get_status(), $blocked_statuses, true ) ) {
return false;
}
return $enabled;
}, 10, 2 );Здесь customer_processing_order — это ID письма WooCommerce. Аналогично можно работать и с другими письмами, например:
customer_completed_order;customer_on_hold_order;new_order;failed_order;cancelled_order.
Если нужно отключить письмо администратору при определённом статусе, логика та же, только меняется ID письма.
add_filter( 'woocommerce_email_enabled_new_order', function( $enabled, $order ) {
if ( ! $order instanceof WC_Order ) {
return $enabled;
}
if ( 'pending' === $order->get_status() ) {
return false;
}
return $enabled;
}, 10, 2 );Если статус кастомный
Кастомные статусы часто появляются из плагинов доставки, оплаты или внутренней автоматизации. В таком случае сравнивайте именно slug статуса, а не его отображаемое название. WooCommerce хранит статус без префикса wc-, поэтому для статуса wc-awaiting-shipment в коде обычно используется awaiting-shipment.
Если не уверены, какой slug у статуса, откройте заказ в админке и посмотрите, как он передаётся в коде через $order->get_status(). Для быстрой проверки можно временно записать значение в лог:
add_action( 'woocommerce_order_status_changed', function( $order_id, $old_status, $new_status ) {
error_log( sprintf( 'Order %d: %s -> %s', $order_id, $old_status, $new_status ) );
}, 10, 3 );После теста не забудьте убрать логирование, чтобы не засорять debug.log.
Пошаговое решение без правки ядра
Если задача разовая или относится только к одному магазину, удобнее добавить код в дочернюю тему или в небольшой функциональный плагин. Так вы не потеряете настройку после обновления темы.
- Создайте дочернюю тему или используйте свой мини-плагин.
- Добавьте фильтр для нужного письма.
- Укажите список статусов, при которых письмо должно быть выключено.
- Проверьте отправку на тестовом заказе.
Если нужно отключить сразу несколько писем, лучше оформить это отдельной функцией, чтобы код не расползался по файлу:
function wpcat_disable_wc_emails_for_statuses( $enabled, $order, $email_id, $blocked_statuses ) {
if ( ! $order instanceof WC_Order ) {
return $enabled;
}
if ( in_array( $order->get_status(), $blocked_statuses, true ) ) {
return false;
}
return $enabled;
}
add_filter( 'woocommerce_email_enabled_customer_processing_order', function( $enabled, $order ) {
return wpcat_disable_wc_emails_for_statuses( $enabled, $order, 'customer_processing_order', array( 'on-hold' ) );
}, 10, 2 );
add_filter( 'woocommerce_email_enabled_customer_completed_order', function( $enabled, $order ) {
return wpcat_disable_wc_emails_for_statuses( $enabled, $order, 'customer_completed_order', array( 'manual-review' ) );
}, 10, 2 );Такой вариант удобен, если бизнес-логика меняется: вы просто правите массив статусов, а не переписываете всю схему.
Сравнение подходов
| Способ | Когда подходит | Минусы |
|---|---|---|
| Настройки WooCommerce | Нужно выключить письмо полностью | Нет точечной логики по статусам |
| Код через фильтр | Нужно отключать письма только при определённых статусах | Нужно аккуратно тестировать |
| Сторонний плагин автоматизации | Есть сложные сценарии и много условий | Дополнительная нагрузка и зависимость от плагина |
Если задача простая, код обычно надёжнее. Если у вас уже стоит плагин автоматизации и он управляет статусами, проверьте, не дублирует ли он письма сам по себе. В некоторых магазинах достаточно отключить уведомления в одном месте, а не в двух.
Как проверить, что решение сработало
Проверка должна быть не «письмо вроде не пришло», а воспроизводимой.
- Создайте тестовый заказ с реальной сменой статуса.
- Переведите его в статус, который указан в коде.
- Убедитесь, что письмо не ушло клиенту и/или администратору.
- Переведите тот же заказ в статус, который не блокируется, и проверьте, что письмо отправляется.
- Если используете SMTP-плагин, посмотрите его журнал отправки — иногда письмо создаётся WooCommerce, но блокируется уже на уровне почтового сервиса.
Дополнительно полезно проверить страницу WooCommerce → Статус → Журналы, если у вас включено логирование или используется плагин для почтовых логов. Это помогает понять, где именно письмо было остановлено.
Частые ошибки и как их исправить
Сравнивают не тот статус
Ошибка типичная: в коде пишут wc-on-hold, хотя $order->get_status() возвращает on-hold. Из-за этого условие никогда не срабатывает. Проверяйте именно значение, которое возвращает объект заказа.
Отключают письмо не тем фильтром
Если вы хотите убрать письмо клиенту, а используете фильтр для письма администратору, результат будет нулевой. У каждого письма свой ID. Сначала определите, какое уведомление реально уходит, потом вешайте фильтр на его ID.
Пишут код в файле темы, который потом перезаписывается
Если код добавлен в родительскую тему, обновление может его удалить. Для таких задач лучше использовать дочернюю тему или мини-плагин.
Не учитывают сторонние интеграции
Если письмо отправляет CRM, сервис доставки или платёжный шлюз, WooCommerce-фильтр не поможет. В этом случае нужно искать настройку в самом сервисе или отключать webhook/автоматизацию там, где она настроена.
Отключают всё подряд
Иногда пытаются выключить все письма ради чистоты почты, а потом теряют важные уведомления о проблемных заказах. Безопаснее отключать только те письма, которые действительно дублируются или не нужны.
Что учесть по безопасности и производительности
Сам фильтр почти не влияет на производительность, но есть несколько практических моментов:
- не используйте тяжёлые запросы к базе внутри фильтра, если можно обойтись
$order->get_status(); - не оставляйте
error_log()в рабочем коде надолго; - если логика зависит от большого списка статусов, храните его в одном месте, а не размазывайте по нескольким хукам;
- после изменений проверьте, не сломалась ли отправка критичных писем, особенно о возвратах и отменах.
Если в магазине уже много автоматизаций, иногда полезно сначала навести порядок в служебных уведомлениях. Для этого можно использовать инструменты очистки и удаления дублей, например Clearfy Pro: https://wpshop.ru/plugins/clearfy?source=wpcat.ru&medium=article&campaign=woocommerce-otklyuchit-otpravku-elektronnykh-pisem-dlya-opredelennykh-statusov-zakaza. Но саму логику отключения писем всё равно лучше держать в коде, если нужен точный контроль.
Если у вас есть конкретный статус, письмо и сценарий, этот фильтр можно адаптировать без лишней архитектуры. Главное — сначала зафиксировать, какое уведомление уходит, потом отключать его точечно и обязательно проверить на тестовом заказе.