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

Почему важно автоматически удалять просроченные заказы в WooCommerce

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

Диагностика проблемы с просроченными заказами

Для начала определимся, что считать просроченным заказом. Обычно это заказы со статусом pending или on-hold, которые не были оплачены в течение определённого времени (например, 7 дней). Чтобы проверить, сколько таких заказов у вас сейчас, выполните запрос в базе данных или используйте WP-CLI:

wp post list --post_type=shop_order --post_status=pending --field=ID | wc -l

Этот пример покажет количество заказов со статусом pending. Аналогично для on-hold.

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

1. Добавляем функцию для удаления просроченных заказов

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

function wpset_delete_expired_orders() {
    $days_to_keep = 7; // количество дней до удаления
    $statuses = array('pending', 'on-hold'); // статусы для проверки

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

    $args = array(
        'post_type' => 'shop_order',
        'post_status' => $statuses,
        'date_query' => array(
            array(
                'column' => 'post_date',
                'before' => $date_threshold,
            ),
        ),
        'fields' => 'ids',
        'posts_per_page' => -1,
    );

    $orders = get_posts($args);

    if (!empty($orders)) {
        foreach ($orders as $order_id) {
            wp_delete_post($order_id, true); // true - удалять без восстановления
        }
    }
}

2. Настраиваем крон задачу для регулярного запуска

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

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

add_action('wpset_daily_expired_orders_cleanup', 'wpset_delete_expired_orders');

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

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

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

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

  • Выполните заказы в статусах pending и on-hold старше 7 дней в базе данных (можно вручную через админку или БД).
  • Запустите функцию вручную для теста, вызвав wpset_delete_expired_orders(); из файла или консоли WP-CLI.
  • Убедитесь, что заказы удалены без ошибок и больше не отображаются в списке заказов.
  • Проверьте логи сервера на предмет ошибок при запуске cron.

Частые ошибки и способы исправления

  • Заказы не удаляются: Проверьте, что функция действительно вызывается. Для отладки добавьте в функцию error_log('Удаление заказов запущено');, чтобы убедиться в срабатывании.
  • Крон-задача не запускается: Убедитесь, что на сервере работает WP-Cron. Если сайт низко посещаемый, используйте системный cron для запуска wp-cron.php.
  • Удаление не происходит из-за прав: Проверьте, что ваш PHP-процесс имеет права на удаление записей в базе данных.
  • Непреднамеренное удаление: Проверьте корректность условий выборки заказов, чтобы не удалить актуальные заказы.

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

  • Удаляйте заказы принудительно (wp_delete_post($order_id, true)), чтобы избежать попадания в корзину мусора.
  • Для больших магазинов с тысячами заказов разбивайте удаление на порции (batch), чтобы избежать таймаутов:
function wpset_delete_expired_orders_batch() {
    $days_to_keep = 7;
    $statuses = array('pending', 'on-hold');
    $date_threshold = date('Y-m-d H:i:s', strtotime('-' . $days_to_keep . ' days'));

    $args = array(
        'post_type' => 'shop_order',
        'post_status' => $statuses,
        'date_query' => array(
            array(
                'column' => 'post_date',
                'before' => $date_threshold,
            ),
        ),
        'fields' => 'ids',
        'posts_per_page' => 50, // порция из 50 заказов
    );

    $orders = get_posts($args);

    if (!empty($orders)) {
        foreach ($orders as $order_id) {
            wp_delete_post($order_id, true);
        }
        // Запустить повторно в следующий раз cron
    }
}
  • Для большей безопасности добавьте логирование удалённых заказов, чтобы иметь возможность отслеживать действия.
  • Если магазин интегрирован с внешними сервисами, убедитесь, что удаление заказов не нарушает логику синхронизации.

Сравнение вариантов очистки просроченных заказов

МетодПлюсыМинусыКогда использовать
Ручное удаление через админку Простота, не требует кода Затратно по времени, риск забыть Маленькие магазины с редкими просрочками
Плагины автоматизации (например, WP-Optimize) Удобство, дополнительные функции Нагрузка, возможны конфликты, не всегда гибко Если нужна комплексная оптимизация с UI
Кодовая реализация с WP-Cron (как в статье) Гибкость, контроль, без лишних плагинов Требует знаний, ответственность за поддержку Средние и крупные магазины с нуждой в кастомизации