WooCommerce: как автоматически изменять статус заказа по коду с помощью сниппетов

Диагностика проблемы: зачем нужна автоматическая смена статуса заказа в WooCommerce

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

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

Пошаговое решение: как программно изменить статус заказа по коду

1. Используем хук для запуска функции изменения статуса

Чаще всего нужно менять статус заказа в ответ на какое-то событие или по расписанию. Ниже пример функции, которая меняет статус заказа на "completed" по ID заказа.

function wpnews_change_order_status_by_id( $order_id, $new_status = 'completed' ) {
    if ( ! $order_id ) {
        return false;
    }
    $order = wc_get_order( $order_id );
    if ( ! $order ) {
        return false;
    }
    // Проверяем, что статус отличается от текущего
    if ( $order->get_status() === $new_status ) {
        return false;
    }
    $order->update_status( $new_status, 'Статус изменен автоматически через wpnews.ru', true );
    return true;
}

2. Пример применения: смена статуса заказа через 24 часа после оплаты

Добавим задачу в WP-Cron, которая проверяет заказы со статусом "processing" старше 24 часов и переводит их в "completed".

function wpnews_schedule_order_status_change() {
    if ( ! wp_next_scheduled( 'wpnews_check_orders_for_status_change' ) ) {
        wp_schedule_event( time(), 'hourly', 'wpnews_check_orders_for_status_change' );
    }
}
add_action( 'wp', 'wpnews_schedule_order_status_change' );

function wpnews_check_orders_for_status_change() {
    $args = [
        'status' => 'processing',
        'limit' => -1,
        'date_created' => '<' . ( time() - DAY_IN_SECONDS ),
    ];
    $orders = wc_get_orders( $args );
    foreach ( $orders as $order ) {
        // Меняем статус на completed
        wpnews_change_order_status_by_id( $order->get_id(), 'completed' );
    }
}
add_action( 'wpnews_check_orders_for_status_change', 'wpnews_check_orders_for_status_change' );

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

  • Через интерфейс WooCommerce проверьте заказы со статусом "processing" старше 24 часов — они должны автоматически перейти в "completed".
  • В админке WordPress в разделе "Инструменты" - "Запланированные задачи" (если установлен плагин WP Crontrol) проверьте, что задача wpnews_check_orders_for_status_change запускается ежечасно.
  • Посмотрите в метаданных заказа комментарии, там должна появиться запись с текстом "Статус изменен автоматически через wpnews.ru".

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

  • WP-Cron не запускается автоматически: на некоторых хостингах WP-Cron не срабатывает без захода на сайт. Решение — настроить системный cron для вызова wp-cron.php или использовать плагин, например WP Crontrol.
  • Неверный формат даты в параметрах wc_get_orders: параметр date_created принимает массив с ключами before и after или объекты DateTime. В примере выше для упрощения используется UNIX-время, но на практике правильнее использовать:
$args = [
    'status' => 'processing',
    'limit' => -1,
    'date_created' => [ 'before' => ( new WC_DateTime( '@' . ( time() - DAY_IN_SECONDS ) ) )->format( 'Y-m-d H:i:s' ) ],
];
  • Статус не меняется: проверьте, что статус, на который вы меняете, допустим в WooCommerce (например, completed, processing, cancelled). Нельзя указывать произвольные строки.
  • Ошибка прав доступа: убедитесь, что код выполняется с правами администратора или в контексте, где доступны функции WooCommerce.

Практические советы по производительности и безопасности

  • Не выполняйте массовое обновление заказов напрямую в хуках с высоким трафиком — используйте WP-Cron с разумным интервалом (например, час) и лимитируйте количество обновляемых заказов за один запуск.
  • Для крупных магазинов с тысячами заказов лучше реализовать пакетную обработку, чтобы не перегружать сервер.
  • Добавляйте логирование действий изменения статусов, чтобы отслеживать автоматические изменения и вовремя реагировать на сбои.
  • Используйте nonce и проверки прав пользователя, если планируете расширять функционал, вызываемый через UI или AJAX.

Сравнение вариантов реализации автоматической смены статуса заказов

ВариантОписаниеПлюсыМинусы
Плагины автоматизации WooCommerceГотовые решения с UI и множеством настроекПростота использования, поддержка, часто много функцийНагрузка, стоимость, избыточность
Кастомный код через WP-CronКонтроль и минимальный вес, гибкостьЛегко адаптировать, быстро, без лишнего функционалаТребует знаний, нужно тестировать и поддерживать
Внешний скрипт через REST APIВызов изменения статуса по внешним событиямИнтеграции с ERP, CRM, внешними системамиСложнее реализовать, безопасность
Как отключить AJAX в WooCommerce для повышения производительности
24.04.2026
Как использовать WordPress Transients для эффективного кэширования данных
07.02.2026
Как удалить все незавершённые задачи WP-Cron в WordPress
23.01.2026
Как удалить старые медиа файлы в WordPress
11.02.2026
Как удалить все комментарии с одного поста в WordPress
06.12.2025