Диагностика задачи: когда и зачем менять цену автоматически
В интернет-магазинах на WooCommerce часто возникает потребность менять цену товара программно — например, при акциях, изменении курса валют, наличии определённых категорий товаров, или для особых пользователей (оптовиков, постоянных клиентов). Встроенные возможности WooCommerce позволяют задать скидки или цены через купоны и правила, но для сложных сценариев требуется писать код.
Если у вас есть задача автоматически изменять цену товара при загрузке страницы или в корзине на основе кастомных условий, важно понимать, что простая замена цены в базе данных без применения WooCommerce Hooks не сработает корректно, и цены не обновятся в интерфейсе.
Пошаговое решение: как программно менять цену товара
1. Используем фильтр woocommerce_product_get_price
Этот фильтр позволяет динамически изменить цену товара на фронтенде и в корзине. Пример кода для изменения цены товаров из категории "Акция" с увеличением на 10%:
add_filter('woocommerce_product_get_price', 'custom_dynamic_price', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_dynamic_price', 10, 2);
function custom_dynamic_price($price, $product) {
if (has_term('aktsiya', 'product_cat', $product->get_id())) {
$new_price = $price * 1.1; // увеличить цену на 10%
return wc_format_decimal($new_price, 2);
}
return $price;
}2. Дополнительно меняем цену для вариативных товаров
Для вариативных товаров нужно также фильтровать цены вариаций:
add_filter('woocommerce_variation_prices_price', 'custom_variation_price', 10, 3);
add_filter('woocommerce_variation_prices_regular_price', 'custom_variation_price', 10, 3);
function custom_variation_price($price, $variation, $product) {
if (has_term('aktsiya', 'product_cat', $product->get_id())) {
$new_price = $price * 1.1;
return wc_format_decimal($new_price, 2);
}
return $price;
}3. Меняем цену в корзине для расчёта итогов
Чтобы цена изменилась и в корзине, используйте хук woocommerce_before_calculate_totals:
add_action('woocommerce_before_calculate_totals', 'custom_cart_item_price');
function custom_cart_item_price($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
foreach ($cart->get_cart() as $cart_item) {
$product = $cart_item['data'];
if (has_term('aktsiya', 'product_cat', $product->get_id())) {
$price = $product->get_price();
$new_price = $price * 1.1;
$product->set_price($new_price);
}
}
}Проверка результата после внедрения
- Откройте страницу товара из категории "Акция" и убедитесь, что цена увеличилась на 10%.
- Добавьте товар в корзину и проверьте итоговую стоимость — она должна соответствовать изменённой цене.
- Проверьте вариативные товары с категорией "Акция" — все вариации должны отображать цену с наценкой.
- В админке цена товара не изменится — это нормальное поведение, так как цена изменяется программно только на фронтенде.
Частые ошибки и как их исправить
- Цена не меняется в корзине: не добавлен или неправильно реализован хук
woocommerce_before_calculate_totals. Проверьте, что функция подключена и работает. - Цена сбрасывается при обновлении страницы: убедитесь, что установлены фильтры и действия с правильным приоритетом и параметрами.
- Изменённая цена не учитывается при оформлении заказа: в некоторых случаях нужно дополнительно реализовать сохранение цены в метаданных заказа при создании заказа через хук
woocommerce_checkout_create_order_line_item. - Конфликт с плагинами кеширования: отключите кеширование страниц для страниц корзины и товаров, чтобы динамическое изменение цены применялось корректно.
Практические советы по безопасности и производительности
- Не изменяйте цены напрямую в базе без фильтров WooCommerce — это может сломать логику магазина и привести к ошибкам.
- Используйте проверку условий по категориям или меткам, чтобы ограничить область действия кода и не влиять на все товары.
- Избегайте дорогостоящих запросов в циклах — используйте кеширование результатов, если нужно часто проверять условия.
- Тестируйте изменения на тестовом сайте перед внедрением в продакшен, чтобы избежать сбоев в работе магазина.
Сравнение вариантов реализации динамического изменения цены
| Метод | Плюсы | Минусы | Пример использования |
|---|---|---|---|
Фильтры woocommerce_product_get_price | Лёгкая реализация, динамичность, не меняет базу | Не меняет цену в админке, может не работать с кастомными плагинами | Изменение цены на 10% для категории |
Хук woocommerce_before_calculate_totals в корзине | Корректное обновление цены в корзине и на этапе оформления | Требует дополнительной логики для сохранения в заказе | Установка модифицированной цены в корзине |
| Изменение цены товара в базе данных | Постоянное изменение цены | Риск ошибок, сбои, требует отката, не подходит для временных изменений | Обновление цены через SQL запросы |