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

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

В магазинах на WooCommerce часто накапливается большое количество неоплаченных заказов, особенно при оплате через банковские переводы или отложенные платежи. Это может привести к:

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

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

Выбор способа автоматизации

Есть три основных варианта решения задачи:

СпособОписаниеПлюсыМинусы
Плагин (например, WooCommerce Cancel Unpaid Orders)Готовое решение с настройкамиПростота установки, настройка без кодаДополнительная нагрузка, меньше контроля
WP-Cron задача в functions.phpРегулярная проверка и отмена заказов через кодПолный контроль, без лишних плагиновЗависит от WP-Cron, может не сработать на низком трафике
Настройка системного cron и WP-CLIВызов скрипта из системного cronНадежность, не зависит от трафикаТребует доступа к серверу, сложнее в настройке

Пошаговое решение на примере WP-Cron и кода

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

function wpapp_cancel_unpaid_orders() {
    if ( ! class_exists( 'WC_Order_Query' ) ) {
        return;
    }

    $args = array(
        'limit'        => -1,
        'status'       => array('pending', 'failed'),
        'date_created' => '<' . ( time() - 60 * 60 * 24 ), // старше 24 часов
    );

    $orders = wc_get_orders( $args );

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

2. Регистрируем событие WP-Cron

function wpapp_schedule_cancel_unpaid_orders() {
    if ( ! wp_next_scheduled( 'wpapp_cancel_unpaid_orders_event' ) ) {
        wp_schedule_event( time(), 'hourly', 'wpapp_cancel_unpaid_orders_event' );
    }
}
add_action( 'wp', 'wpapp_schedule_cancel_unpaid_orders' );

add_action( 'wpapp_cancel_unpaid_orders_event', 'wpapp_cancel_unpaid_orders' );

3. Проверяем наличие и удаление cron задачи при деактивации

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

Как проверить, что решение сработало

  • Создайте тестовый заказ со статусом pending или failed с датой создания более 24 часов назад (можно изменить дату в базе вручную для теста)
  • Запустите событие WP-Cron вручную с помощью плагина WP Crontrol или дождитесь автоматического запуска
  • Проверьте, что статус заказа изменился на cancelled и в комментариях заказа появилась запись об автоматической отмене
  • Проверьте журнал ошибок сервера на наличие ошибок выполнения функции

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

  • Отсутствие запуска WP-Cron из-за низкого трафика: Проверьте логи, запустите cron вручную с WP Crontrol или настройте системный cron для вызова wp-cron.php.
  • Неправильный формат даты в date_created: Убедитесь, что время передается в формате UNIX timestamp и правильно сравнивается.
  • Функция wc_get_orders не доступна: Убедитесь, что код выполняется после инициализации WooCommerce (например, хук init или позднее).
  • Отмена заказов с важными статусами: Проверьте, что фильтр статусов в запросе включает только нужные статусы (pending, failed), чтобы не отменять оплаченные заказы.

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

  • Не запускайте отмену заказов слишком часто — достаточно один раз в час, чтобы не нагружать базу.
  • Добавьте логирование действий в отдельный файл или используйте системный журнал для аудита.
  • При большом количестве заказов разбивайте обработку на части, используя пагинацию (limit и offset) в wc_get_orders.
  • Используйте функции WooCommerce для обновления статуса, чтобы не нарушить логику плагина.

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