Диагностика задачи: почему нужно автоматически удалять товары из корзины по атрибутам после оплаты
В WooCommerce часто возникает необходимость очищать корзину от определённых товаров после успешного оформления заказа. Это актуально, например, для временных товаров, цифровых продуктов с ограниченным сроком использования, или когда по бизнес-логике товар должен исчезать из корзины после покупки. Стандартный WooCommerce не предоставляет встроенных средств для удаления товаров из корзины по атрибутам после оплаты, поэтому требуется кастомное решение.
Как определить нужные атрибуты для удаления товаров
Первым шагом нужно понять, по каким именно атрибутам товаров нужно фильтровать корзину. Атрибуты в WooCommerce — это таксономии, например, pa_color, pa_size и т.д. Для правильной фильтрации важно знать slug атрибута и значения, которые нужно исключить.
Чтобы получить список атрибутов и их значений, в админке WooCommerce перейдите Товары > Атрибуты. Для проверки атрибутов в коде можно использовать пример:
$product = wc_get_product( $product_id );
$attributes = $product->get_attributes();
var_dump( $attributes );Пошаговое решение: автоматическое удаление товаров из корзины по атрибутам после успешной оплаты
Реализуем хук на событие woocommerce_order_status_completed, который срабатывает после успешной оплаты и смены статуса заказа на "завершён".
add_action('woocommerce_order_status_completed', 'remove_products_from_cart_by_attributes_after_payment');
function remove_products_from_cart_by_attributes_after_payment( $order_id ) {
if ( ! is_admin() ) {
$cart = WC()->cart;
if ( ! $cart ) {
return; // Корзина не инициализирована
}
// Атрибуты и значения для удаления
$target_attributes = [
'pa_color' => ['red', 'blue'],
'pa_size' => ['small']
];
// Обходим товары в корзине
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
foreach ( $target_attributes as $attr_name => $values ) {
if ( $product->is_type('variation') ) {
$variation_attributes = $product->get_variation_attributes();
if ( isset( $variation_attributes[$attr_name] ) && in_array( $variation_attributes[$attr_name], $values ) ) {
$cart->remove_cart_item( $cart_item_key );
break;
}
} else {
$product_attributes = $product->get_attributes();
if ( isset( $product_attributes[ $attr_name ] ) ) {
$attr = $product_attributes[ $attr_name ];
if ( $attr->is_taxonomy() ) {
$terms = wp_get_post_terms( $product->get_id(), $attr_name, ['fields' => 'slugs'] );
if ( array_intersect( $values, $terms ) ) {
$cart->remove_cart_item( $cart_item_key );
break;
}
}
}
}
}
}
}
}Объяснения:
- В
$target_attributesзадайте атрибуты и значения, по которым нужно удалять товары. - Функция проверяет и вариации, и простые товары.
- Удаление из корзины происходит через
$cart->remove_cart_item().
Проверка результата после внедрения
- Создайте заказ с товарами, у которых есть целевые атрибуты.
- Оплатите заказ (в тестовом режиме или реальной оплатой).
- После изменения статуса заказа на "завершён" откройте страницу корзины — товары с указанными атрибутами должны исчезнуть.
- В логе ошибок или консоли PHP проверьте отсутствие ошибок.
Частые ошибки и их исправление
- Корзина не очищается: возможно, хук срабатывает, но объект корзины не инициализирован в контексте обработки заказа. Решение — убедиться, что код запускается только на фронтенде (проверка
!is_admin()), либо использовать сторонние подходы (например, удаление товаров через сессию). - Неправильно указаны атрибуты: атрибуты WooCommerce всегда начинаются с
pa_в slug, проверьте правильность написания. - Удаляются не те товары: проверьте, что значение атрибута совпадает с теми, что заданы в массиве
$target_attributes.
Практические советы по оптимизации и безопасности
- Для улучшения производительности не используйте тяжелые запросы в цикле — при необходимости кэшируйте данные атрибутов.
- Проверяйте, что корзина и сессия WooCommerce доступны перед вызовом методов.
- Не удаляйте товары в админке, чтобы не нарушить логику управления заказами.
Сравнение вариантов реализации удаления товаров по атрибутам
| Метод | Плюсы | Минусы |
|---|---|---|
Код через хук woocommerce_order_status_completed | Точное время удаления, полная кастомизация, не требует плагинов | Зависит от инициализации корзины, требует отладки |
| Плагин с настройками фильтрации | Простота установки, готовый UI | Может создавать нагрузку, не всегда гибко |
| Удаление при загрузке страницы корзины | Простота реализации | Удаление не сразу после оплаты, возможные конфликты |