Диагностика задачи: зачем менять стоимость товаров динамически
В стандартном WooCommerce цена товара фиксирована и при изменении количества сумма пересчитывается автоматически, умножаясь на цену. Однако в некоторых случаях требуется динамическое изменение стоимости в зависимости от количества в корзине, например, скидка за оптовую покупку, градация цен или специальные условия, которые нельзя реализовать штатными средствами.
Без кастомизации WooCommerce не умеет менять цену товара на лету в корзине — для этого нужно вмешательство в хуки и фильтры. В статье разберём, как грамотно и безопасно реализовать динамическое изменение стоимости товара при изменении количества в корзины с помощью PHP-кода.
Как проверить, что цена товара не меняется динамически
- Добавьте товар в корзину на сайте WooCommerce.
- Измените количество товара в корзине.
- Проверьте, что сумма пересчитывается просто как цена * количество без учёта дополнительных условий.
- Обычно в стандартном WooCommerce сумма меняется только за счёт умножения, без изменения цены за единицу.
Пошаговое решение: динамическое изменение цены товара в корзине
1. Используем фильтр woocommerce_before_calculate_totals
Этот хук позволяет изменять цены товаров в корзине до расчёта итоговой суммы. Подключимся к нему и изменим цену товара в зависимости от количества.
2. Пример кода для динамической цены с градацией
add_action('woocommerce_before_calculate_totals', 'custom_dynamic_price_based_on_quantity', 10, 1);
function custom_dynamic_price_based_on_quantity( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
return;
}
// Защита от повторного применения
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) {
return;
}
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$quantity = $cart_item['quantity'];
$original_price = $cart_item['data']->get_regular_price();
// Пример градации цен
if ( $quantity >= 10 ) {
$new_price = $original_price * 0.8; // 20% скидка при 10 и более
} elseif ( $quantity >= 5 ) {
$new_price = $original_price * 0.9; // 10% скидка при 5-9
} else {
$new_price = $original_price; // обычная цена
}
// Применяем новую цену
$cart_item['data']->set_price( $new_price );
}
}3. Куда добавить код
Рекомендуется добавлять кастомный код в файл functions.php дочерней темы или в собственный плагин, чтобы не потерять изменения при обновлении.
Проверка результата после внедрения
- Добавьте товар в корзину и меняйте количество с 1 до 15.
- Убедитесь, что цена за единицу меняется в соответствии с логикой (скидка 10% от 5 до 9 штук, 20% от 10 и более).
- Проверьте итоговую сумму и убедитесь, что она соответствует новой цене * количеству.
- Проверьте на разных товарах, чтобы не было конфликтов.
Частые ошибки и как исправить
- Цена не меняется: убедитесь, что хук
woocommerce_before_calculate_totalsподключён правильно и ваш код не блокируется другими плагинами. Проверьте, что нет ошибок PHP в логах. - Цена меняется некорректно или дублируется: применяйте проверку
did_action, чтобы избежать повторного применения фильтра. - Изменение цены влияет на другие страницы: код должен работать только в контексте корзины и оформления заказа, используйте условия
is_admin()иDOING_AJAX. - Проблемы с отображением цены в фронтенде: иногда нужно обновить кэш браузера и кэш плагинов кеширования.
Практические советы по безопасности и производительности
- Не используйте этот метод для изменения цены в базе данных — меняйте цену только в объекте товара в корзине, чтобы не нарушить логику WooCommerce.
- Проверяйте совместимость с другими плагинами, которые могут менять цены (купонные системы, другие скидки).
- Используйте кеширование для сложных вычислений цен, если логика меняется в зависимости от внешних API или данных.
- Тестируйте на тестовом окружении перед запуском на продакшене.
Сравнение вариантов реализации динамического ценообразования
| Метод | Плюсы | Минусы | Рекомендуется для |
|---|---|---|---|
Кастомный код на woocommerce_before_calculate_totals | Полный контроль, гибкость, бесплатно | Требует навыков PHP, возможны ошибки при неправильном коде | Разработчики, уникальные бизнес-правила |
| Плагины для скидок и оптовых цен | Простота настройки, готовые функции | Могут быть платными, ограниченная кастомизация | Быстрая реализация без программирования |
| Использование пользовательских цен в товарах | Прозрачность в админке, нет кастомного кода | Требует ручного обновления цен, нет динамики | Малые магазины со стабильными ценами |