WooCommerce: автоматическое изменение статуса заказа при отсутствии платежа

Диагностика проблемы: заказ остается в статусе "ожидает платежа" слишком долго

Иногда в WooCommerce заказы остаются в статусе pending (ожидает платежа) после того, как пользователь покинул сайт или не завершил оплату. Это приводит к захламлению базы и сбивает статистику продаж. Нужно автоматически переводить такие заказы в статус cancelled или failed спустя определенное время.

Как проверить текущие заказы с долгим статусом "pending"

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

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

Пошаговое решение: автоматическое изменение статуса через WP-Cron

1. Создаем функцию для смены статуса заказов

function wpdemo_cancel_unpaid_orders() {
    $args = [
        'limit'        => -1,
        'status'       => 'pending',
        'date_created' => '<' . ( time() - 24 * 60 * 60 ) // заказы старше 24 часов
    ];
    $orders = wc_get_orders( $args );

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

2. Регистрируем WP-Cron задачу для ежедневного запуска

function wpdemo_schedule_cancel_unpaid_orders() {
    if ( ! wp_next_scheduled( 'wpdemo_cancel_unpaid_orders_hook' ) ) {
        wp_schedule_event( time(), 'daily', 'wpdemo_cancel_unpaid_orders_hook' );
    }
}
add_action( 'wp', 'wpdemo_schedule_cancel_unpaid_orders' );

add_action( 'wpdemo_cancel_unpaid_orders_hook', 'wpdemo_cancel_unpaid_orders' );

3. Очистка при деактивации плагина или темы

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

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

Через сутки после активации функции проверьте наличие отмененных заказов через панель WooCommerce или по SQL-запросу:

SELECT ID, post_status, post_date FROM wp_posts WHERE post_type = 'shop_order' AND post_status = 'wc-cancelled' AND post_date > NOW() - INTERVAL 2 DAY;

Если новые заказы автоматически меняют статус, значит задача работает корректно.

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

  • Задача WP-Cron не запускается: проверьте системный CRON или настройте реальный cron на сервере, поскольку WP-Cron зависит от посещений сайта.
  • Функция не находит заказы: убедитесь, что параметр date_created передается корректно (time() в формате UNIX timestamp, а wc_get_orders ожидает объект даты или строку).
  • Статус не меняется: проверьте права пользователя, под которым работает PHP, а также логи ошибок.

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

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

Альтернативы: плагин vs собственный код

МетодПреимуществаНедостатки
Плагин (например, WooCommerce Order Status Control)Готовое решение, интерфейс настройки, поддержкаМожет нагружать сайт, ограниченная кастомизация
Собственный WP-Cron скриптПолный контроль, легковесность, можно адаптироватьТребует навыков, нужно следить за работой
WooCommerce: автоматическое возвратное действие при отклонённом платеже
03.05.2026
WooCommerce: автоматическое отключение товаров при отсутствии на складе с возможностью возврата
07.06.2026
WP-Cron не работает: как исправить проблему в WordPress
15.11.2025
Как настроить автозаполнение форм в WordPress с помощью AJAX
16.04.2026
Как создать настройки для своего плагина WordPress с примерами кода
24.11.2025