Диагностика проблемы: почему корзина не очищается автоматически
В WooCommerce корзина пользователя по умолчанию не очищается автоматически после создания неоплаченного заказа. Это может привести к тому, что товары остаются в корзине, вызывая путаницу у клиентов и увеличивая риск дублирующих заказов. Особенно актуально для магазинов с длительным процессом оплаты или с отложенными платежами.
Проверить проблему просто: сделайте тестовый заказ и не завершайте оплату. Перейдите в корзину — если товары остались, значит автоматической очистки нет.
Пошаговое решение: автоматическая очистка корзины после неоплаченного заказа
1. Добавление хука для очистки корзины через cron
Реализуем функцию, которая будет очищать корзины пользователей с неоплаченными заказами старше заданного времени (например, 1 час).
function wc_clear_cart_for_unpaid_orders() {
// Получаем заказы со статусом 'pending' или 'failed', созданные более часа назад
$args = [
'status' => ['pending', 'failed'],
'date_created' => '<' . ( time() - HOUR_IN_SECONDS ),
'limit' => -1,
'return' => 'ids',
];
$orders = wc_get_orders( $args );
if ( empty( $orders ) ) {
return;
}
foreach ( $orders as $order_id ) {
$order = wc_get_order( $order_id );
$user_id = $order->get_user_id();
if ( ! $user_id ) {
// Если гость, корзина хранится в сессии, очистить невозможно программно
continue;
}
// Получаем сессию пользователя
$session_handler = WC()->session;
if ( ! $session_handler ) {
continue;
}
// Путь очистки корзины пользователя через сессию
$session_key = 'cart';
// Очистка корзины пользователя
$session_handler->set_customer_session_cookie( true );
$session_handler->set( $session_key, null );
}
}
// Добавляем задачу в WP-Cron
if ( ! wp_next_scheduled( 'wc_clear_cart_unpaid_orders_hook' ) ) {
wp_schedule_event( time(), 'hourly', 'wc_clear_cart_unpaid_orders_hook' );
}
add_action( 'wc_clear_cart_unpaid_orders_hook', 'wc_clear_cart_for_unpaid_orders' );2. Очистка корзины текущего пользователя при загрузке страницы
Для гостей и текущих пользователей можно добавить проверку при заходе на сайт:
add_action( 'template_redirect', 'wc_clear_cart_if_pending_order_exists' );
function wc_clear_cart_if_pending_order_exists() {
if ( ! is_user_logged_in() ) {
return; // Для гостей не реализуем
}
$user_id = get_current_user_id();
$args = [
'customer_id' => $user_id,
'status' => ['pending', 'failed'],
'limit' => 1,
'orderby' => 'date',
'order' => 'DESC',
];
$orders = wc_get_orders( $args );
if ( ! empty( $orders ) ) {
WC()->cart->empty_cart();
}
}Как проверить, что очистка корзины сработала
- Создайте тестовый заказ и не оплачивайте его.
- Подождите час или измените время проверки в функции на меньшее (например, 60 секунд) для теста.
- Зайдите в корзину под тем же пользователем — она должна быть пустой.
- Проверьте логи cron (можно добавить логирование в функцию), чтобы убедиться, что задача срабатывает.
Частые ошибки и как их исправить
- Ошибка: Корзина не очищается для гостей — гости хранят корзину в сессии браузера, серверная очистка невозможна. Решение — добавить уведомление с предложением очистить корзину вручную или использовать cookie/JS.
- Ошибка: WP-Cron не срабатывает — проверьте, что на сайте проходят запросы, или настройте системный cron для wp-cron.php.
- Ошибка: Очистка происходит слишком часто или редко — корректно задайте интервал в wp_schedule_event (hourly, twicedaily и т.п.) или создайте свой.
Практические советы по безопасности и производительности
- Не очищайте корзины без проверки статуса заказа, чтобы не потерять данные активных пользователей.
- Добавьте логирование в функцию очистки, чтобы отслеживать успешные и неудачные попытки.
- Используйте серверный cron вместо WP-Cron для стабильности на больших сайтах.
- Для гостевых пользователей можно реализовать очистку корзины через JavaScript при загрузке страницы, основываясь на времени последней активности.
Сравнение вариантов реализации очистки корзины
| Метод | Преимущества | Недостатки |
|---|---|---|
| Очистка через WP-Cron (серверный) | Автоматизация, не зависит от активности пользователя | Не работает для гостей, зависит от WP-Cron |
| Очистка при загрузке страницы (текущий пользователь) | Работает для авторизованных пользователей, простая реализация | Не очищает корзины гостей, зависит от активности пользователя |
| Очистка через JavaScript для гостей | Можно очистить гостевые корзины | Зависит от браузера, менее надежно, требует доп. кода |