WPFAQ

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

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

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

Когда это нужно и что именно ломается

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

Здесь важно разделить две вещи:

  • статус заказа в админке;
  • email-уведомление, которое WooCommerce отправляет при смене статуса или при создании заказа.

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

Диагностика: где именно уходит письмо

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

Если письмо уходит сразу после оплаты, обычно причина одна из трёх:

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

Проверка простая: откройте заказ в админке и посмотрите, какой статус появляется после оплаты. Затем в WooCommerce → Настройки → Email найдите письмо, которое связано с этим статусом. Если статус меняется на processing, а письмо клиенту уходит именно на этом этапе, отключать нужно не шлюз, а уведомление или сам переход в этот статус.

Пошаговое решение

1. Создаём отдельный статус для ручной проверки

Такой статус удобнее, чем держать заказ в on-hold или pending, если у вас уже есть своя логика для этих состояний. Ниже пример регистрации собственного статуса wc-awaiting-review.

add_action( 'init', function () {
    register_post_status( 'wc-awaiting-review', array(
        'label'                     => _x( 'На проверке', 'Order status', 'textdomain' ),
        'public'                    => true,
        'exclude_from_search'       => false,
        'show_in_admin_all_list'    => true,
        'show_in_admin_status_list' => true,
        'label_count'               => _n_noop( 'На проверке (%s)', 'На проверке (%s)', 'textdomain' ),
    ) );
} );

add_filter( 'wc_order_statuses', function ( $order_statuses ) {
    $new_statuses = array();

    foreach ( $order_statuses as $key => $label ) {
        $new_statuses[ $key ] = $label;

        if ( 'wc-processing' === $key ) {
            $new_statuses['wc-awaiting-review'] = __( 'На проверке', 'textdomain' );
        }
    }

    return $new_statuses;
} );

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

2. Переводим оплаченный заказ в статус проверки

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

add_action( 'woocommerce_payment_complete', function ( $order_id ) {
    $order = wc_get_order( $order_id );

    if ( ! $order ) {
        return;
    }

    // Не трогаем уже завершённые или отменённые заказы.
    if ( in_array( $order->get_status(), array( 'completed', 'cancelled', 'refunded' ), true ) ) {
        return;
    }

    $order->update_status( 'awaiting-review', __( 'Оплата получена, заказ отправлен на ручную проверку.', 'textdomain' ) );
}, 20 );

Если платёжный шлюз уже ставит processing, этот хук может сработать слишком поздно. В таком случае лучше перехватывать изменение статуса через woocommerce_payment_complete_order_status и возвращать нужный статус до отправки письма.

add_filter( 'woocommerce_payment_complete_order_status', function ( $status, $order_id, $order ) {
    if ( $order instanceof WC_Order ) {
        return 'awaiting-review';
    }

    return $status;
}, 10, 3 );

3. Отключаем письмо клиенту на этапе проверки

Если заказ должен оставаться без уведомления до ручного подтверждения, проще всего отключить конкретное письмо через фильтр woocommerce_email_enabled_.... Название фильтра зависит от класса письма. Для письма о новом заказе у клиента это обычно customer_processing_order или customer_completed_order, в зависимости от вашей схемы.

Пример для отключения письма о заказе, пока статус awaiting-review:

add_filter( 'woocommerce_email_enabled_customer_processing_order', function ( $enabled, $order ) {
    if ( $order instanceof WC_Order && 'awaiting-review' === $order->get_status() ) {
        return false;
    }

    return $enabled;
}, 10, 2 );

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

4. Включаем уведомление после ручного подтверждения

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

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

Сравнение подходов

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

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

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

После правки не ограничивайтесь тестом «письмо пришло/не пришло». Проверьте цепочку целиком:

  • оформите тестовый заказ на staging;
  • оплатите его тем же шлюзом, что и на боевом сайте;
  • убедитесь, что статус стал awaiting-review, а не processing;
  • проверьте, что клиент не получил письмо раньше времени;
  • после ручной смены статуса на processing или completed убедитесь, что нужное письмо отправилось;
  • посмотрите журнал почты, если используете SMTP-плагин или логирование писем.

Если письма не видно, но статус меняется правильно, проблема часто не в WooCommerce, а в почтовой доставке сервера. В таком случае полезно проверить отправку через SMTP и логи почтового плагина.

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

Заказ остаётся в processing, хотя код добавлен

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

Письмо отключилось для всех заказов

Обычно это происходит, если в фильтре не проверяют статус заказа или используют слишком общий хук. Убедитесь, что условие завязано на $order->get_status(), а не на глобальный флаг.

Статус не отображается в админке

Чаще всего забывают добавить статус в фильтр wc_order_statuses. Само register_post_status() недостаточно: WooCommerce должен знать, как показать статус в списке заказов.

Появляются дубли уведомлений

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

Безопасность и поддержка

Такой код лучше держать в небольшом mu-plugin или в отдельном мини-плагине, а не в functions.php темы. Тогда он не пропадёт при смене темы и проще будет откатить изменения.

Если магазин работает с реальными оплатами, не тестируйте на бою без резервной копии и без staging. Особенно это важно, если у вас подключены антифрод-сервисы, CRM или внешняя логистика: они тоже могут реагировать на смену статуса заказа.

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

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

×

AI-плагин

WPGPT
Сам создает статьи для вашего сайта WordPress

SEO и мета-теги

Парсинг конкурентов

Изображения

Комментарии

Подробнее