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

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

В WooCommerce нередко возникают ситуации, когда пользователь начинает оформление заказа, но не завершается оплата. Такие заказы остаются в статусе "ожидается оплата" или "в обработке" длительное время, создавая путаницу в админке и потенциально влияя на учет и складские запасы. Автоматическое отключение возможности оплаты по таким неактивным заказам помогает поддерживать чистоту данных и снижает нагрузку на систему.

Как определить неактивный заказ в WooCommerce

Основным критерием неактивного заказа является длительность нахождения заказа в статусе, требующем оплаты, без изменений. Чаще всего это статус pending (ожидается оплата). Можно отслеживать заказы, которые находятся в этом статусе более определенного времени, например, 24 часа.

Пример SQL-запроса для диагностики

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

Этот запрос покажет заказы в статусе pending, созданные более суток назад.

Пошаговое решение: автоматическое отключение оплаты

1. Добавляем метаполе для блокировки оплаты

Будем использовать пользовательское поле заказа disable_payment, которое при значении true будет блокировать оплату.

2. Функция для отключения оплаты

function disable_payment_for_inactive_orders() {
    $args = array(
        'status' => 'pending',
        'date_created' => '<' . ( new WC_DateTime() )->modify('-1 day')->format('Y-m-d H:i:s'),
        'limit' => -1
    );

    $orders = wc_get_orders($args);

    foreach ($orders as $order) {
        // Устанавливаем метаполе для блокировки оплаты
        $order->update_meta_data('disable_payment', 'true');
        $order->save();
    }
}

// Запуск функции ежедневно через WP-Cron
add_action('wp_ajax_disable_payment_cron', 'disable_payment_for_inactive_orders');
add_action('wp_ajax_nopriv_disable_payment_cron', 'disable_payment_for_inactive_orders');

// Для запуска по расписанию зарегистрируем событие
if (!wp_next_scheduled('disable_payment_daily_event')) {
    wp_schedule_event(time(), 'daily', 'disable_payment_daily_event');
}
add_action('disable_payment_daily_event', 'disable_payment_for_inactive_orders');

3. Блокируем кнопку оплаты на фронтенде

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

add_action('woocommerce_before_checkout_form', function() {
    $order_id = absint(get_query_var('order-pay'));
    if (!$order_id) return;

    $order = wc_get_order($order_id);
    if (!$order) return;

    $disable_payment = $order->get_meta('disable_payment');
    if ($disable_payment === 'true') {
        wp_die('Оплата для этого заказа отключена из-за длительного отсутствия активности. Пожалуйста, создайте новый заказ.');
    }
});

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

  • Создайте тестовый заказ в статусе pending и измените дату создания заказа на дату более 24 часов назад (можно через базу данных или код).
  • Запустите вручную функцию disable_payment_for_inactive_orders() через WP-CLI или вызовите AJAX.
  • Перейдите на страницу оплаты такого заказа — вы должны увидеть сообщение об отключении оплаты.
  • Проверьте, что для новых заказов без метаполя disable_payment оплата работает корректно.

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

  • Функция не запускается по расписанию: Проверьте, активирован ли WP-Cron и не отключена ли эта функциональность в wp-config.php. Можно вызвать функцию вручную для теста.
  • Метаполе не сохраняется: Убедитесь, что используете метод save() после обновления метаполя заказа.
  • Ошибка при проверке оплаты на странице checkout: Возможно, переменная order-pay не установлена. Проверьте правильность получения ID заказа.
  • Заказы не попадают под фильтр по дате: Проверьте формат даты и часовой пояс сайта (WordPress использует часовой пояс, установленный в настройках).

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

  • Для больших магазинов с тысячами заказов используйте пагинацию при выборке заказов в wc_get_orders, чтобы не перегружать сервер.
  • Добавьте логирование действий функции, чтобы отслеживать сколько заказов было обновлено.
  • Ограничьте права доступа к AJAX-запросам, если используете их для вызова функции вручную.
  • Убедитесь, что сообщение на странице оплаты не раскрывает лишней информации о заказе.

Альтернативы: код или плагин?

МетодПлюсыМинусы
Код (свой плагин или functions.php)Гибкость, контроль, нет лишних плагиновТребует навыков, поддержка на вас
Плагин для управления статусами заказовПростота установки, готовый функционалМожет быть избыточным, нагрузка, платные версии
Как установить ограничения на регистрацию пользователей в WordPress
21.01.2026
Автоматизация создания резервных копий WordPress с помощью PHP-кода
16.12.2025
Автоматическое удаление старого контента в WordPress по дате с примером кода
20.02.2026
WooCommerce: автоматическое изменение цен при изменении атрибутов товара
13.06.2026
Как удалить или изменить авторские права в метаданных WordPress
08.02.2026