Автоматическое закрытие неоплаченных заказов в WooCommerce через код

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

В стандартной настройке WooCommerce неоплаченные заказы могут оставаться в системе неопределенно долго. Это приводит к засорению базы данных, неправильной статистике и потенциальным проблемам с инвентарём. Особенно актуально для магазинов с большим потоком заказов и ограниченным запасом товаров.

Проверьте, есть ли у вас неоплаченные заказы со статусом pending или on-hold, которые не меняют статус более 24 часов:

SELECT ID, post_date, post_status FROM wp_posts WHERE post_type = 'shop_order' AND post_status IN ('wc-pending', 'wc-on-hold') AND post_date < NOW() - INTERVAL 1 DAY;

Если таких заказов много, автоматизация их закрытия решит проблему.

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

1. Создание WP-Cron задачи

Добавим в файл functions.php вашей темы или в кастомный плагин код, который создаст периодическую задачу для проверки и закрытия заказов.

if ( ! wp_next_scheduled( 'wc_auto_cancel_unpaid_orders' ) ) {
    wp_schedule_event( time(), 'hourly', 'wc_auto_cancel_unpaid_orders' );
}

add_action( 'wc_auto_cancel_unpaid_orders', 'wc_cancel_unpaid_orders' );

2. Функция для закрытия заказов

Реализуем функцию, которая найдет заказы со статусом pending или on-hold, которым больше 24 часов, и изменит их статус на cancelled.

function wc_cancel_unpaid_orders() {
    $args = [
        'limit'        => -1,
        'status'       => [ 'pending', 'on-hold' ],
        'date_created' => '<' . ( gmdate( 'Y-m-d H:i:s', strtotime( '-24 hours' ) ) ),
    ];

    $orders = wc_get_orders( $args );

    foreach ( $orders as $order ) {
        $order->update_status( 'cancelled', 'Автоматическое закрытие неоплаченного заказа через 24 часа.' );
    }
}

3. Очистка WP-Cron при деактивации

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

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

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

Через час после добавления кода выполните проверку:

  • Перейдите в WooCommerce - Заказы и отфильтруйте по статусу cancelled. Должны появиться автоматически закрытые заказы.
  • Запустите WP-Cron вручную через плагин WP Crontrol или WP-CLI команду wp cron event run wc_auto_cancel_unpaid_orders и проверьте, меняются ли статусы заказов.

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

  • WP-Cron не срабатывает: убедитесь, что на вашем хостинге не отключен WP-Cron, или настройте системный cron для запуска wp cron event run --due-now.
  • Заказы не меняют статус: проверьте, что статусы указаны правильно (с префиксом wc- внутри БД, но без префикса в функциях).
  • Большая нагрузка при большом количестве заказов: ограничьте выборку заказов, например, по дате или используйте пагинацию.

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

  • Используйте limit в запросах wc_get_orders, чтобы не перегружать сервер при большом количестве заказов.
  • Избегайте частого запуска WP-Cron — достаточно один раз в час или реже, чтобы не нагружать сайт.
  • Для контроля и логирования работы функции можно добавить запись в системный лог или отдельную таблицу.
  • При необходимости интегрируйте с плагином Clearfy Pro от WPShop для дополнительной оптимизации и чистки базы.

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

МетодПреимуществаНедостатки
Ручное закрытиеПростота, контрольТрудозатратно, ошибки
Плагин (например, WooCommerce Order Status Manager)Готовое решение, UIЗависимость от стороннего кода, нагрузка
Код с WP-Cron (как в статье)Легковесно, гибко, без плагиновТребует технических навыков, настройка WP-Cron

Наш каталог плагинов WordPress