Диагностика задачи: зачем менять цену при изменении количества в корзине
В стандартном WooCommerce цена товара фиксирована и не зависит от количества в корзине. Задача — автоматически изменять цену товара в зависимости от объема заказа, например, применять скидку при покупке оптом или повышать цену при малых объемах. Такое поведение удобно для магазинов с ценовой политикой, зависящей от количества.
Как реализовать динамическое изменение цены в WooCommerce
Использование хука woocommerce_before_calculate_totals
Для изменения цены товаров в корзине необходимо использовать фильтр woocommerce_before_calculate_totals. В нем мы можем перебрать все товары в корзине и скорректировать set_price() для каждого товара в зависимости от количества.
add_action('woocommerce_before_calculate_totals', 'custom_dynamic_price_based_on_quantity', 20, 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) {
$product = $cart_item['data'];
$qty = $cart_item['quantity'];
$base_price = $product->get_regular_price();
// Пример логики изменения цены
if ($qty >= 10) {
// скидка 15% при 10+ товарах
$new_price = $base_price * 0.85;
} elseif ($qty >= 5) {
// скидка 7% при 5-9 товарах
$new_price = $base_price * 0.93;
} else {
$new_price = $base_price;
}
$product->set_price($new_price);
}
}Особенности реализации
- Проверяем, что действие не происходит в админке и без AJAX, чтобы избежать двойного вызова.
- Получаем базовую цену
get_regular_price(), а не текущую, чтобы избежать повторных изменений. - Присваиваем новую цену через метод
set_price()объекта продукта.
Проверка результата после внедрения
Чтобы убедиться, что динамическое изменение цены работает корректно:
- Добавьте товар в корзину и измените его количество.
- Обновите страницу корзины, проверьте итоговую цену товара — она должна меняться согласно заданной логике (например, скидка 15% при 10 и более товарах).
- Проверьте, что цена не меняется в каталоге и на странице товара — изменения касаются только корзины.
Частые ошибки и как их исправить
- Цена меняется и на странице товара: это происходит, если изменять цену не только в корзине, а глобально. Нужно применять логику только в
woocommerce_before_calculate_totals, так как этот хук вызывается только при подсчете корзины. - Цены меняются некорректно после обновления корзины: проверьте, что не происходит повторное применение скидки. Используйте проверку
did_action('woocommerce_before_calculate_totals'). - Изменения не применяются в админке или при AJAX-запросах: добавьте проверку
is_admin()иdefined('DOING_AJAX')чтобы избежать конфликтов.
Практические советы по безопасности и производительности
- Не храните цены с изменениями в базе — используйте динамическое изменение только в корзине.
- Оптимизируйте логику вычисления цены, избегайте тяжелых запросов в цикле
foreach. - Тестируйте интеграцию с плагинами кэширования и сторонними расширениями WooCommerce.
Сравнение вариантов реализации динамической цены
| Вариант | Плюсы | Минусы | Пример |
|---|---|---|---|
PHP-код через woocommerce_before_calculate_totals | Полный контроль, гибкость, без сторонних плагинов | Требует навыков программирования, возможно конфликт с другими хуками | Этот пример в статье |
| Плагины скидок и динамического ценообразования | Простота настройки, готовые решения | Может быть дорого, ограниченные настройки, нагрузка | WooCommerce Dynamic Pricing & Discounts |