Диагностика проблемы: корзина не очищается после оплаты
В WooCommerce нередко возникает ситуация, когда после успешной оплаты товара в корзине остаются старые позиции. Это приводит к путанице у пользователей и может вызвать повторные заказы или конфликты с учётной записью. Причины могут быть разные:
- Использование сторонних плагинов для оплаты, которые не интегрируются корректно с WooCommerce;
- Кэширование страниц корзины и сессий пользователя;
- Ошибки в теме или кастомных скриптах, вмешивающихся в процесс оформления заказа;
- Неправильная настройка хуков, связанных с очищением корзины.
Пошаговое решение: добавляем автоматическую очистку корзины по хуку успешной оплаты
WooCommerce по умолчанию очищает корзину при переходе на страницу благодарности (thank you page). Но если этот процесс не срабатывает, можно принудительно очистить корзину по хуку woocommerce_thankyou, который вызывается после успешного оформления заказа.
Добавьте следующий код в файл functions.php вашей дочерней темы или в кастомный плагин:
add_action( 'woocommerce_thankyou', 'auto_clear_cart_after_payment' );
function auto_clear_cart_after_payment( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
if ( $order && $order->has_status( 'completed' ) ) {
WC()->cart->empty_cart();
}
}Этот код проверяет, что заказ существует и его статус "выполнен", после чего очищает корзину текущего пользователя.
Поддержка разных статусов заказа
Иногда заказ может иметь статус processing или on-hold. Чтобы учитывать эти случаи, расширим условие:
add_action( 'woocommerce_thankyou', 'auto_clear_cart_after_payment' );
function auto_clear_cart_after_payment( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
if ( $order && in_array( $order->get_status(), array( 'completed', 'processing', 'on-hold' ), true ) ) {
WC()->cart->empty_cart();
}
}Проверка результата после внедрения
- Откройте тестовый магазин в режиме гостя или под тестовым пользователем.
- Добавьте товары в корзину и оформите заказ с любым из поддерживаемых способов оплаты.
- После перенаправления на страницу "Спасибо за заказ" откройте корзину — она должна быть пустой.
- Для проверки можно вывести содержимое корзины через консоль браузера или добавить временный вывод в коде:
error_log( 'Cart contents after payment: ' . print_r( WC()->cart->get_cart(), true ) );В логах сервера не должно быть товаров.
Частые ошибки и как их исправить
- Код не срабатывает, корзина не очищается: Проверьте, вызывается ли хук
woocommerce_thankyou. Если вы используете нестандартные платежные шлюзы, этот хук может не запускаться. В этом случае потребуется интеграция с хуками самого платежного плагина. - Корзина очищается слишком рано: Убедитесь, что проверяете статус заказа, чтобы не удалять корзину при неподтверждённых платежах.
- Кэширование мешает обновлению корзины: Отключите кэширование страниц корзины и оформления заказа на уровне плагинов кеша (например, WP Rocket, LiteSpeed Cache) или на стороне сервера.
- Ошибка "WC() is null" или "Call to a member function empty_cart() on null": Этот код должен выполняться после инициализации WooCommerce. Добавляйте его в хуки, которые запускаются после загрузки WooCommerce, например,
woocommerce_thankyou.
Практические советы по безопасности и производительности
- Не используйте этот код для очистки корзины на страницах, отличных от страницы подтверждения заказа — это ухудшит UX.
- Если у вас много плагинов оплаты, протестируйте каждый платежный метод отдельно.
- Используйте дебаг-логи
WP_DEBUG_LOGдля отслеживания работы кода. - Избегайте прямого вмешательства в сессии WooCommerce без проверки контекста.
Сравнение способов очистки корзины после оплаты
| Метод | Преимущества | Недостатки | Пример |
|---|---|---|---|
Хук woocommerce_thankyou с проверкой статуса заказа | Нативное решение, не требует дополнительных плагинов | Не работает с нестандартными шлюзами, зависит от статуса заказа | Код из статьи |
| Интеграция с хуками платежного плагина | Работает с любыми шлюзами, более надёжно | Требует изучения API плагина, больше кода | Зависит от конкретного плагина |
| Очистка корзины через JS на странице "Спасибо" | Простая реализация | Менее надёжно, зависит от клиента, можно обойти | window.onload = () => WC()->cart->empty_cart(); (нужен кастомный скрипт) |