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

В WooCommerce статус заказа после оплаты меняется не «сам по себе», а по логике шлюза оплаты и самого магазина. Чаще всего проблема выглядит так: клиент оплатил заказ, а вместо нужного вам статуса заказ уходит в processing или сразу в completed. Для магазина с цифровыми товарами, предзаказами, ручной проверкой или нестандартной логистикой это неудобно: менеджер теряет контроль над обработкой, а автоматические письма и интеграции с CRM начинают срабатывать раньше времени.

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

Когда WooCommerce меняет статус автоматически

После успешной оплаты WooCommerce опирается на тип товара, способ оплаты и код шлюза. Условно поведение делится на три сценария:

  • Заказ уходит в processing — обычно для физических товаров, которые нужно собирать и отправлять.
  • Заказ уходит в completed — часто для цифровых товаров, когда доставка не требуется.
  • Статус меняет сам платежный плагин — например, после callback/webhook от банка или платежной системы.

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

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

Перед правкой кода важно понять, где происходит переключение. Иначе можно отключить одно место, а статус продолжит меняться в другом.

Проверяем журнал заказов и логи шлюза

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

Дальше проверьте:

  • WooCommerce → Статус → Логи — если шлюз пишет в лог, там часто видно, какой метод вызвал обновление.
  • Настройки платежного плагина — некоторые шлюзы имеют отдельный параметр вроде «автоматически завершать заказы».
  • Кастомные хуки в теме или плагинах — ищите вызовы update_status(), payment_complete(), set_status().

Быстрый способ понять источник через отладочный хук

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

add_action( 'woocommerce_order_status_changed', function( $order_id, $old_status, $new_status, $order ) {
    if ( ! $order instanceof WC_Order ) {
        return;
    }

    error_log( sprintf(
        'Order #%d status changed: %s => %s, payment method: %s',
        $order_id,
        $old_status,
        $new_status,
        $order->get_payment_method()
    ) );
}, 10, 4 );

После этого оплатите тестовый заказ и посмотрите debug.log. Если изменение происходит сразу после payment_complete(), значит нужно вмешиваться в логику оплаты. Если статус меняется позже, ищите webhook или отдельный обработчик плагина.

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

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

Вариант 1: оставить все оплаченные заказы в on-hold

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

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

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

Что делает этот код: после успешной оплаты WooCommerce не переводит заказ в processing или completed, а оставляет его на ручной контроль.

Вариант 2: вернуть кастомный статус

Если у вас уже есть кастомный статус заказа, можно вернуть его вместо стандартного. Например, если вы используете статус awaiting-review:

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

    return 'awaiting-review';
}, 10, 3 );

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

Вариант 3: отключить автозавершение только для отдельных способов оплаты

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

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

    $payment_method = $order->get_payment_method();

    if ( in_array( $payment_method, array( 'bacs', 'cod' ), true ) ) {
        return 'on-hold';
    }

    return $status;
}, 10, 3 );

Если статус меняет платежный плагин, а не WooCommerce

Это частая ситуация с банковскими эквайрингами, локальными шлюзами и сервисами, которые отправляют webhook. В таком случае фильтр woocommerce_payment_complete_order_status может не помочь, потому что плагин сам вызывает update_status() после подтверждения платежа.

Что делать:

  1. Проверьте настройки шлюза — иногда есть опция вроде «автоматически завершать заказы».
  2. Посмотрите документацию плагина на наличие собственного фильтра статуса.
  3. Если фильтра нет, перехватывайте изменение статуса через общий хук и возвращайте нужное состояние в своей логике.

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

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

    if ( ! $order ) {
        return;
    }

    if ( $order->get_payment_method() === 'your_gateway' ) {
        remove_action( 'woocommerce_order_status_completed', __FUNCTION__ );
        $order->update_status( 'processing', 'Статус скорректирован после оплаты.' );
    }
}, 10, 1 );

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

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

ПодходКогда подходитПлюсыМинусы
Настройка платежного плагинаЕсли шлюз умеет управлять статусомБез кода, меньше рисковНе у всех плагинов есть такая опция
Фильтр woocommerce_payment_complete_order_statusЕсли нужно изменить статус после оплаты глобально или по методам оплатыПросто внедрить, не трогает ядроНе сработает, если статус меняет сам шлюз позже
Перехват через action/status hooksЕсли плагин оплаты жестко меняет статусМожно точечно исправить поведениеНужно аккуратно избегать циклов и дублей

Пошаговое решение без лишнего риска

  1. Сделайте тестовый заказ в staging-окружении.
  2. Определите, кто меняет статус: WooCommerce или платежный плагин.
  3. Если есть настройка в шлюзе — используйте ее первой.
  4. Если настройки нет, добавьте фильтр woocommerce_payment_complete_order_status.
  5. Проверьте письма, вебхуки и интеграции с CRM после изменения.
  6. Только после этого переносите правку на боевой сайт.

Как проверить, что решение сработало

Проверка должна быть не только визуальной в админке. После внедрения убедитесь в трех вещах:

  • Статус заказа остается тем, который вы задали в коде или настройке.
  • Письма WooCommerce не уходят раньше времени, если они завязаны на смену статуса.
  • Интеграции с CRM, складом или доставкой не получают ложный сигнал о завершении заказа.

Практический чек-лист:

  • создать тестовый заказ;
  • оплатить его тестовым способом;
  • проверить статус в админке;
  • посмотреть запись в debug.log;
  • убедиться, что webhook платежного шлюза не возвращает заказ в другой статус;
  • проверить, не сломалась ли логика возвратов и ручной обработки.

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

Фильтр добавили, но статус все равно меняется

Значит, изменение делает не WooCommerce, а платежный плагин после callback/webhook. Ищите собственные настройки шлюза или его хуки.

Возвращаете несуществующий статус

Если статус не зарегистрирован, заказ может отображаться некорректно. Перед использованием кастомного статуса убедитесь, что он добавлен через register_post_status() и отображается в списке статусов WooCommerce.

Случайно ломаете email-уведомления

Многие письма завязаны на переходы между статусами. Если вы оставляете заказ в on-hold, а раньше он уходил в completed, проверьте, какие письма должны отправляться вручную, а какие — автоматически.

Правите файл темы напрямую

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

Безопасность и производительность

Сам код для смены статуса легкий, но проблема обычно не в нем, а в сопутствующей логике: логировании, webhook-обработчиках и повторных запросах от платежной системы. Не пишите отладку в продакшн без необходимости и не оставляйте временные error_log() на постоянной основе.

Если на сайте много заказов и интеграций, держите изменения в отдельном мини-плагине. Так проще отключить правку, если платежный шлюз обновится и начнет вести себя иначе. Для чистки лишней логики и дублей в WooCommerce иногда помогает аудит плагинов и настроек, а не только код; в таких задачах полезны инструменты вроде Clearfy Pro, если они уже используются в проекте, но саму логику статуса заказа все равно лучше решать точечно.

Главная идея простая: сначала выясняем, кто именно меняет статус, потом меняем только этот участок. Тогда WooCommerce не превращается в набор случайных костылей, а поведение заказов остается предсказуемым.

Как установить ограничения на регистрацию в WordPress
05.04.2026
WooCommerce: как автоматически удалять товары из заказа после оплаты
31.05.2026
Как изменить URL страницы авторского архива в WordPress
23.03.2026
Как добавить свои метаданные в WordPress
16.11.2025
Как удалить или отключить плагин WordPress: практическое руководство
09.04.2026