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

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

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

Проверить наличие проблемы можно, просмотрев список заказов в админке WooCommerce и отфильтровав их по статусу on-hold или pending. Если таких заказов много и они долго не меняют статус, логично ограничить доступ к способам оплаты для заказчиков с такими заказами.

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

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

Для начала нам нужно проверить, есть ли у текущего пользователя заказы в статусах pending или on-hold. Если есть — отключаем способы оплаты.

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

Добавим в файл functions.php вашей дочерней темы или в собственный плагин следующий код:

add_filter('woocommerce_available_payment_gateways', 'disable_payment_methods_for_unconfirmed_orders');
function disable_payment_methods_for_unconfirmed_orders($available_gateways) {
    if (!is_user_logged_in()) {
        return $available_gateways; // не меняем для гостей
    }

    $user_id = get_current_user_id();

    // Получаем заказы пользователя со статусом pending или on-hold
    $args = array(
        'customer_id' => $user_id,
        'status' => array('pending', 'on-hold'),
        'limit' => 1
    );

    $orders = wc_get_orders($args);

    if (!empty($orders)) {
        // Отключаем все способы оплаты
        return array();
    }

    return $available_gateways;
}

3. Дополнительная настройка: вывод сообщения пользователю

Чтобы пользователь видел, почему способы оплаты недоступны, выведите уведомление. Добавьте в functions.php следующий код:

add_action('woocommerce_before_checkout_form', 'show_payment_disabled_message');
function show_payment_disabled_message() {
    if (!is_user_logged_in()) {
        return;
    }

    $user_id = get_current_user_id();
    $args = array(
        'customer_id' => $user_id,
        'status' => array('pending', 'on-hold'),
        'limit' => 1
    );

    $orders = wc_get_orders($args);

    if (!empty($orders)) {
        wc_print_notice('У вас есть неподтверждённые заказы. Новые оплаты временно недоступны, пока предыдущие заказы не будут завершены.', 'error');
    }
}

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

  • Залогиньтесь под пользователем, у которого есть неподтверждённые заказы (статус pending или on-hold).
  • Перейдите на страницу оформления заказа (checkout).
  • Убедитесь, что способы оплаты не отображаются, а выводится сообщение о блокировке оплаты.
  • Залогиньтесь под пользователем без неподтверждённых заказов и проверьте, что способы оплаты доступны.
  • Также проверьте гостевой режим — способы оплаты должны быть доступны, если не внедрена другая логика.

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

  • Способы оплаты не отключаются: проверьте, что функция wc_get_orders возвращает заказы, используйте отладку error_log(print_r($orders, true)); для диагностики.
  • Сообщение не выводится: убедитесь, что хук woocommerce_before_checkout_form подключен и код находится в активном файле.
  • У гостя оплата отключена: проверьте условие is_user_logged_in() в коде, чтобы исключить гостей.
  • Блокировка слишком жёсткая: можно добавить дополнительную проверку по дате заказа, например, отключать способы оплаты только если заказ старше 1 часа.

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

  • Используйте limit => 1 в запросах, чтобы снизить нагрузку на базу данных.
  • Не храните большие объёмы данных в сессии для проверки статуса заказов, используйте запросы по необходимости.
  • Если сайт с большим количеством заказов, кешируйте результаты проверки статуса на 5-10 минут, чтобы избежать частых запросов к базе.
  • Для сайтов с гостевой оплатой можно дополнительно расширить логику, например, по IP или сессии, чтобы ограничить повторные попытки оплаты.

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

МетодПлюсыМинусы
Плагин стороннийБыстрое решение, поддержка обновленийМожет влиять на производительность, лишний функционал
Код в functions.phpПолный контроль, минимальная нагрузкаТребует навыков, нужно поддерживать самостоятельно
Автоматическая очистка неподтверждённых заказовУменьшение нагрузки, автоматизацияРиск удаления нужных заказов, требует тестирования