Диагностика проблемы с неактивными заказами в WooCommerce
В интернет-магазинах на WooCommerce со временем накапливаются заказы, которые не были оплачены, отменены или находятся в состоянии ожидания слишком долго. Такие заказы занимают место в базе данных, замедляют работу админки и могут мешать аналитике. В стандартном функционале WooCommerce нет инструмента для массового удаления таких заказов по определённым критериям — пользователю приходится делать это вручную или с помощью сторонних плагинов, которые не всегда подходят.
Чаще всего проблема проявляется так:
- В разделе заказов много записей со статусом
pending,failedилиcancelled. - База данных растёт, размер таблиц
wp_postsиwp_postmetaувеличивается, что сказывается на производительности. - Невозможно быстро очистить старые неактивные заказы без риска затронуть актуальные.
Пошаговое решение: скрипт автоматического удаления заказов по статусу и дате
Оптимальный подход — создать кастомную функцию, которая по Cron будет удалять заказы с определёнными статусами старше заданного количества дней. Вот пример рабочего кода для functions.php вашей темы или кастомного плагина:
function wc_delete_old_orders_by_status() {
if ( ! current_user_can( 'manage_woocommerce' ) ) {
return;
}
$statuses_to_delete = array( 'pending', 'failed', 'cancelled' );
$days_old = 30; // Количество дней, старше которых заказы будут удалены
$cutoff_date = date( 'Y-m-d H:i:s', strtotime( "-{$days_old} days" ) );
$args = array(
'post_type' => 'shop_order',
'post_status' => $statuses_to_delete,
'date_query' => array(
array(
'column' => 'post_date',
'before' => $cutoff_date,
),
),
'posts_per_page' => -1,
'fields' => 'ids',
'no_found_rows' => true,
);
$orders = get_posts( $args );
if ( empty( $orders ) ) {
return;
}
foreach ( $orders as $order_id ) {
wp_delete_post( $order_id, true ); // true — удаление без перемещения в корзину
}
}
// Создаем Cron-задачу, если не существует
if ( ! wp_next_scheduled( 'wc_delete_old_orders_event' ) ) {
wp_schedule_event( time(), 'daily', 'wc_delete_old_orders_event' );
}
add_action( 'wc_delete_old_orders_event', 'wc_delete_old_orders_by_status' );В этом коде:
$statuses_to_delete— массив статусов заказов для удаления.$days_old— число дней, по истечении которых заказы считаются устаревшими.- Используем WP_Query с
date_queryдля выборки заказов по дате создания. - Удаляем заказы принудительно (
wp_delete_postс параметромtrue). - Создаётся ежедневное событие Cron для автоматического запуска функции.
Как подключить и активировать скрипт
- Вставьте код в файл
functions.phpактивной темы или создайте отдельный мини-плагин. - Убедитесь, что на сайте включён WP-Cron (по умолчанию активирован).
- При необходимости вызовите функцию вручную для проверки.
// Временный вызов для теста
add_action( 'init', function() {
if ( isset( $_GET['test_delete_orders'] ) && current_user_can( 'manage_woocommerce' ) ) {
wc_delete_old_orders_by_status();
exit( 'Old orders deleted.' );
}
} );Проверка результата после внедрения
Чтобы убедиться, что автоматическое удаление работает:
- Добавьте параметр
?test_delete_orders=1к URL сайта, будучи авторизованным админом. После обновления появится сообщение об удалении. - Проверьте раздел WooCommerce — Заказы в админке: устаревшие заказы должны исчезнуть.
- Посмотрите в базу данных (таблицы
wp_postsиwp_postmeta): записи заказов со старыми статусами должны отсутствовать. - Проверьте запуск Cron — можно использовать плагин WP Crontrol для контроля задач.
Частые ошибки и способы их исправления
- Не удаляются заказы: Проверьте, что статус заказа в массиве
$statuses_to_deleteточно совпадает с существующими статусами. Используйтеwc_get_order_statuses()для проверки. - WP-Cron не срабатывает: Удостоверьтесь, что на сайте есть посещения, так как WP-Cron запускается при загрузках страниц. Для серверов без трафика настройте системный cron job.
- Удаляются нужные заказы: Будьте осторожны с выбором статусов и периода удаления. Проверьте логику и протестируйте на копии сайта.
- Проблемы с правами доступа: Функция проверяет
current_user_can('manage_woocommerce'), запускайте её от имени администратора.
Практические советы по безопасности и производительности
- Не удаляйте заказы без резервного копирования — удаление необратимо.
- Используйте
wp_delete_post( $order_id, true )для полного удаления, иначе заказ попадёт в корзину. - Для сайтов с большим количеством заказов делайте удаление партиями — добавьте параметр
posts_per_page50-100 и используйте циклы. - Если база очень большая, рассчитайте cron-задания через WP-CLI для ускорения.
- По возможности создайте отдельный плагин для кода, чтобы не потерять изменения при обновлении темы.
Сравнение вариантов удаления заказов
| Метод | Плюсы | Минусы |
|---|---|---|
| Скрипт в functions.php | Лёгкий контроль, без сторонних плагинов | Риск ошибок, зависит от активной темы |
| Отдельный кастомный плагин | Удобно поддерживать и обновлять | Требуется базовые навыки плагин-разработки |
| Сторонние плагины (например, WP Bulk Delete) | Простота установки и интерфейс | Могут грузить сайт, лишний функционал |