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

Диагностика проблемы с неподтверждёнными заказами в WooCommerce

Проблема: клиенты пытаются оплатить заказ, но способы оплаты остаются активными, даже если у них уже есть неподтверждённые заказы. Это приводит к дублированию заказов и путанице в системе. Особенно актуально для магазинов с ограниченным количеством товара или специфическими условиями оплаты.

Для диагностики используйте следующие шаги:

  • Проверьте в админке WooCommerce список заказов и найдите неподтверждённые (статус "Ожидает оплаты" или "На проверке").
  • Имитируйте попытку оформления заказа с тем же пользователем, чтобы проверить, активны ли способы оплаты.
  • Откройте консоль браузера и посмотрите, нет ли ошибок JavaScript, которые могут мешать корректной работе способов оплаты.
  • Проверьте логи WooCommerce (WooCommerce > Статус > Логи) на наличие ошибок, связанных с платежами.

Пошаговое решение: как автоматически отключать способы оплаты при неподтверждённых заказах

Основная идея — при попытке загрузить страницу оформления заказа проверять, есть ли у текущего пользователя неподтверждённые заказы, и если есть — отключать определённые методы оплаты.

1. Добавление проверки неподтверждённых заказов пользователя

function has_unpaid_orders( $user_id ) {
    if ( ! $user_id ) {
        return false;
    }
    $args = array(
        'customer_id' => $user_id,
        'status' => array('pending', 'on-hold'), // статусы неподтверждённых заказов
        'limit' => -1,
        'return' => 'ids',
    );
    $orders = wc_get_orders( $args );
    return ! empty( $orders );
}

2. Фильтрация доступных способов оплаты на странице оформления заказа

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 ( has_unpaid_orders( $user_id ) ) {
        // Отключаем все способы оплаты кроме, например, "наличными при получении"
        foreach ( $available_gateways as $gateway_id => $gateway ) {
            if ( 'cod' !== $gateway_id ) { // 'cod' — ID способа оплаты "Наложенный платеж"
                unset( $available_gateways[ $gateway_id ] );
            }
        }
    }
    return $available_gateways;
}

3. Кеширование результатов и оптимизация

Если у вас много пользователей и заказов, проверка может замедлить загрузку. Используйте кеширование результата при помощи transient:

function has_unpaid_orders_cached( $user_id ) {
    if ( ! $user_id ) {
        return false;
    }
    $cache_key = 'unpaid_orders_' . $user_id;
    $has_unpaid = get_transient( $cache_key );

    if ( $has_unpaid === false ) {
        $has_unpaid = has_unpaid_orders( $user_id );
        set_transient( $cache_key, $has_unpaid, 10 * MINUTE_IN_SECONDS );
    }
    return $has_unpaid;
}

И замените вызов в фильтре на has_unpaid_orders_cached.

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

  • Залогиньтесь под пользователем с неподтверждённым заказом и перейдите на страницу оформления заказа. Убедитесь, что доступны только разрешённые способы оплаты.
  • Залогиньтесь под пользователем без неподтверждённых заказов — все способы оплаты доступны.
  • Проверьте на разных устройствах и браузерах, чтобы исключить проблемы с кешем.
  • Просмотрите логи ошибок PHP и WooCommerce, чтобы убедиться в отсутствии новых ошибок.

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

  • Проверка не срабатывает для гостей: функция работает только для авторизованных пользователей, для гостей нужно реализовать проверку по сессии или cookie.
  • Неправильные ID способов оплаты: убедитесь, что используете правильные ID, которые можно узнать в WooCommerce > Настройки > Способы оплаты.
  • Кеширование мешает обновлению статуса: если заказ сменил статус, а кеш ещё не истёк, может сохраняться устаревшая информация — уменьшите время кеша или реализуйте сброс при изменении заказа.
  • Фильтр срабатывает в админке: добавляйте проверку is_admin(), чтобы не блокировать способы оплаты в админке.

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

  • Для безопасности не раскрывайте в интерфейсе, почему способы оплаты отключены — лучше показывать нейтральное сообщение.
  • Используйте транзиенты для кеширования, чтобы снизить нагрузку на базу данных.
  • Регулярно очищайте кеш при массовом изменении заказов с помощью хука woocommerce_order_status_changed.
  • Тестируйте на staging-сервере, чтобы избежать сбоев в работе магазина.

Сравнение вариантов реализации автоматического отключения способов оплаты

МетодПлюсыМинусыРекомендации
Использовать фильтр woocommerce_available_payment_gateways с проверкой заказовГибко, без плагинов, встроено в логику WooCommerceНагрузка при большом числе заказов, требует кешированияОптимизировать запросы и кешировать
Плагин с расширенными настройкамиУдобство, готовые UI, поддержкаДополнительный вес, может конфликтоватьИспользовать при необходимости сложных правил
Отключение способов оплаты через JavaScriptБыстрое визуальное скрытиеНе безопасно, пользователь может обойтиНе рекомендовано как основное решение