Диагностика проблемы: зачем менять цену по количеству товара
В стандартной комплектации WooCommerce не поддерживает динамическое изменение стоимости товара в зависимости от количества в корзине. Обычно пользователи хотят сделать скидки при покупке большего объема (например, цена за единицу снижается при покупке от 5 штук) или наоборот добавить надбавку при малых объемах. Для достижения этого нужно вмешаться в процесс расчета цены в корзине и на странице оформления заказа.
Как работает расчет стоимости товаров в WooCommerce
WooCommerce рассчитывает итоговую стоимость товара исходя из regular_price или sale_price и умножает на количество. Для динамических цен нужно изменить итоговую стоимость на этапе формирования корзины, используя соответствующие хуки.
Основные хуки для изменения стоимости товара в корзине
woocommerce_before_calculate_totals— позволяет изменить цены товаров перед расчетом общей суммы.woocommerce_cart_item_price— для изменения отображаемой цены товара в корзине.
Пошаговое решение: изменение цены товара в зависимости от количества
Приведем пример кода, который меняет цену товара в корзине, если количество больше или равно 5. В этом случае цена за единицу снижается на 10%.
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 ) {
$quantity = $cart_item['quantity'];
$product = $cart_item['data'];
if ( $quantity >= 5 ) {
$original_price = $product->get_regular_price();
$discounted_price = $original_price * 0.9; // 10% скидка
$product->set_price( $discounted_price );
} else {
// Важно вернуть оригинальную цену при обратном изменении количества
$product->set_price( $product->get_regular_price() );
}
}
}Этот код добавьте в файл functions.php вашей дочерней темы или в пользовательский плагин.
Как изменить отображаемую цену в корзине и на странице оформления заказа
Чтобы покупатель видел правильную цену, можно дополнительно изменить отображение цены товара:
add_filter('woocommerce_cart_item_price', 'custom_cart_item_price_display', 10, 3);
function custom_cart_item_price_display( $price, $cart_item, $cart_item_key ) {
$quantity = $cart_item['quantity'];
if ( $quantity >= 5 ) {
$original_price = wc_price( $cart_item['data']->get_regular_price() );
$discounted_price = wc_price( $cart_item['data']->get_price() );
return '<del>' . $original_price . '</del> <ins>' . $discounted_price . '</ins>';
}
return $price;
}Проверка результата после внедрения
- Добавьте в корзину товар в количестве 1-4 штук — цена должна оставаться базовой.
- Добавьте товар в количестве 5 и более — цена должна снизиться на 10%.
- Проверьте отображение цен в корзине и на странице оформления заказа — должна отображаться зачеркнутая оригинальная цена и выделенная новая цена.
- Обновите количество товара в корзине с более чем 5 до меньшего числа — цена должна вернуться к исходной.
Частые ошибки и как исправить
- Изменение цены происходит только один раз или не происходит вовсе: проверьте, что хук
woocommerce_before_calculate_totalsне вызывается более одного раза с помощьюdid_action(). Это помогает избежать дублирования изменений. - Цена меняется в админке или при обновлении товара: добавьте проверку
is_admin() && ! defined( 'DOING_AJAX' ), чтобы не влиять на административные операции. - Цена не возвращается к оригинальной при уменьшении количества: обязательно сбрасывайте цену к
regular_price, если условие скидки не выполняется. - Кэширование мешает обновлению цен: очистите кеш и отключите кеширование страниц, если оно активно, чтобы увидеть изменения.
Практические советы по безопасности и производительности
- Не храните измененную цену в базе данных, а меняйте ее динамически в корзине — это безопасно и не нарушает логику WooCommerce.
- Проверяйте, что ваш код не влияет на другие плагины, изменяющие цены (например, плагины скидок или динамических цен).
- Добавляйте кэширование результатов, если расчет сложный, но при динамической цене по количеству это обычно не требуется.
- Для сложной логики скидок лучше использовать специализированные плагины с поддержкой всех сценариев и совместимостью.
Сравнение вариантов реализации изменения цены
| Вариант | Плюсы | Минусы |
|---|---|---|
| Код в functions.php (как в примере) | Простой, быстро внедряется, полный контроль | Требует поддержки при обновлениях, может конфликтовать |
| Плагин динамических цен (например, WooCommerce Dynamic Pricing) | Готовые настройки, гибкая логика, поддержка | Платные, возможны конфликты, нагрузка |
| Использование купонов и скидок WooCommerce | Простой функционал, не требует кода | Ограниченный контроль, не для сложных условий |