Проблема: накопление неактивных заказов в WooCommerce и нагрузка на базу данных
В интернет-магазинах на WooCommerce с большим количеством трафика и заказов часто возникает ситуация, когда в базе накапливаются заказы с задержками оплаты, отменённые или «зависшие» в статусах вроде «ожидает оплаты» или «в обработке». Это замедляет работу админки, увеличивает размер базы и усложняет аналитику.
Ручное удаление неэффективно и требует времени. Поэтому задача — реализовать автоматическое удаление заказов, которые остаются в неактивных статусах дольше определённого времени.
Диагностика: как определить, какие заказы подлежат удалению
Первый шаг — получить список заказов с целевыми статусами и датой создания старше заданного периода. Статусы могут быть стандартными WooCommerce (pending, failed, cancelled) или кастомными.
Для диагностики используйте следующий пример кода для вывода таких заказов в лог:
function debug_old_inactive_orders() {
$args = [
'limit' => -1,
'status' => ['pending', 'failed', 'cancelled'],
'date_created' => '<' . ( new WC_DateTime( '-30 days' ) )->format( 'Y-m-d H:i:s' ),
'return' => 'ids',
];
$orders = wc_get_orders( $args );
error_log('Found ' . count($orders) . ' inactive orders older than 30 days.');
}
add_action('init', 'debug_old_inactive_orders');В логах сервера появится количество заказов, подходящих под критерии. Если их много — можно приступать к автоматизации очистки.
Пошаговое решение: автоматическое удаление заказов по расписанию
1. Создание WP-Cron задачи
Добавьте в файл functions.php или в собственный плагин код для регистрации и выполнения повторяющейся задачи:
if ( ! wp_next_scheduled( 'wc_delete_old_inactive_orders_hook' ) ) {
wp_schedule_event( time(), 'daily', 'wc_delete_old_inactive_orders_hook' );
}
add_action( 'wc_delete_old_inactive_orders_hook', 'wc_delete_old_inactive_orders' );
function wc_delete_old_inactive_orders() {
$days = 30; // Период старости заказов для удаления
$args = [
'limit' => -1,
'status' => ['pending', 'failed', 'cancelled'],
'date_created' => '<' . ( new WC_DateTime( "-{$days} days" ) )->format( 'Y-m-d H:i:s' ),
'return' => 'ids',
];
$orders = wc_get_orders( $args );
foreach ( $orders as $order_id ) {
$order = wc_get_order( $order_id );
if ( $order ) {
$order->delete( true ); // true = удаление без возможности восстановления
}
}
}2. Очистка WP-Cron (при необходимости)
Для проверки и очистки задач WP-Cron используйте плагин WP Crontrol. Там можно отследить расписание, запуск и при необходимости принудительно выполнить задачу.
Проверка результата после внедрения
- Запустите задачу вручную через WP Crontrol — заказы старше 30 дней и с указанными статусами должны удалиться.
- Проверьте таблицу
wp_posts(типshop_order) через phpMyAdmin или аналог, чтобы убедиться, что старые заказы отсутствуют. - В админке WooCommerce в разделе заказов проверьте количество заказов с целевыми статусами — они должны уменьшиться.
Частые ошибки и как их исправить
- Отсутствие прав на удаление заказов. Убедитесь, что код выполняется с достаточными правами (обычно в контексте администратора). Ошибка может возникать, если код запускается в ранних хуках без доступа к WooCommerce.
- Неправильные статусы заказов. Проверьте, что статусы указаны верно (без опечаток). Используйте
wc_get_order_statuses()для просмотра всех статусов. - Не запускается WP-Cron. На некоторых хостингах WP-Cron по умолчанию отключён, либо не срабатывает без посещений сайта. Для гарантированного выполнения настройте системный cron или используйте плагин для обхода.
- Удаляются нужные заказы. Проверьте дату и статус в запросе — возможно, стоит увеличить или уменьшить период хранения.
Практические советы по безопасности и производительности
- Резервное копирование. Перед внедрением автоматического удаления сделайте бэкап базы данных.
- Пакетная обработка. Если заказов много, делайте удаление порциями, чтобы избежать таймаутов. Например, обрабатывайте по 50 заказов за один запуск и запускате задачу чаще.
- Логирование. Добавьте запись в лог об удалённых заказах для аудита:
function wc_delete_old_inactive_orders() {
$days = 30;
$args = [
'limit' => 50,
'status' => ['pending', 'failed', 'cancelled'],
'date_created' => '<' . ( new WC_DateTime( "-{$days} days" ) )->format( 'Y-m-d H:i:s' ),
'return' => 'ids',
];
$orders = wc_get_orders( $args );
foreach ( $orders as $order_id ) {
$order = wc_get_order( $order_id );
if ( $order ) {
$order->delete( true );
error_log( "Deleted old inactive order #{$order_id}" );
}
}
}
Сравнение вариантов удаления заказов
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Ручное удаление через админку | Просто, без кода | Неэффективно при большом количестве, риск ошибки | Подходит для единичных случаев |
| Автоматическое удаление WP-Cron + код | Полная автоматизация, гибкость по статусам и времени | Нужна настройка, возможны ошибки с WP-Cron | Рекомендуется для средних и крупных магазинов |
| Плагины очистки WooCommerce | Готовые решения с интерфейсом | Меньше контроля, возможны лишние функции | Удобно при отсутствии навыков программирования |