Диагностика задачи: зачем менять стоимость товара программно
В WooCommerce часто возникает необходимость динамически изменять цену товара в зависимости от условий — например, применять скидку для определенной категории покупателей, менять цену при покупке определенного количества или менять стоимость в зависимости от даты. Ручное изменение цены через админку неудобно и не масштабируется, поэтому оптимальный способ — использовать хуки WooCommerce для автоматического изменения цены на лету.
Основные хуки для изменения цены в WooCommerce
Для изменения цены в WooCommerce в процессе отображения и оформления заказа используют хуки, которые позволяют перезаписать цену товара перед выводом и расчетом в корзине и заказе.
woocommerce_product_get_price— возвращает цену товара для отображения.woocommerce_product_get_regular_price— возвращает базовую цену товара.woocommerce_before_calculate_totals— позволяет изменить цену товаров в корзине перед расчетом итогов.
Важно понимать, что изменение цены через woocommerce_product_get_price влияет на отображение цены на странице товара, а через woocommerce_before_calculate_totals — на итоговую стоимость в корзине и заказе.
Пошаговое решение: пример автоматической скидки 10% для товаров из категории «Распродажа»
Шаг 1: Подключение к хуку для изменения цены на странице товара
add_filter('woocommerce_product_get_price', 'custom_discounted_price', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_discounted_price', 10, 2);
function custom_discounted_price($price, $product) {
if (has_term('sale', 'product_cat', $product->get_id())) {
$discounted_price = $price * 0.9; // 10% скидка
return round($discounted_price, 2);
}
return $price;
}Этот код изменит цену для вывода на страницах магазина и товара, если у товара есть категория sale.
Шаг 2: Изменение цены в корзине и заказах
add_action('woocommerce_before_calculate_totals', 'custom_cart_item_price', 10);
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('sale', 'product_cat', $product->get_id())) {
$original_price = $product->get_price();
$new_price = $original_price * 0.9; // 10% скидка
$product->set_price(round($new_price, 2));
}
}
}Этот код гарантирует, что итоговая стоимость в корзине и заказах также будет со скидкой 10%.
Проверка результата после внедрения
- Перейдите на страницу товара с категорией «Распродажа» и убедитесь, что цена отображается с 10% скидкой.
- Добавьте этот товар в корзину и проверьте, что в корзине и на странице оформления заказа цена также снижена.
- Для контроля можно временно добавить логирование в функцию, например,
error_log(), чтобы убедиться, что код срабатывает.
Частые ошибки и их исправления
- Цена не меняется в корзине: часто забывают использовать
woocommerce_before_calculate_totalsдля изменения цены в корзине. Изменение цены только на фильтрах, связанных с выводом, не влияет на итоговую сумму. - Конфликт с кешированием: кеширование страниц или объектов может показывать старую цену. Отключите кеширование или добавьте исключения для страниц WooCommerce.
- Неверная категория: убедитесь, что slug категории указан верно в функции
has_term(). - Изменения влияют на админку: добавьте проверку
is_admin() && !defined('DOING_AJAX'), чтобы не менять цены в админ-панели и избежать ошибок.
Практические советы по безопасности и производительности
- Избегайте тяжелых запросов внутри хуков, особенно
woocommerce_before_calculate_totals, чтобы не замедлять процесс оформления заказа. - Кэшируйте результаты проверок, если логика сложная (например, проверка пользовательских метаданных или внешних условий).
- Используйте точные проверки категорий и условий, чтобы не затрагивать ненужные товары.
- Тестируйте изменения на staging-сайте перед внедрением в продакшен.
Сравнение способов изменения цены в WooCommerce
| Метод | Где меняет цену | Плюсы | Минусы |
|---|---|---|---|
Фильтр woocommerce_product_get_price |
Отображение на страницах товара | Простота, влияет на фронтенд | Цена в корзине без изменений |
Хук woocommerce_before_calculate_totals |
Цена в корзине и заказе | Меняет итоговую сумму, учитывается при оплате | Сложнее, может влиять на производительность |
| Комбинация двух методов | Отображение и расчет | Полное покрытие задачи | Требует аккуратности в коде |