WooCommerce: как изменить стоимость товара в корзине по условиям

Диагностика задачи: зачем менять стоимость товара в корзине

В WooCommerce стандартно цена товара фиксирована и отображается в корзине, исходя из цены в карточке товара. Однако часто возникает задача изменить стоимость товара динамически в корзине по определённым условиям: скидка при покупке нескольких товаров, изменение цены по ролям пользователей, индивидуальные скидки или специальные цены для определённых категорий. Без изменения цены именно в корзине эти сценарии не реализовать корректно.

Пошаговое решение: изменение цены товара в корзине через хук woocommerce_before_calculate_totals

Основной способ — использовать хук woocommerce_before_calculate_totals, который срабатывает до подсчёта итоговой стоимости корзины. Внутри этого хука можно изменить цену каждого товара в объекте корзины.

Пример: скидка 10% на все товары категории "Футболки" при покупке больше 3 штук

add_action('woocommerce_before_calculate_totals', 'custom_dynamic_price_cart', 10, 1); function custom_dynamic_price_cart( $cart ) { if ( is_admin() && ! defined('DOING_AJAX') ) return; // Проверяем, что это не админка и не ajax foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) { $product = $cart_item['data']; $quantity = $cart_item['quantity']; if ( has_term( 'futbolki', 'product_cat', $product->get_id() ) && $quantity >= 3 ) { $regular_price = $product->get_regular_price(); $new_price = $regular_price * 0.9; // Скидка 10% $product->set_price( $new_price ); } else { $product->set_price( $product->get_regular_price() ); // Возвращаем стандартную цену } } }

Как это работает

  • Проверяем категорию товара через has_term.
  • Проверяем количество товара в корзине.
  • Если условие выполнено — изменяем цену товара методом set_price().
  • Иначе сбрасываем цену на регулярную (чтобы при повторном подсчёте не осталось изменённой цены).

Проверка результата после внедрения

  • Добавьте в корзину товары из нужной категории, например футболки, в количестве 3 и более.
  • Перейдите в корзину и убедитесь, что цена изменилась на 10% меньше.
  • Измените количество товара на меньше 3 — цена должна вернуться к обычной.
  • Протестируйте на разных товарах и категориях, чтобы убедиться, что цены меняются корректно.

Частые ошибки и как исправить

1. Изменения не применяются, цена остаётся прежней

Убедитесь, что вы используете хук woocommerce_before_calculate_totals с приоритетом не выше 10, и что функция не вызывается в админке или ajax-запросах, которые могут сбрасывать цену.

2. Цена меняется, но итоговая сумма корзины неверна

Проверьте, чтобы каждый раз в цикле вы корректно сбрасывали цену к обычной, если условие не выполняется. Иначе WooCommerce может считать цену по старым значениям.

3. Изменение цены влияет на базу данных

Метод set_price() в корзине не меняет цену в базе, только в объекте корзины. Если вы видите, что цена изменилась в базе, возможно, где-то есть другой код, который сохраняет изменения. Исключите это.

Практические советы по безопасности и производительности

  • Не храните изменённые цены в метаданных или базе без крайней необходимости — это может привести к рассинхронизации данных.
  • Всегда проверяйте, что условия изменения цены не конфликтуют с кэшированием корзины и страниц.
  • Избегайте сложных и тяжёлых вычислений в хук, особенно если корзина содержит много товаров — это замедлит страницу.

Сравнение вариантов реализации динамического изменения цены товара в корзине

МетодОписаниеПлюсыМинусы
Хук woocommerce_before_calculate_totalsИзменение цены в объекте корзины перед подсчётом итоговой суммыЛегко реализовать, не меняет базу, гибкоНужно сбрасывать цену при ненужных условиях, влияет на производительность при большом количестве товаров
Создание пользовательской скидки через купоны или скидочные классыИспользование стандартных механик WooCommerce для скидокПростота и совместимость, кеширование работает корректноМенее гибко для сложных условий, ограничено функционалом купонов
Изменение цены товара в базе данныхПереопределение цены продукта через метаданные или сохранениеПостоянное изменение, отображается во всех местахРиск рассинхронизации, требует очистки кэша, сложнее реализовать

Дополнительный пример: изменение цены по роли пользователя

add_action('woocommerce_before_calculate_totals', 'price_for_user_role', 10, 1); function price_for_user_role( $cart ) { if ( is_admin() && ! defined('DOING_AJAX') ) return; $user = wp_get_current_user(); foreach ( $cart->get_cart() as $cart_item ) { $product = $cart_item['data']; if ( in_array( 'wholesale_customer', (array) $user->roles ) ) { // Для оптовых покупателей  $product->set_price( $product->get_regular_price() * 0.8 ); // Скидка 20% } else { $product->set_price( $product->get_regular_price() ); } } }

Это простой способ задать разные цены в корзине для разных ролей пользователей без изменения данных продуктов.

Добавь в закладки и поделись с друзьями:

⭐⭐⭐⭐⭐
Как добавить автоматическое удаление старых записей в WordPress
08.03.2026
Как избежать проблем с удалением пользователей в WordPress: практические решения
21.03.2026
Как успешно перенести сайт на новый домен в WordPress: практическое руководство
18.03.2026
Как отключить XML-RPC в WordPress для повышения безопасности
13.01.2026
Оптимизация загрузки шрифтов в WordPress: улучшение скорости и производительности
23.11.2025
×

Пора действовать!

Скидки на
WordPress!

-20%
на премиум темы

Успей купить ⋙