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

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

В интернет-магазинах на WooCommerce часто скапливаются заказы со статусом «ожидание оплаты» или «в ожидании», которые остаются открытыми месяцами. Это увеличивает нагрузку на базу данных, замедляет отчёты и усложняет администрирование. Автоматическое удаление таких заказов помогает поддерживать чистоту данных и оптимизировать работу магазина.

Как понять, что проблема есть?

  • В разделе «Заказы» WooCommerce много записей со статусом «ожидание оплаты» старше 30 дней.
  • Отчёты WooCommerce и админка работают медленно.
  • Рост размера базы данных без очевидных причин.

Для быстрой проверки можно выполнить SQL-запрос в phpMyAdmin:

SELECT COUNT(*) FROM wp_posts WHERE post_type = 'shop_order' AND post_status = 'wc-pending' AND post_date < DATE_SUB(NOW(), INTERVAL 30 DAY);

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

Пошаговое решение: настройка автоматического удаления просроченных заказов через WP-Cron

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

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

function wpgen_delete_expired_orders() {
    global $wpdb;
    $threshold = 30; // дней

    // Получаем ID заказов в статусе 'pending' старше $threshold дней
    $orders = $wpdb->get_col($wpdb->prepare(
        "SELECT ID FROM {$wpdb->posts} 
        WHERE post_type = 'shop_order' 
        AND post_status = 'wc-pending' 
        AND post_date < DATE_SUB(NOW(), INTERVAL %d DAY)", 
        $threshold
    ));

    if (!empty($orders)) {
        foreach ($orders as $order_id) {
            wp_trash_post($order_id); // переводим заказ в корзину
            // Если нужно полностью удалить, используйте wp_delete_post($order_id, true);
        }
    }
}

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

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

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

add_action('wpgen_delete_expired_orders_cron_hook', 'wpgen_delete_expired_orders');

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

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

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

  • Через 24 часа проверьте список заказов в WooCommerce — заказы со статусом wc-pending, которым более 30 дней, должны быть перемещены в корзину (или удалены, если использовали wp_delete_post).
  • Для быстрой проверки запустите функцию вручную в консоли WP-CLI: wp eval 'wpgen_delete_expired_orders();'
  • Проверьте логи ошибок сервера на отсутствие PHP-ошибок.

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

  • Функция не вызывается автоматически: Проверьте, активен ли WP-Cron (файл wp-config.php не должен содержать define('DISABLE_WP_CRON', true);), либо настройте системный cron на вызов wp-cron.php.
  • Заказы не удаляются: Убедитесь, что статус заказа точно wc-pending. В WooCommerce статусы начинаются с wc-. Также проверьте права доступа базы данных.
  • Удаляются не те заказы: Проверьте SQL-запрос и условие даты. Для теста уменьшите $threshold до 1 дня.
  • Удаление слишком агрессивное: Вместо wp_delete_post используйте wp_trash_post, чтобы сначала переместить заказ в корзину и иметь возможность восстановить.

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

  • Перед автоматическим удалением рекомендуем делать резервную копию базы данных.
  • Если заказов очень много, разбивайте удаление на партии, чтобы не перегрузить сервер:
function wpgen_delete_expired_orders_batch() {
    global $wpdb;
    $threshold = 30; // дней
    $batch_size = 50; // количество за раз

    $orders = $wpdb->get_col($wpdb->prepare(
        "SELECT ID FROM {$wpdb->posts} 
        WHERE post_type = 'shop_order' 
        AND post_status = 'wc-pending' 
        AND post_date < DATE_SUB(NOW(), INTERVAL %d DAY) 
        LIMIT %d",
        $threshold,
        $batch_size
    ));

    if (!empty($orders)) {
        foreach ($orders as $order_id) {
            wp_trash_post($order_id);
        }
    }
}
  • Используйте транзакции базы данных, если нужно комплексное удаление связанных данных.
  • Оповещайте администратора по почте при удалении, чтобы контролировать процесс.

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

МетодПлюсыМинусыПример
Ручное удалениеПростой контроль, нет риска автоматических ошибокТрудозатратно, неэффективно при большом количестве заказовАдминка WooCommerce
WP-Cron + кастомный кодАвтоматизация, гибкость настройкиЗависит от работы WP-Cron, требует тестированияКод из статьи
Плагины очистки базыУдобство, дополнительные функцииМожет быть избыточным, возможны конфликтыClearfy Pro (https://wpshop.ru/plugins/clearfy?utm_source=wpgen.ru&utm_medium=article&utm_campaign=woocommerce-avtomaticheskoe-udaleniye-prosrochennyh-zakazov-s-pomoshhyu-wp-cron)
WooCommerce: автоматическое удаление товаров по срокам с помощью WP-Cron
07.06.2026
Как добавить автоматическое удаление спам-комментариев в WordPress
24.03.2026
WooCommerce: автоматическое удаление просроченных заказов с помощью WP-Cron
17.07.2026
Как сделать защитные метаполя в WordPress для хранения персональных данных
24.12.2025
Оптимизация базы данных WordPress для повышения производительности сайта
16.11.2025