WooCommerce: автоматическое удаление заказов со статусом Отменен и Возврат

Диагностика проблемы с накоплением заказов статусов Отменен и Возврат в WooCommerce

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

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

SELECT post_status, COUNT(*) as count FROM wp_posts 
WHERE post_type = 'shop_order' 
AND post_status IN ('wc-cancelled', 'wc-refunded') 
GROUP BY post_status;

Если количество таких заказов исчисляется тысячами, стоит автоматизировать их удаление.

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

1. Создаем функцию для удаления заказов со статусом отменен и возврат

Добавьте следующий код в файл functions.php вашей дочерней темы или в собственный плагин:

function wpmentor_delete_old_cancelled_refunded_orders() {
    global $wpdb;
    // Удаляем заказы старше 30 дней
    $date_threshold = date('Y-m-d H:i:s', strtotime('-30 days'));

    // Получаем ID заказов со статусом wc-cancelled или wc-refunded старше 30 дней
    $order_ids = $wpdb->get_col($wpdb->prepare(
        "SELECT ID FROM {$wpdb->posts} 
        WHERE post_type = 'shop_order' 
        AND post_status IN ('wc-cancelled', 'wc-refunded') 
        AND post_date < %s",
        $date_threshold
    ));

    if (empty($order_ids)) {
        return;
    }

    foreach ($order_ids as $order_id) {
        wp_delete_post($order_id, true); // true - принудительное удаление без перемещения в корзину
    }
}

2. Регистрируем WP-Cron для запуска функции ежедневно

Добавьте в тот же файл следующий код для регистрации и запуска задачи ежедневно:

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

add_action('wpmentor_daily_order_cleanup', 'wpmentor_delete_old_cancelled_refunded_orders');

3. Очистка WP-Cron при деактивации

Если реализуете код в плагине, не забудьте отменить задачу при деактивации:

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

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

Для проверки корректности работы:

  • Запустите функцию вручную, вызвав wpmentor_delete_old_cancelled_refunded_orders() через wp shell или добавив временный вызов в functions.php.
  • Проверьте, что заказы старше 30 дней со статусом отменен и возврат удалились.
  • В админке WooCommerce проверьте, что заказы с этими статусами отсутствуют или их количество уменьшилось.
  • Проверьте логи ошибок сервера на предмет ошибок удаления.

Можно также вывести количество удаленных заказов в лог:

function wpmentor_delete_old_cancelled_refunded_orders() {
    global $wpdb;
    $date_threshold = date('Y-m-d H:i:s', strtotime('-30 days'));
    $order_ids = $wpdb->get_col($wpdb->prepare(
        "SELECT ID FROM {$wpdb->posts} 
        WHERE post_type = 'shop_order' 
        AND post_status IN ('wc-cancelled', 'wc-refunded') 
        AND post_date < %s",
        $date_threshold
    ));
    if (empty($order_ids)) {
        error_log('No old cancelled or refunded orders to delete');
        return;
    }
    foreach ($order_ids as $order_id) {
        wp_delete_post($order_id, true);
        error_log('Deleted order ID: ' . $order_id);
    }
}

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

  • Ничего не удаляется: Проверьте правильность статусов заказов. WooCommerce добавляет префикс wc-, используйте именно wc-cancelled и wc-refunded.
  • WP-Cron не срабатывает: Убедитесь, что на сайте посещают страницы — WP-Cron зависит от трафика. Для надежности настройте системный Cron или плагин WP Crontrol для ручного запуска событий.
  • Удаление не полное, остаются метаданные: Функция wp_delete_post удаляет все связанные записи, но если есть кэш или сторонние плагины — очистите кэш.
  • Проблемы с правами доступа: Код должен выполняться от имени администратора или с достаточными правами. Размещайте в плагине или functions.php, протестируйте на локальной копии.

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

  • Не удаляйте заказы без резервных копий. Перед активацией функции сделайте бэкап базы данных.
  • Ограничьте удаление заказов старше определенного срока. В нашем примере — 30 дней, но вы можете увеличить или уменьшить.
  • Оптимизируйте запрос удаления по пакетам. Если заказов очень много, удаляйте партиями по 50-100 заказов, чтобы избежать таймаутов.
  • Для критически загруженных сайтов используйте системный Cron. WP-Cron зависит от посещаемости и может срабатывать с задержкой.
  • Добавьте логирование. Для отслеживания работы скрипта используйте error_log или внешние сервисы мониторинга.

Сравнение решений: плагин vs собственный код

КритерийСобственный кодПлагин (например, Advanced Database Cleaner)
Гибкость настроекПолный контроль, можно адаптировать под свои нуждыОграничена интерфейсом плагина
РесурсоемкостьМинимальная, выполняется быстро по расписаниюМожет нагружать сайт при сканировании базы
УдобствоТребуется знание PHP, настройка вручнуюИнтуитивный интерфейс, подходит новичкам
БезопасностьЗависит от качества кода разработчикаПроверяется автором плагина, но зависит от обновлений
ПоддержкаВаша ответственностьОбычно есть поддержка и обновления
Как добавить динамические атрибуты в shortcode WordPress
01.03.2026
Как добавить локализацию в свой плагин WordPress
27.11.2025
WooCommerce: автоматическое изменение стоимости товара при изменении количества в корзине
18.07.2026
Оптимизация загрузки изображений в WordPress для ускорения сайта
06.02.2026
Как добавить автоматическое удаление старых комментариев в WordPress
04.03.2026