Диагностика проблемы: зачем удалять товар из корзины после отмены оплаты
В WooCommerce по умолчанию товары остаются в корзине пользователя даже если он начал, но не завершил оплату или отменил заказ. Это может привести к путанице и затруднить оформление повторных заказов, особенно если товар ограничен в наличии. Автоматическое удаление таких товаров из корзины помогает улучшить UX и избежать конфликтов с остатками.
Пошаговое решение: автоматическое очищение корзины после отмены оплаты
1. Определяем событие отмены заказа
WooCommerce генерирует несколько статусов заказа. Для обработки отмены оплаты нам нужно отследить смену статуса заказа на cancelled или failed. Для этого используем хук woocommerce_order_status_changed.
2. Получаем пользователя и очищаем корзину
После того, как заказ получил статус отменён или неудачный, нужно очистить корзину пользователя, который оформлял заказ.
add_action('woocommerce_order_status_changed', 'wp8_clear_cart_after_cancel', 10, 4);
function wp8_clear_cart_after_cancel($order_id, $old_status, $new_status, $order) {
if (in_array($new_status, ['cancelled', 'failed'])) {
$user_id = $order->get_user_id();
if ($user_id) {
$session_handler = WC()->session;
if ($session_handler) {
$key = 'cart';
// Получаем объект сессии пользователя по ID
$sessions = WC()->session->get_session_cookie();
// К сожалению, WC не предоставляет прямой метод очистки корзины другого пользователя,
// поэтому для зарегистрированных пользователей можно использовать следующий подход:
// Добавляем мета-данные в заказ или уведомляем пользователя очистить корзину вручную.
// Для гости можно использовать JS для очистки.
}
}
}
}Однако WooCommerce не хранит сессию корзины пользователей на сервере в доступном виде, и очистить корзину другого пользователя программно невозможно без дополнительного плагина или кастомного решения.
3. Рабочий вариант для текущего пользователя при повторном входе
Чаще всего нужно очистить корзину, если пользователь пытается оформить оплату повторно, но у него остались старые товары. Для этого можно добавить очистку корзины при загрузке страницы оформления заказа, если у пользователя есть отменённый или неудачный заказ.
add_action('woocommerce_before_checkout_form', 'wp8_clear_cart_if_cancelled_order');
function wp8_clear_cart_if_cancelled_order() {
if (!is_user_logged_in()) return;
$user_id = get_current_user_id();
$orders = wc_get_orders(array(
'customer_id' => $user_id,
'status' => array('cancelled', 'failed'),
'limit' => 1,
'orderby' => 'date',
'order' => 'DESC',
));
if (!empty($orders) && WC()->cart->get_cart_contents_count() > 0) {
WC()->cart->empty_cart();
wc_add_notice('Ваша корзина была очищена из-за отменённого заказа. Пожалуйста, добавьте товары заново.', 'notice');
}
}Проверка результата после внедрения
- Авторизуйтесь под тестовым пользователем и оформите заказ с любым статусом
cancelledилиfailed. - Перейдите на страницу оформления заказа (checkout). Корзина должна очиститься автоматически, а вы увидите уведомление.
- Проверьте, что корзина пуста, и можно добавлять товары заново без конфликтов.
Частые ошибки и как исправить
- Корзина не очищается: Убедитесь, что пользователь авторизован, так как WC()->cart работает с текущей сессией.
- Код очищает корзину при каждом заходе на checkout: Добавьте дополнительную проверку на дату заказа или используйте пользовательское мета для отметки, что очистка уже была выполнена.
- Невозможно очистить корзину другого пользователя: Стандартный WooCommerce не хранит сессии пользователей централизованно, для этого нужны кастомные решения или сторонние плагины.
Практические советы по безопасности и производительности
- Не используйте тяжелые запросы в хуках, которые срабатывают при каждой загрузке страницы. Кэшируйте результаты, если проверяете заказы.
- Очищайте корзину только у текущего пользователя, чтобы не повредить данные других.
- Добавьте уведомления для пользователей, чтобы они понимали причину очистки корзины.
- При необходимости используйте плагин для управления сессиями WooCommerce или кастомное хранение корзин в базе.
Сравнение вариантов реализации
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Очистка корзины при смене статуса заказа через хук | Прямое действие на событие | Невозможно очистить корзину другого пользователя напрямую | Использовать для текущей сессии, уведомлять пользователя |
| Очистка корзины при входе на страницу оформления заказа | Работает для авторизованных пользователей | Может срабатывать лишний раз без дополнительных проверок | Добавлять проверки даты и флагов очистки |
| Использование сторонних плагинов для управления сессиями | Расширенные возможности, очистка любых корзин | Дополнительная нагрузка и зависимость от плагина | Подходит для больших магазинов с большим количеством пользователей |