Диагностика проблемы с неуспешными платежами и заблокированной корзиной
В интернет-магазинах на 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) | Хранение и очистка сессий на уровне кеша | Скорость, масштабируемость | Требует дополнительной настройки сервера |