Диагностика задачи: зачем менять цену при добавлении в корзину
В стандартном WooCommerce цена товара фиксирована и задаётся на странице продукта. Однако бывают ситуации, когда нужно динамически изменить цену именно в момент добавления товара в корзину — например, чтобы применять персональные скидки, менять стоимость в зависимости от количества или других условий, без влияния на цену продукта в каталоге.
Часто новички пытаются менять цену товара через фильтр woocommerce_get_price, но это не сработает для корзины. Для корректного изменения цены именно в корзине нужно использовать хук woocommerce_before_calculate_totals.
Пошаговое решение: как изменить цену товара в корзине
1. Используем хук woocommerce_before_calculate_totals
Этот хук срабатывает перед подсчётом итоговой стоимости заказа. В нём можно перебрать товары в корзине и изменить их цену.
add_action('woocommerce_before_calculate_totals', 'custom_change_cart_item_price', 20, 1); function custom_change_cart_item_price($cart) { if (is_admin() && !defined('DOING_AJAX')) return; // Защита от админки и ajax foreach ($cart->get_cart() as $cart_item_key => $cart_item) { $product = $cart_item['data']; $original_price = $product->get_price(); // Пример: уменьшаем цену на 10% $new_price = $original_price * 0.9; $product->set_price($new_price); }}2. Добавление условий для изменения цены
Можно менять цену только для определённых товаров, категорий или по пользовательским меткам:
add_action('woocommerce_before_calculate_totals', 'custom_conditional_price_change', 20, 1); function custom_conditional_price_change($cart) { if (is_admin() && !defined('DOING_AJAX')) return; foreach ($cart->get_cart() as $cart_item_key => $cart_item) { $product = $cart_item['data']; // Проверяем категорию if (has_term('sale', 'product_cat', $product->get_id())) { $original_price = $product->get_price(); $new_price = $original_price * 0.8; $product->set_price($new_price); } } }Проверка результата после внедрения
- Добавьте товар в корзину, подходящий под условие изменения цены.
- Перейдите на страницу корзины — цена должна отобразиться с изменением (например, со скидкой).
- Проверьте, что цена товара на странице каталога и карточке товара осталась без изменений.
- Включите режим отладки WooCommerce (в настройках) для проверки правильности расчётов.
Частые ошибки и как их исправить
- Изменение цены в функции без проверки контекста. Вызов изменения цены в админке или при ajax-запросах может привести к ошибкам. Добавляйте проверку
if (is_admin() && !defined('DOING_AJAX')) return;. - Изменение цены продукта напрямую в базе. Это ломает логику WooCommerce и не подходит для динамических сценариев.
- Использование фильтра
woocommerce_get_priceдля изменения цены в корзине. Этот фильтр не влияет на цену товара в корзине, а только на вывод цены в каталоге. - Не сбрасывать кеш объектов товара. При сложных изменениях используйте методы
$product->set_price()корректно, не создавая новых объектов.
Практические советы по производительности и безопасности
- Не делайте сложных вычислений внутри цикла перебора корзины — кешируйте данные вне цикла, если нужно.
- Избегайте работы с базой в момент изменения цены — все данные должны быть загружены в объекты WC_Product.
- При использовании пользовательских условий (например, метаполя пользователя) не забывайте проверять права доступа и безопасность данных.
- Для сложных сценариев с большим количеством товаров рассмотрите использование transient-кеша или внешних сервисов для расчёта цен.
Альтернативные варианты реализации: код vs плагины
| Вариант | Плюсы | Минусы |
|---|---|---|
Ручное изменение цены через хук woocommerce_before_calculate_totals | Гибкость, контроль, минимальная нагрузка | Требует навыков PHP, ручная поддержка |
| Плагины динамического ценообразования (например, WooCommerce Dynamic Pricing) | Удобство, готовые правила, интерфейс | Стоимость, возможные конфликты, нагрузка |