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

Проблема: платежные системы остаются активными при неоплате заказа

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

Диагностика проблемы

Для начала нужно понять, что WooCommerce по умолчанию не блокирует способы оплаты для неоплаченных заказов. Проверьте следующее:

  • В разделе WooCommerce > Настройки > Платежи активированы все нужные способы оплаты.
  • При создании заказа, который не был оплачен, способы оплаты продолжают отображаться.
  • Отсутствует логика, ограничивающая доступ к платежным методам в зависимости от статуса заказа.

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

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

Шаг 1. Добавляем проверку статуса заказа и времени создания

Нам нужно фильтровать доступные способы оплаты на странице оформления заказа, отключая их, если есть неоплаченный заказ старше определённого времени (например, 1 час).

add_filter('woocommerce_available_payment_gateways', 'disable_payment_gateways_for_unpaid_orders');
function disable_payment_gateways_for_unpaid_orders($available_gateways) {
    if (is_admin()) return $available_gateways; // Не менять в админке

    $user_id = get_current_user_id();
    if (!$user_id) return $available_gateways; // Только для залогиненных

    $args = array(
        'customer_id' => $user_id,
        'status' => array('pending', 'on-hold'), // Неоплаченные статусы
        'limit' => 1,
        'orderby' => 'date',
        'order' => 'ASC',
    );

    $orders = wc_get_orders($args);
    if (empty($orders)) return $available_gateways; // Нет неоплаченных заказов

    $order = $orders[0];
    $order_date = $order->get_date_created();
    if (!$order_date) return $available_gateways;

    $order_timestamp = $order_date->getTimestamp();
    $current_timestamp = current_time('timestamp');
    $limit_seconds = 3600; // 1 час

    if (($current_timestamp - $order_timestamp) > $limit_seconds) {
        // Отключаем все способы оплаты
        return array();
    }

    return $available_gateways;
}

Шаг 2. Вывод сообщения для пользователя

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

add_action('woocommerce_checkout_before_customer_details', 'show_payment_disabled_notice');
function show_payment_disabled_notice() {
    $user_id = get_current_user_id();
    if (!$user_id) return;

    $args = array(
        'customer_id' => $user_id,
        'status' => array('pending', 'on-hold'),
        'limit' => 1,
        'orderby' => 'date',
        'order' => 'ASC',
    );
    $orders = wc_get_orders($args);
    if (empty($orders)) return;

    $order = $orders[0];
    $order_date = $order->get_date_created();
    if (!$order_date) return;

    $order_timestamp = $order_date->getTimestamp();
    $current_timestamp = current_time('timestamp');
    $limit_seconds = 3600;

    if (($current_timestamp - $order_timestamp) > $limit_seconds) {
        wc_print_notice('У вас есть неоплаченный заказ старше 1 часа. Оплата временно недоступна.', 'error');
    }
}

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

  • Создайте заказ с текущим пользователем и не оплачивайте его.
  • Дождитесь истечения времени (например, 1 час) или временно уменьшите $limit_seconds для теста.
  • Перейдите на страницу оформления заказа. Способы оплаты должны быть отключены, и появится уведомление.
  • Проверьте, что при отсутствии неоплаченных заказов способы оплаты отображаются корректно.

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

  • Платежи не отключаются: Проверьте, что пользователя идентифицируете правильно и что статус заказа действительно pending или on-hold.
  • Способы оплаты отключаются для всех пользователей: Убедитесь, что проверка get_current_user_id() работает корректно и что код не применяется в админке.
  • Сообщение не выводится: Проверьте, что хук woocommerce_checkout_before_customer_details не конфликтует с другими плагинами и что функция вызывается.
  • Проблемы с часовым поясом: Для корректного подсчёта времени используйте current_time('timestamp'), а не time().

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

  • Оптимизируйте запросы wc_get_orders, ограничивая выборку только необходимыми полями через параметр 'return' => 'ids' при необходимости.
  • Используйте транзиенты для кэширования результатов проверки, если на сайте много пользователей, чтобы снизить нагрузку на базу.
  • Не отключайте способы оплаты полностью, если это критично для бизнеса — лучше показать ограниченное сообщение или предложить связаться с поддержкой.

Сравнение вариантов реализации

МетодПлюсыМинусы
Код в functions.phpПолный контроль, бесплатно, быстроТребует навыков, требует тестирования
Плагины управления оплатой (например, WooCommerce Conditional Shipping and Payments)Готовое решение, поддержка, GUIПлатно, может быть избыточным
Кастомные плагиныГибкость, масштабируемостьТребует разработки и поддержки
Как отключить комментарии для отдельных типов записей в WordPress
28.03.2026
WooCommerce: как ограничить доступ к товарам по авторизации пользователя
07.06.2026
Как использовать WPRemark для оценки комментариев в WordPress
13.12.2025
Как отключить Gutenberg в WordPress 2024: практические способы и примеры кода
09.12.2025
Как использовать хуки для изменения функциональности WordPress
04.01.2026