Как отключить автоматический переход заказа в «В обработке» после оплаты в WooCommerce

|

Сценарий знакомый: покупатель оплатил заказ, а WooCommerce сразу переводит его в статус processing («В обработке»), хотя вам нужен другой рабочий поток — например, оставить заказ в on-hold, отправить его на ручную проверку или не ломать интеграцию с внешней CRM. Проблема обычно не в одном месте: автопереход может быть вызван способом оплаты, настройками самого плагина, кастомным кодом темы или расширением для склада/доставки.

Когда это действительно проблема

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

Диагностика: кто именно меняет статус

Прежде чем что-то отключать, стоит понять источник. В WooCommerce статус после оплаты может меняться по нескольким причинам:

1. Поведение платёжного шлюза

Некоторые методы оплаты сами переводят заказ в processing или completed, если считают оплату успешной. Это нормально для шлюза, но не всегда подходит вашему процессу.

2. Хук в теме или плагине

Частая практика — кастомный код на woocommerce_payment_complete, woocommerce_order_status_changed или woocommerce_payment_complete_order_status. Именно он может принудительно менять статус.

3. Плагин автоматизации

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

4. Настройки самого WooCommerce

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

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

add_action('woocommerce_order_status_changed', function($order_id, $old_status, $new_status, $order) {
    if (defined('WP_DEBUG') && WP_DEBUG) {
        error_log(sprintf(
            'Order #%d status changed: %s -> %s',
            $order_id,
            $old_status,
            $new_status
        ));
    }
}, 10, 4);

Этот лог не покажет, кто именно вызвал изменение, но даст точку входа: после какой оплаты и в какой момент статус уходит в processing.

Как отключить автопереход: рабочие варианты

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

ПодходКогда использоватьПлюсыМинусы
Код через фильтрНужно точечно изменить статус после оплатыКонтроль, без лишних плагиновНужна проверка после обновлений
Настройка платёжного шлюзаПроблема только в одном способе оплатыЧистое решение на уровне интеграцииНе все шлюзы дают такой параметр
Кастомный обработчик статусаНужна отдельная логика для разных товаровГибко для сложных магазиновСложнее сопровождать

Вариант 1. Изменить статус после оплаты через фильтр

Если вам нужно, чтобы заказ после успешной оплаты не уходил в processing, а оставался, например, в on-hold, можно переопределить статус через фильтр woocommerce_payment_complete_order_status.

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

    // Пример: для всех заказов оставляем статус on-hold
    return 'on-hold';
}, 10, 3);

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

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

    // Только для оплаты банковским переводом
    if ($order->get_payment_method() === 'bacs') {
        return 'on-hold';
    }

    // Для остальных заказов не вмешиваемся
    return $status;
}, 10, 3);

Вариант 2. Не давать шлюзу переводить заказ в processing

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

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

Вариант 3. Менять статус только для части товаров

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

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

    foreach ($order->get_items() as $item) {
        $product = $item->get_product();
        if ($product && ! $product->is_virtual()) {
            return 'processing';
        }
    }

    return 'on-hold';
}, 10, 3);

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

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

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

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

Для дополнительной проверки можно временно добавить запись в лог при каждом изменении статуса:

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);

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

Статус меняется, но письмо уже ушло

Это значит, что письмо привязано к другому хуку или срабатывает раньше вашего фильтра. Решение — проверить, не завязано ли уведомление на woocommerce_order_status_processing. Иногда нужно менять не только статус, но и условия отправки письма.

Код работает для части заказов, но не для всех

Чаще всего причина в том, что разные способы оплаты используют разные сценарии завершения платежа. Проверьте $order->get_payment_method() и убедитесь, что фильтр не пропускает нужный метод.

После обновления плагина всё вернулось обратно

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

Заказ зависает в неправильном статусе

Так бывает, если фильтр возвращает статус, который не соответствует логике магазина. Например, вы оставили заказ в on-hold, но не настроили ручную обработку менеджером. В итоге заказ не двигается дальше, хотя оплата уже прошла.

Что учесть по безопасности и производительности

Любой код, который вмешивается в статус заказа, должен быть предсказуемым. Не добавляйте в фильтр тяжёлые запросы к внешним API и не делайте там длинные циклы по базе. Фильтр вызывается в момент обработки оплаты, и лишняя задержка сразу бьёт по UX.

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

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

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

Как автоматически удалять пустые термины в WordPress: практическое руководство
12.04.2026
Как удалить meta tag generator в WordPress: практическое руководство
06.01.2026
Как создать эксклюзивный сайт на WordPress с поддержкой подписки и доступом к контенту
30.03.2026
Как добавить собственные типы записей (Custom Post Types) в WordPress
22.11.2025
Как использовать внешние API в WordPress с помощью AJAX: практическое руководство
02.04.2026
×
Прокачай свой WordPress!

Скидка -20% на премиум темы и плагины

Воспользоваться сейчас ⋙