Диагностика проблемы: зачем удалять неактивные заказы в WooCommerce
Магазины на WooCommerce часто сталкиваются с накоплением заказов в статусе «ожидает оплаты» или других неактивных статусов. Это приводит к раздуванию базы данных, ухудшению производительности и затрудняет аналитику. Вопрос: как автоматизировать очистку таких заказов, не удаляя активные и завершённые?
Что считать неактивным заказом
Чаще всего неактивный заказ — это заказ, который долгое время находится в статусе pending, failed или on-hold без изменений. Для примера возьмём заказы, которые не обновлялись более 7 дней.
Пошаговое решение: настройка автоматического удаления заказов с помощью Cron и PHP
Реализуем задачу на примере пользовательского кода в functions.php вашей темы или в отдельном плагине.
1. Создание функции для удаления неактивных заказов
function wpzen_delete_inactive_orders() {
$days = 7; // Кол-во дней без активности
$date_threshold = date('Y-m-d H:i:s', strtotime("-{$days} days"));
// Получаем заказы в статусах pending, failed, on-hold старше даты
$args = [
'limit' => -1,
'status' => ['pending', 'failed', 'on-hold'],
'date_modified' => '<' . $date_threshold,
'return' => 'ids',
];
$orders = wc_get_orders($args);
if (empty($orders)) {
return;
}
foreach ($orders as $order_id) {
wp_delete_post($order_id, true); // Принудительное удаление
}
}Обратите внимание, что мы используем wc_get_orders с фильтром по дате модификации, что позволяет точно отсеять устаревшие заказы.
2. Добавление Cron задачи в WordPress
Чтобы выполнять функцию регулярно, регистрируем собственное событие cron и запускаем его ежедневно.
// Регистрируем событие при активации темы/плагина
function wpzen_schedule_delete_orders() {
if (!wp_next_scheduled('wpzen_delete_inactive_orders_event')) {
wp_schedule_event(time(), 'daily', 'wpzen_delete_inactive_orders_event');
}
}
add_action('wp', 'wpzen_schedule_delete_orders');
// Обработчик события
add_action('wpzen_delete_inactive_orders_event', 'wpzen_delete_inactive_orders');
// Очистка при деактивации
function wpzen_clear_scheduled_delete_orders() {
$timestamp = wp_next_scheduled('wpzen_delete_inactive_orders_event');
if ($timestamp) {
wp_unschedule_event($timestamp, 'wpzen_delete_inactive_orders_event');
}
}
register_deactivation_hook(__FILE__, 'wpzen_clear_scheduled_delete_orders');Проверка результата после внедрения
Для проверки, что автоматическое удаление работает:
- Создайте тестовый заказ со статусом
pendingи измените дату его модификации в базе (например, вручную через phpMyAdmin) на дату старше 7 дней. - Запустите вручную функцию
wpzen_delete_inactive_orders()через WP-CLI или добавьте временный вызов в код. - Проверьте, что заказ удалился из админки WooCommerce.
- Подождите выполнение cron (или вызовите wp-cron.php вручную) и убедитесь, что автоматизация работает.
Частые ошибки и как их исправить
- Код не запускается по Cron
Причина: WP Cron не активен на сервере или редиректы блокируют его. Проверьте, что wp-cron.php вызывается либо через реальный Cron на сервере, либо через посещения сайта. - Удаляются не те заказы
Проверьте параметры фильтрации вwc_get_orders. Убедитесь, что дата модификации корректно сравнивается. Можно в отладке вывести список ID до удаления. - Заказы не удаляются полностью
Функцияwp_delete_postс параметромtrueудаляет заказ без возможности восстановления. Если параметр пропущен, заказ может попасть в корзину. - Потеря данных
Перед удалением обязательно сделайте резервную копию базы. Можно добавить логику перемещения в специальный статус или таблицу, если нужна дополнительная безопасность.
Практические советы по безопасности и производительности
- Добавьте проверку прав текущего пользователя, если функция запускается вручную из админки.
- Ограничьте количество удаляемых заказов за один запуск, чтобы не перегружать сервер.
- Рекомендуется использовать WP-CLI для запуска больших операций на больших магазинах.
- Добавьте логирование удалённых заказов для аудита:
function wpzen_delete_inactive_orders() {
$days = 7;
$date_threshold = date('Y-m-d H:i:s', strtotime("-{$days} days"));
$args = [
'limit' => 50,
'status' => ['pending', 'failed', 'on-hold'],
'date_modified' => '<' . $date_threshold,
'return' => 'ids',
];
$orders = wc_get_orders($args);
if (empty($orders)) return;
foreach ($orders as $order_id) {
error_log("Удаляем заказ #" . $order_id);
wp_delete_post($order_id, true);
}
}Сравнение вариантов удаления неактивных заказов
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Плагин автоматизации | Простой, готовый функционал, поддержка | Может быть избыточным или платным | Использовать для крупных магазинов |
| Собственный код + WP Cron | Легко кастомизировать, бесплатно | Требует навыков, возможны ошибки в логике | Для разработчиков и небольших магазинов |
| Ручное удаление через админку | Контроль, простота | Ручной труд, риск пропуска заказов | Для разовых чисток |