Проблема: товары остаются в корзине после отмены заказа
В стандартной логике WooCommerce при отмене заказа товары остаются в корзине пользователя, что может привести к путанице и снижению удобства работы с магазином. Особенно это актуально, если пользователь хочет заново оформить заказ или сменить состав корзины. Автоматическое удаление товаров из корзины после отмены заказа решает эту проблему.
Диагностика проблемы
Для начала убедитесь, что у вас действительно возникает ситуация, когда отменённый заказ не очищает корзину пользователя:
- Оформите тестовый заказ и отмените его в админке WooCommerce;
- Перейдите на сайт под тем же пользователем и проверьте содержимое корзины;
- Если товары остались — проблема подтверждена.
При гостевых заказах (неавторизованных пользователей) корзина хранится в сессии. При авторизованных — в базе данных. В обоих случаях нужно программно очистить корзину после отмены.
Пошаговое решение: очистка корзины после отмены заказа
1. Используем хук для отслеживания смены статуса заказа
WooCommerce предоставляет хук woocommerce_order_status_changed, который срабатывает при смене статуса заказа. Мы будем слушать переход в статус cancelled и очищать корзину пользователя, связанного с этим заказом.
2. Код для functions.php или собственного плагина
add_action('woocommerce_order_status_changed', 'wpcompany_clear_cart_on_cancel', 10, 4);
function wpcompany_clear_cart_on_cancel($order_id, $old_status, $new_status, $order) {
if ($new_status === 'cancelled') {
$user_id = $order->get_user_id();
if ($user_id) {
// Загружаем объект пользователя
$user = get_user_by('ID', $user_id);
if ($user) {
// Используем WC_Session для очистки корзины авторизованного пользователя
WC()->session->set('cart', null);
WC()->cart->empty_cart();
// Альтернативно, очищаем корзину пользователя через пользовательскую сессию
// Но WC не сохраняет корзину в базе, поэтому чистим сессию текущего пользователя
}
}
}
}Однако данный код сработает только для текущей сессии пользователя, если он в момент отмены заказа онлайн. Для надёжного удаления товаров из корзины пользователя, который не онлайн, нужно удалить его сохранённую корзину из базы данных.
3. Очистка корзины авторизованного пользователя из метаданных
WooCommerce хранит корзину в пользовательском метаданных _woocommerce_persistent_cart и _woocommerce_persistent_cart_hash. Их нужно удалить для очистки корзины у пользователя.
add_action('woocommerce_order_status_changed', 'wpcompany_clear_persistent_cart_on_cancel', 10, 4);
function wpcompany_clear_persistent_cart_on_cancel($order_id, $old_status, $new_status, $order) {
if ($new_status === 'cancelled') {
$user_id = $order->get_user_id();
if ($user_id) {
delete_user_meta($user_id, '_woocommerce_persistent_cart');
delete_user_meta($user_id, '_woocommerce_persistent_cart_hash');
}
}
}Проверка результата после внедрения
- Создайте тестовый заказ под авторизованным пользователем;
- Отмените заказ в админке WooCommerce;
- Авторизуйтесь на сайте под этим же пользователем и перейдите в корзину;
- Корзина должна быть пустой.
Для гостевых пользователей (неавторизованных) такая очистка невозможна без пользовательских решений на стороне сессий, так как данные хранятся в cookie. Чтобы решить и эту проблему, можно добавить JS скрипт, который очистит корзину при загрузке страницы, если заказ отменен — но это выходит за рамки базового решения.
Частые ошибки и как их исправить
- Корзина не очищается у пользователя: проверьте, что у пользователя есть ID (т.е. он авторизован). Для гостей очистка через PHP невозможна.
- Код срабатывает только для текущей сессии: в этом случае нужно удалять пользовательские метаданные, как показано выше.
- Ошибка при вызове WC()->cart: убедитесь, что хук вызывается в правильный момент, и WooCommerce загружен. Если вызываете очистку вне фронтенда, WC()->cart может быть не инициализирован.
- Отмена заказа не меняет статус на cancelled: проверьте, что вы используете именно статус
cancelled. Статусы могут отличаться в зависимости от настроек.
Практические советы по производительности и безопасности
- Не добавляйте очистку корзины при каждом изменении заказа — только при смене на статус
cancelled, чтобы избежать излишних операций. - Удаление метаданных пользователя — лёгкая операция, но не стоит делать её в циклах или массово без необходимости.
- Для безопасности убедитесь, что код добавлен в собственный плагин или child theme, чтобы не потерять изменения при обновлении.
Сравнение вариантов очистки корзины после отмены заказа
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
| Очистка WC()->cart в хуке | Очищает корзину текущей сессии | Просто реализовать, работает для онлайн-пользователей | Не работает для офлайн-пользователей, корзина остаётся в базе |
| Удаление user_meta _woocommerce_persistent_cart | Удаляет сохранённую корзину пользователя из базы | Работает для авторизованных пользователей в любом состоянии | Не работает для гостей, нужно обрабатывать отдельно |
| JS очистка корзины у гостей | Очистка через JavaScript на фронтенде для гостей | Можно реализовать для гостей | Сложнее реализовать, зависит от пользовательских сценариев |