WooCommerce: решение проблемы с автозакрытием отменённых и зависших заказов

Диагностика проблемы с отменёнными и зависшими заказами в WooCommerce

Часто в интернет-магазинах на WooCommerce возникают ситуации, когда заказы остаются в статусе отменённых или зависших (on-hold) слишком долго. Это приводит к некорректной статистике, увеличению нагрузки на базу данных и путанице с учётом остатков на складе.

Чтобы проверить наличие таких заказов, выполните SQL-запрос к базе данных:

SELECT ID, post_status, post_date FROM wp_posts WHERE post_type = 'shop_order' AND post_status IN ('wc-cancelled', 'wc-on-hold');

Здесь post_status принимает значения с префиксом wc-, соответствующим статусам WooCommerce.

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

Почему важно автозакрывать отменённые и зависшие заказы

  • Уменьшается нагрузка на базу данных и сервер — удаление или изменение статуса старых заказов освобождает ресурсы.
  • Обновляется актуальный запас товаров — заказы, которые висят в статусе on-hold, могут резервировать товар, не позволяя другим клиентам его купить.
  • Чистая статистика продаж и заказов — без «мертвых» записей.

Пошаговое решение: автоматическое закрытие заказов с помощью WP-Cron

1. Регистрация кастомного события для автоматического запуска задачи

add_action('wp', function() {
    if (!wp_next_scheduled('wpmy_auto_close_orders')) {
        wp_schedule_event(time(), 'daily', 'wpmy_auto_close_orders');
    }
});

2. Реализация функции автозакрытия заказов

add_action('wpmy_auto_close_orders', function() {
    $days_limit = 7; // количество дней для ожидания
    $date_threshold = date('Y-m-d H:i:s', strtotime("-{$days_limit} days"));

    $args = [
        'status' => ['cancelled', 'on-hold'],
        'date_created' => '<' . $date_threshold,
        'limit' => -1,
        'return' => 'ids',
    ];

    $orders = wc_get_orders($args);

    foreach ($orders as $order_id) {
        $order = wc_get_order($order_id);

        if ($order->get_status() === 'on-hold') {
            // Отменяем заказ, если завис более 7 дней
            $order->update_status('cancelled', 'Автоматическая отмена заказа после 7 дней ожидания оплаты.');
        } elseif ($order->get_status() === 'cancelled') {
            // Закрываем заказ, если он отменён и старше 7 дней
            $order->update_status('completed', 'Автоматическое закрытие отменённого заказа.');
        }
    }
});

3. Очистка расписания при деактивации плагина/темы

register_deactivation_hook(__FILE__, function() {
    wp_clear_scheduled_hook('wpmy_auto_close_orders');
});

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

  • В панели WooCommerce проверьте, что заказы, которые были отменены или удерживались более 7 дней, имеют статус completed или cancelled по логике.
  • Запрос SQL из раздела диагностики должен показывать уменьшение количества заказов в статусах wc-cancelled и wc-on-hold со временем.
  • Вы можете временно включить логирование внутри функции, добавив error_log для отладки.

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

  • Неправильный префикс статуса заказа: WooCommerce использует статус с префиксом wc- в базе, но в функциях API — без префикса. Используйте в wc_get_orders статусы без wc-.
  • Отсутствие запланированного события WP-Cron: WP-Cron зависит от посещений сайта. Для гарантированной работы настройте системный cron (Linux) для вызова wp-cron.php.
  • Ошибки прав доступа: убедитесь, что PHP-скрипт имеет права на изменение заказов.
  • Неверное время ожидания: параметр $days_limit стоит подбирать под бизнес-процессы магазина.

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

  • Для больших магазинов с тысячами заказов используйте пагинацию при выборке заказов, чтобы не перегружать память:
$args['limit'] = 100;
$args['paged'] = 1;
do {
    $orders = wc_get_orders($args);
    foreach ($orders as $order_id) {
        // обработка заказа
    }
    $args['paged']++;
} while (count($orders) === 100);
  • Регулярно проверяйте логи ошибок PHP и WooCommerce для выявления сбоев в работе автозакрытия.
  • Для повышения безопасности применяйте фильтрацию и проверку данных, если планируете расширять функционал автозакрытия с внешними интеграциями.
  • Если хотите минимизировать нагрузку на Cron, можно запускать задачу не ежедневно, а с интервалом 2-3 дня.

Сравнение подходов для автозакрытия заказов

МетодПреимуществаНедостатки
WP-Cron с PHP функциейГибкость, возможность точной настройки логики, бесплатное решениеЗависимость от посещений сайта, требует знаний PHP
Плагины для автозакрытия заказовПростота установки, готовый функционал, обновленияМогут быть платными, не всегда подходят под все бизнес-процессы
Ручное закрытие заказов через админкуМаксимальный контроль, без технических навыковТрудоёмко, неэффективно при большом количестве заказов
Как автоматизировать создание и удаление черновиков в WordPress
07.02.2026
Как создать автоматическую удалённую регистрацию пользователей в WordPress с проверкой данных
27.01.2026
WooCommerce: правильное отображение вариаций товаров — практическое руководство
17.05.2026
Как создать собственный виджет WordPress с примерами кода
26.11.2025
Как использовать WP REST API для автоматической обновы продуктов WooCommerce
21.04.2026