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

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

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

Типичные признаки проблемы:

  • Админка WooCommerce тормозит при загрузке страницы заказов;
  • В списке заказов много старых заказов со статусом pending или failed;
  • База данных растёт, что может влиять на резервное копирование и производительность.

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

1. Определяем правила удаления

Удалять будем заказы со статусами pending и failed, которым больше 7 дней. Этот срок можно менять по потребностям.

2. Создаём функцию для удаления заказов

function wpfreecourses_delete_old_inactive_orders() {
    if ( ! class_exists( 'WooCommerce' ) ) {
        return;
    }

    $date_threshold = date( 'Y-m-d H:i:s', strtotime( '-7 days' ) );

    $args = array(
        'status' => array( 'pending', 'failed' ),
        'date_created' => '<' . $date_threshold,
        'limit' => -1,
        'return' => 'ids',
    );

    $orders = wc_get_orders( $args );

    foreach ( $orders as $order_id ) {
        wp_delete_post( $order_id, true );
    }
}

3. Регистрируем событие WP-Cron

Добавим ежесуточный хук, запускающий нашу функцию.

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

add_action( 'wpfreecourses_daily_delete_inactive_orders', 'wpfreecourses_delete_old_inactive_orders' );

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

Чтобы не оставлять крон-задачи, добавим удаление расписания.

function wpfreecourses_clear_schedule_on_deactivation() {
    $timestamp = wp_next_scheduled( 'wpfreecourses_daily_delete_inactive_orders' );
    if ( $timestamp ) {
        wp_unschedule_event( $timestamp, 'wpfreecourses_daily_delete_inactive_orders' );
    }
}
register_deactivation_hook( __FILE__, 'wpfreecourses_clear_schedule_on_deactivation' );

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

  • Запустить функцию вручную через wpfreecourses_delete_old_inactive_orders() в среде разработки и проверить удаление заказов;
  • В админке WooCommerce проверить отсутствие заказов старше 7 дней со статусами pending и failed после выполнения WP-Cron (обычно через сутки);
  • В базе данных проверить таблицу wp_posts по типу shop_order и статусам заказов;
  • Для тестирования можно временно сократить срок удаления (например, до 1 дня) и смотреть на удаление.

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

  • Функция wp_delete_post не удаляет заказ: убедитесь, что передаёте ID заказа и второй параметр true для окончательного удаления, а не в корзину.
  • WP-Cron не запускается автоматически: на некоторых серверах нужно настроить системный cron или проверить, что на сайте есть посещения для запуска wp-cron.php;
  • Неправильный формат даты в запросе wc_get_orders: используйте формат Y-m-d H:i:s и знак сравнения в параметре date_created;
  • Заказы не удаляются, потому что статусы указаны неверно: используйте точные статусы WooCommerce - pending, failed, on-hold и т.п.

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

  • Используйте wp_delete_post( $order_id, true ) для полной очистки, чтобы не оставлять метаданные и записи в связанных таблицах.
  • Если заказов много, разбивайте удаление на батчи, чтобы избежать таймаутов:
function wpfreecourses_delete_old_orders_batch() {
    $date_threshold = date( 'Y-m-d H:i:s', strtotime( '-7 days' ) );

    $args = array(
        'status' => array( 'pending', 'failed' ),
        'date_created' => '<' . $date_threshold,
        'limit' => 20,
        'return' => 'ids',
    );

    $orders = wc_get_orders( $args );

    foreach ( $orders as $order_id ) {
        wp_delete_post( $order_id, true );
    }

    if ( count( $orders ) === 20 ) {
        // Повторить через крон или планировщик
    }
}
  • Проверяйте логи ошибок сервера на предмет сбоев при удалении заказов.
  • Для больших магазинов рассмотрите использование внешних инструментов очистки или WP-CLI с командой wp post delete.
  • Если нужны уведомления об удалении, можно добавить логирование или отправку писем администратору.

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

Метод Плюсы Минусы Рекомендации
Ручное удаление в админке Просто, не требует кода Трудозатратно, не подходит для большого количества Для единичных заказов или тестов
WP-Cron с пользовательским кодом Автоматизация, гибкость, настройка периода Зависит от работы WP-Cron, возможны таймауты Оптимальный вариант для большинства магазинов
WP-CLI команды Быстро, подходит для больших сайтов Требует доступа к серверу и навыков командной строки Лучше для продвинутых пользователей и администраторов
WooCommerce: автоматическое создание скидки при покупке N товаров без использования плагинов
11.05.2026
WooCommerce: как автоматически отключать товары после завершения продаж
19.06.2026
WooCommerce: автоматическое изменение атрибутов товаров при изменении заказа
01.06.2026
Как создать собственный REST API endpoint в WordPress с примерами кода
22.12.2025
Как безопасно удалить старые версии плагинов WordPress и освободить место
09.02.2026