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

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

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

Типичные симптомы:

  • Платежный шлюз продолжает показываться в списке, хотя предыдущая попытка оплаты не была успешной;
  • Товары остаются в корзине слишком долго, блокируя возможность повторной покупки;
  • Отсутствие уведомлений или автоматического удаления устаревших заказов и корзин.

Как автоматически отключать платежи при неуспешных транзакциях в WooCommerce

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

Шаг 1. Отслеживание статуса заказа

Подпишемся на хук woocommerce_order_status_failed, который срабатывает при изменении статуса заказа на "неудачный".

add_action('woocommerce_order_status_failed', 'disable_payment_gateways_for_failed_order', 10, 1);
function disable_payment_gateways_for_failed_order($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) return;

    // Сохраняем ID заказа в опцию или transient для дальнейшего использования
    update_option('wc_disable_payments_for_order_' . $order_id, true, false);
}

Шаг 2. Отключение платежных шлюзов для конкретного пользователя

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

add_filter('woocommerce_available_payment_gateways', 'filter_payment_gateways_for_failed_orders');
function filter_payment_gateways_for_failed_orders($gateways) {
    if (is_admin() || !is_checkout()) {
        return $gateways;
    }

    $user_id = get_current_user_id();
    if (!$user_id) {
        return $gateways;
    }

    $orders = wc_get_orders(array(
        'customer_id' => $user_id,
        'status' => 'failed',
        'limit' => -1
    ));

    if (!empty($orders)) {
        // Отключаем все платежные методы или конкретные
        // Например, отключаем 'cod' и 'bacs'
        unset($gateways['cod']);
        unset($gateways['bacs']);
    }

    return $gateways;
}

Примечание

Вместо полного отключения платежей можно добавить уведомление пользователю о предыдущих ошибках.

Автоматическое удаление товаров из корзины по времени нахождения

WooCommerce не удаляет товары из корзины по времени по умолчанию. Это приводит к тому, что корзина может содержать устаревшие товары. Можно настроить cron-задачу для очистки корзин, которые не обновлялись длительное время.

Шаг 1. Создаем функцию очистки корзин

function wc_clear_old_carts() {
    global $wpdb;
    $expiration_time = 3600; // 1 час в секундах

    $time_limit = time() - $expiration_time;

    // Получаем все сессии пользователей, где время модификации старше 1 часа
    $sessions = $wpdb->get_results($wpdb->prepare(
        "SELECT session_key FROM {$wpdb->prefix}sessions WHERE session_expiry < %d",
        $time_limit
    ));

    if (empty($sessions)) {
        return;
    }

    foreach ($sessions as $session) {
        WC()->session->set_customer_session_cookie(true);
        WC()->session->set_session($session->session_key);
        WC()->cart->empty_cart(true);
    }
}

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

if (!wp_next_scheduled('wc_clear_old_carts_hook')) {
    wp_schedule_event(time(), 'hourly', 'wc_clear_old_carts_hook');
}

add_action('wc_clear_old_carts_hook', 'wc_clear_old_carts');

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

  • Создайте тестовый заказ и имитируйте неудачную оплату. Перейдите на страницу оформления заказа и проверьте, что платежные методы отключены или скрыты.
  • Добавьте товар в корзину и не совершайте действия более часа. Проверьте, что после запуска WP-Cron корзина очищается автоматически.
  • Для удобства можно вручную запустить cron-задачу, используя плагин WP Crontrol или WP-CLI.

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

  • Не отключаются платежные методы: Проверьте, что используемый фильтр подключен и правильно проверяет статус заказов текущего пользователя.
  • Очистка корзины не работает: Убедитесь, что таблица wp_sessions используется (некоторые сайты используют другие механизмы хранения сессий). Проверьте права доступа к базе данных и работу WP-Cron.
  • Ошибки сессии при очистке корзины: Не используйте WC()->session->set_session() напрямую без инициализации сессии. Рассмотрите использование плагинов для управления сессиями.

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

  • Не храните чувствительные данные в опциях или transient без валидации и очистки.
  • WP-Cron может не запускаться на слабых хостингах – для критичных задач используйте системные cron-задачи.
  • При работе с платежами всегда логируйте события ошибок и изменения статуса для последующего анализа.
  • Используйте фильтрацию платежных методов аккуратно, чтобы не заблокировать оплату для пользователей с прошлыми ошибками, если это не требуется.

Сравнение вариантов реализации очистки корзины

МетодОписаниеПреимуществаНедостатки
Кастомный WP-CronОчистка сессий и корзины по времениГибкость, контроль, бесплатноеЗависит от WP-Cron, сложность реализации
Плагин для очистки корзиныГотовые решения, настройки через UIПростота, поддержкаМожет нагружать сайт, платные функции
Использование стороннего кеша (Redis, Memcached)Хранение и очистка сессий на уровне кешаСкорость, масштабируемостьТребует дополнительной настройки сервера
Как закрыть дубли страниц с помощью canonical и noindex в WordPress
14.08.2026