Проблема: необходимость автоматического изменения статуса заказа в WooCommerce по времени
В стандартном WooCommerce нет встроенной функции для автоматического изменения статуса заказа спустя определённый промежуток времени. Например, нужно переводить заказ из статуса "в ожидании оплаты" в "отменён" через 48 часов или менять статус "обработка" на "завершён" через неделю. Это особенно актуально для магазинов с длительным циклом обработки или для автоматизации управления заказами.
Диагностика задачи и её особенности
Для решения задачи важно понять:
- Какие статусы и сроки перехода нужны;
- Как запускать проверку и обновление статусов — вручную или автоматически;
- Как избежать конфликтов с другими процессами WooCommerce;
- Нужно ли уведомлять клиента и админа при смене статуса.
Реализация должна быть максимально надёжной и не нагружать сервер.
Пошаговое решение: настройка автоматического изменения статуса заказа
1. Используем WP-Cron для регулярной проверки заказов
Добавьте в functions.php вашей темы или в плагин следующий код для регистрации задачи, которая будет запускаться, например, каждый час:
function wc_schedule_status_change_event() {
if ( ! wp_next_scheduled( 'wc_auto_change_order_status' ) ) {
wp_schedule_event( time(), 'hourly', 'wc_auto_change_order_status' );
}
}
add_action( 'wp', 'wc_schedule_status_change_event' );2. Добавляем функцию обработки смены статусов
В этой функции мы будем искать заказы, которые старше нужного времени и соответствуют исходному статусу, и менять их статус:
add_action( 'wc_auto_change_order_status', 'wc_auto_update_order_statuses' );
function wc_auto_update_order_statuses() {
// Параметры для смены статуса "в ожидании" на "отменён" спустя 48 часов
$old_status = 'pending';
$new_status = 'cancelled';
$hours_limit = 48;
$args = array(
'status' => $old_status,
'limit' => -1,
'date_created' => '<' . ( time() - $hours_limit * 3600 ),
);
$orders = wc_get_orders( $args );
foreach ( $orders as $order ) {
// Проверяем, что заказ реально старше 48 часов
$created_date = $order->get_date_created();
if ( ! $created_date ) continue;
$order_age = ( time() - $created_date->getTimestamp() ) / 3600;
if ( $order_age >= $hours_limit ) {
$order->update_status( $new_status, 'Автоматическое изменение статуса по времени', true );
}
}
}3. Расширение: добавление смены статуса "обработка" на "завершён" через 7 дней
Добавьте аналогичный блок в ту же функцию:
// Смена статуса "processing" на "completed" через 7 дней
$old_status_2 = 'processing';
$new_status_2 = 'completed';
$hours_limit_2 = 168; // 7 дней * 24 часа
$args_2 = array(
'status' => $old_status_2,
'limit' => -1,
'date_created' => '<' . ( time() - $hours_limit_2 * 3600 ),
);
$orders_2 = wc_get_orders( $args_2 );
foreach ( $orders_2 as $order ) {
$created_date = $order->get_date_created();
if ( ! $created_date ) continue;
$order_age = ( time() - $created_date->getTimestamp() ) / 3600;
if ( $order_age >= $hours_limit_2 ) {
$order->update_status( $new_status_2, 'Автоматическое завершение заказа по времени', true );
}
}Проверка результата после внедрения
Чтобы проверить, что код работает:
- Создайте тестовый заказ со статусом, подлежащим смене;
- Отредактируйте дату создания заказа в базе (в таблице
wp_postsдля типаshop_order), чтобы она была старше 48 часов или 7 дней; - Выполните вручную запуск WP-Cron задачи через плагин WP Crontrol или вызов функции через WP-CLI:
wp cron event run wc_auto_change_order_status - Проверьте, изменился ли статус заказа в админке WooCommerce и в базе;
- Проверьте, что в комментариях к заказу появилась запись с текстом изменения.
Частые ошибки и как их исправлять
- Задача WP-Cron не запускается автоматически: если на сайте мало трафика, WP-Cron может не сработать. Решение — настроить системный cron на сервере или запускать задачу вручную через WP-CLI.
- Параметр
date_createdвwc_get_ordersне работает: WP 5.5+ поддерживает параметрdate_created, если версия WooCommerce ниже, используйте прямой запрос к базе или фильтры. - Заказы не меняют статус: проверьте, что статусы указаны правильно — WooCommerce использует без префикса
wc-, например,processing,completed, а неwc-processing. - Ошибка из-за лимита памяти или времени: при большом количестве заказов лучше обрабатывать партии по 50-100 штук, а не сразу все.
Практические советы по безопасности и производительности
- Используйте WP-Cron с системным cron для стабильного выполнения задач.
- Добавьте логирование изменений статусов в отдельный файл, чтобы отслеживать автоматические действия.
- Ограничьте количество обрабатываемых заказов за один запуск, чтобы избежать таймаутов.
- Проверяйте, что роли пользователей, запускающих задачи, имеют необходимые права.
- При необходимости уведомляйте админов и клиентов об автоматической смене статуса через хуки WooCommerce
woocommerce_order_status_changed.
Сравнение вариантов реализации автоматической смены статуса
| Метод | Плюсы | Минусы | Когда использовать |
|---|---|---|---|
| WP-Cron + код в functions.php | Гибкость, нет зависимостей, полный контроль | Зависит от посещаемости сайта, требует тестирования | Малые и средние магазины с доступом к коду |
| Плагины автоматизации (например, AutomateWoo) | Простота настройки, поддержка, визуальный интерфейс | Платные, могут быть избыточны, нагрузка | Крупные магазины, без желания писать код |
| Внешние скрипты с WP-CLI | Точная настройка, не зависит от WP-Cron | Требует настроек сервера, навыков администрирования | Опытные разработчики и хостинги с SSH доступом |