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