wpcat.ru wordpress WPCat.ru

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

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

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

Когда это действительно нужно

Отключать письма имеет смысл не «на всякий случай», а в конкретных ситуациях:

  • заказ переводится в промежуточный статус on-hold, processing или кастомный статус, но письмо клиенту не нужно;
  • уведомления уже отправляет CRM, ERP или сервис рассылок, а WooCommerce только дублирует их;
  • в магазине много ручных изменений статусов, и администраторы получают слишком много служебных писем;
  • нужно оставить только критичные уведомления, например о новом заказе и возврате, а остальные убрать.

Диагностика: какие письма WooCommerce отправляет по статусам

Сначала важно понять, какое именно письмо вы хотите отключить. В WooCommerce письма привязаны не только к статусу, но и к событию. Например, письмо клиенту о заказе в обработке обычно связано с переходом в processing, а письмо о завершении — со статусом completed.

Проверять нужно так:

  1. Откройте WooCommerce → Настройки → Письма.
  2. Посмотрите список уведомлений и их включённые/выключенные состояния.
  3. Проверьте, какой статус меняется в заказе в момент отправки письма.
  4. Если письмо приходит не из 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.

Пошаговое решение без правки ядра

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

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

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

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. Но саму логику отключения писем всё равно лучше держать в коде, если нужен точный контроль.

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

×

Время действовать!

Суперцены на
WordPress!

-20%
на премиум темы

Не упусти шанс ⋙