Диагностика проблемы: почему товары остаются в корзине после отмены оплаты
В WooCommerce по умолчанию товары остаются в корзине пользователя до тех пор, пока он не удалит их вручную или не завершит успешную оплату. Однако при отмене оплаты, например, если покупатель отказался оплачивать заказ или произошла ошибка во время транзакции, корзина остается заполненной, что может вызвать путаницу и снизить удобство покупок.
Пользователи жалуются на то, что после отмены оплаты товары не удаляются автоматически, и приходится вручную очищать корзину, либо при повторном заходе товары все равно отображаются в корзине.
Пошаговое решение: автоматическое очищение корзины после отмены оплаты
1. Используем хук на смену статуса заказа
Для автоматического удаления товаров из корзины при отмене оплаты нужно отслеживать смену статуса заказа на cancelled или failed. После этого можно программно очищать корзину пользователя.
2. Код для functions.php или собственного плагина
add_action('woocommerce_order_status_cancelled', 'clear_cart_after_order_cancelled', 10, 1);
add_action('woocommerce_order_status_failed', 'clear_cart_after_order_cancelled', 10, 1);
function clear_cart_after_order_cancelled($order_id) {
if (!is_admin()) {
WC()->cart->empty_cart();
}
}Этот код добавляет обработчик на смену статуса заказа и вызывает метод empty_cart(), который очищает корзину текущего пользователя.
3. Обработка ситуации с гостевыми пользователями
Если пользователь гость (неавторизованный), то очистить корзину сложнее, так как корзина хранится в сессии. В этом случае очистка корзины при смене статуса заказа не всегда срабатывает, так как событие происходит на сервере, а сессия может не совпадать с текущей сессией пользователя.
Чтобы обработать такие случаи, рекомендуется использовать JavaScript и AJAX, например, при загрузке страницы после отмены оплаты проверять статус заказа через REST API и очищать корзину.
Проверка результата после внедрения
- Создайте тестовый заказ и оплатите его, затем отмените оплату через админку (смените статус на
cancelledилиfailed). - Перейдите на сайт под учётной записью пользователя, который оформлял заказ.
- Откройте корзину — она должна быть пустой.
- Для гостевых пользователей протестируйте очистку корзины через повторный заход и обновление страницы после отмены оплаты.
Частые ошибки и как исправить
- Очистка корзины не срабатывает для гостевых пользователей. Это связано с тем, что корзина хранится в сессии, а событие происходит на сервере. Решение — использовать AJAX и проверять статус заказа на стороне клиента.
- Метод
WC()->cart->empty_cart()вызывается в админке. Вызов всегда должен происходить только на фронтенде, иначе корзина очистится для администратора, что не имеет смысла. Поэтому в коде есть проверка!is_admin(). - Код добавлен в неподходящее место. Добавляйте код либо в functions.php дочерней темы, либо в отдельный плагин, чтобы избежать потери изменений при обновлении.
Практические советы по улучшению UX и безопасности
- Уведомление пользователя. После очистки корзины полезно вывести сообщение или уведомление, что товары были удалены из-за отмены оплаты.
- Кэширование. Если на сайте используется кэширование страниц или объектов, убедитесь, что корзина не кэшируется, иначе изменения не будут видны сразу.
- Безопасность. Проверяйте, что функции очищения корзины вызываются только для соответствующего пользователя, чтобы избежать неожиданного поведения.
Пример AJAX-решения для гостевых пользователей
Для гостевых пользователей можно добавить JavaScript, который при загрузке страницы проверяет статус заказа через REST API и очищает корзину по запросу:
jQuery(document).ready(function($) {
var orderId = localStorage.getItem('last_order_id'); // Например, сохраняем id последнего заказа
if (orderId) {
$.ajax({
url: '/wp-json/wc/v3/orders/' + orderId,
method: 'GET',
beforeSend: function(xhr) {
xhr.setRequestHeader('X-WP-Nonce', wc_rest_nonce);
},
success: function(order) {
if (order.status === 'cancelled' || order.status === 'failed') {
$.post(wc_cart_params.wc_ajax_url.toString().replace('%%endpoint%%', 'clear_cart'), function() {
localStorage.removeItem('last_order_id');
location.reload();
});
}
}
});
}
});И нужно зарегистрировать AJAX-обработчик PHP для clear_cart, который вызовет WC()->cart->empty_cart().
Таблица сравнения методов удаления товаров из корзины после отмены оплаты
| Метод | Преимущества | Недостатки |
|---|---|---|
| Хук на смену статуса заказа | Простая реализация, работает для авторизованных пользователей | Не работает корректно для гостей |
| AJAX с проверкой через REST API | Обрабатывает гостей, работает на клиенте | Сложнее в реализации, требует JavaScript и REST API |
| Плагины для управления корзиной | Готовые решения, дополнительные функции | Могут влиять на производительность, не всегда бесплатны |