WooCommerce: как автоматически удалять отменённые и возвращённые заказы

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

В крупных интернет-магазинах на WooCommerce количество отменённых и возвращённых заказов со временем растёт, засоряя базу данных и замедляя работу сайта. Это особенно заметно при использовании расширенной аналитики и отчётов, где старые заказы создают лишнюю нагрузку. Ручное удаление заказов неудобно и рискованно. Поэтому важна автоматизация этого процесса.

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

1. Добавление кода в functions.php вашей темы или в кастомный плагин

Для удаления заказов со статусом cancelled (отменён) и refunded (возвращён) используем хук wp_scheduled_delete — он вызывается при очистке корзины для мусора и устаревших данных. Добавим функцию, которая будет искать заказы и удалять их безвозвратно.

add_action('wp_scheduled_delete', 'wc_auto_delete_cancelled_refunded_orders');
function wc_auto_delete_cancelled_refunded_orders() {
    if (!class_exists('WC_Order_Query')) {
        return;
    }

    $statuses_to_delete = array('cancelled', 'refunded');

    foreach ($statuses_to_delete as $status) {
        $query = new WC_Order_Query(array(
            'limit' => -1, // без лимита
            'status' => $status,
            'return' => 'ids',
            'date_modified' => '<' . (time() - MONTH_IN_SECONDS * 3), // старше 3 месяцев
        ));
        $order_ids = $query->get_orders();

        foreach ($order_ids as $order_id) {
            wp_delete_post($order_id, true); // true — безвозвратно
        }
    }
}

2. Настройка интервала выполнения задачи WP-Cron

По умолчанию wp_scheduled_delete запускается еженощно. Если хотите более частое удаление, добавьте кастомный интервал:

add_filter('cron_schedules', 'custom_cron_intervals');
function custom_cron_intervals($schedules) {
    $schedules['every_six_hours'] = array(
        'interval' => 21600, // 6 часов в секундах
        'display' => __('Каждые 6 часов')
    );
    return $schedules;
}

if (!wp_next_scheduled('wp_scheduled_delete')) {
    wp_schedule_event(time(), 'every_six_hours', 'wp_scheduled_delete');
}

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

  • Создайте тестовый заказ со статусом cancelled или refunded, установите дату изменения более 3 месяцев назад (через phpMyAdmin или плагин для управления базой).
  • Принудительно запустите задачу WP-Cron, например, с помощью плагина WP Crontrol или вызвав do_action('wp_scheduled_delete') в консоли WP-CLI.
  • Проверьте, что заказ удалён из базы и больше не отображается в админке WooCommerce.
  • Убедитесь, что остальные заказы не пострадали.

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

  • Заказы не удаляются: Проверьте, активен ли WP-Cron и запускается ли задача wp_scheduled_delete. Можно проверить с помощью плагина WP Crontrol.
  • Удаляются нужные заказы: Убедитесь, что фильтр 'date_modified' настроен корректно и не затрагивает свежие заказы.
  • Проблемы с производительностью при большом количестве заказов: Разбейте удаление на партии с лимитом, например, по 100 заказов за раз.
  • Ошибки при удалении из-за зависимостей плагинов: Проверьте совместимость и отключите сторонние плагины, влияющие на типы заказов.

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

  • Создайте резервную копию базы данных перед внедрением автоматического удаления.
  • Используйте транзакции или WP-CLI для пакетного удаления, если заказов много, чтобы избежать таймаутов.
  • Не удаляйте заказы, которые могут понадобиться для отчетности или возвратов налогов — согласуйте с бухгалтерией.
  • Мониторьте логи ошибок сервера и WP, чтобы вовремя заметить сбои.

Таблица сравнения способов удаления заказов

МетодПлюсыМинусыКомпромисс
Ручное удаление через админкуПростота, контрольТрудозатратно, риск ошибокПодходит для малых магазинов
Автоудаление через WP-Cron + кодАвтоматизация, экономия времениНужна настройка и тестыОптимально для средних и больших магазинов
Плагины очистки базыУдобство, доп. функцииМожет конфликтовать, нагрузкаИспользовать с осторожностью, тестировать

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

function wc_delete_orders_in_batches($status, $batch_size = 100) {
    $query = new WC_Order_Query(array(
        'limit' => $batch_size,
        'status' => $status,
        'return' => 'ids',
        'date_modified' => '<' . (time() - MONTH_IN_SECONDS * 3),
    ));
    $order_ids = $query->get_orders();

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

    return count($order_ids);
}

add_action('wp_scheduled_delete', function() {
    $statuses = array('cancelled', 'refunded');
    foreach ($statuses as $status) {
        while (wc_delete_orders_in_batches($status) > 0) {
            // продолжаем удалять пока есть заказы
        }
    }
});
Как использовать хуки в WordPress для расширения функционала
23.11.2025
Как автоматически удалять неактивных пользователей в WordPress
25.03.2026
Автоматический импорт CSV в WordPress: пошаговое руководство
08.01.2026
Как создать мульти-регионный сайт на WordPress с помощью GeoIP
23.02.2026
Как создать собственный шорткод в WordPress
27.11.2025