Диагностика задачи: зачем менять стоимость товаров программно
В WooCommerce часто возникает необходимость менять цену товара динамически — например, в зависимости от пользовательской роли, текущих акций, курса валют или других условий. Ручное изменение цен неудобно и не масштабируется. Лучший способ — использовать хуки для автоматического изменения стоимости на лету без изменения данных в базе.
Какие хуки отвечают за отображение цены
Для корректного изменения цены в WooCommerce используются фильтры:
woocommerce_get_price— для базовой цены товара;woocommerce_product_get_price— объектно-ориентированный вариант;woocommerce_product_get_regular_priceиwoocommerce_product_get_sale_price— для регулярной и акционной цен;woocommerce_variation_prices_price— для вариаций товаров.
Используя эти фильтры, вы можете подменять цену без изменения записи в БД.
Пошаговое решение: пример изменения цены для определённой роли пользователя
Предположим, что для пользователей с ролью wholesale_customer нужно сделать скидку 15% на все товары.
add_filter('woocommerce_product_get_price', 'custom_price_for_wholesale', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_price_for_wholesale', 10, 2);
add_filter('woocommerce_product_get_sale_price', 'custom_price_for_wholesale', 10, 2);
function custom_price_for_wholesale($price, $product) {
if (!is_user_logged_in()) {
return $price;
}
$user = wp_get_current_user();
if (in_array('wholesale_customer', (array) $user->roles)) {
$discount = 0.15; // 15% скидка
$new_price = $price * (1 - $discount);
return round($new_price, 2);
}
return $price;
}Этот код подключается к фильтрам, проверяет роль пользователя и возвращает новую цену. Аналогично можно добавить условия по времени или другим параметрам.
Проверка результата
Чтобы убедиться, что цена меняется корректно:
- Войдите на сайт под пользователем с ролью
wholesale_customerи откройте страницу товара — цена должна отображаться со скидкой 15%. - Выйдите или войдите под обычным пользователем — цена должна быть без изменений.
- Проверьте корзину и оформление заказа — итоговая сумма должна соответствовать новой цене.
Для отладки можно временно добавить error_log() с выводом цены в файл debug.log.
Частые ошибки и их исправление
- Цена не меняется — фильтры не срабатывают. Проверьте, не кеширует ли сайт цены (например, плагин кеширования или CDN). Также убедитесь, что фильтры подключены в
functions.phpили плагине и подключены на нужных хуках. - Цена меняется, но в корзине или на странице оплаты — старая. Добавьте тот же фильтр и для AJAX-запросов и убедитесь, что WooCommerce обновляет цену в сессии.
- Ошибка округления или тип данных. Используйте
round()для корректного округления цены до 2 знаков после запятой.
Практические советы по производительности и безопасности
- Избегайте тяжелых вычислений внутри фильтров цены — они вызываются очень часто.
- Кешируйте результаты вычислений, если это возможно.
- Не меняйте цену в базе, используйте только фильтры для вывода.
- Проверяйте наличие пользователей и ролей безопасным способом, избегайте ошибок с отсутствием пользователя.
Сравнение подходов к изменению цены в WooCommerce
| Метод | Плюсы | Минусы | Пример использования |
|---|---|---|---|
| Фильтры (хуки) | Не меняет БД, динамично, гибко | Сложнее отладка, требует знаний хуков | Пример выше — скидка по роли |
| Изменение цены в админке вручную | Просто | Не масштабируемо, требует ручной работы | Редактирование товара |
| Плагины скидок и динамического ценообразования | Удобный UI, готовые функции | Весомый вес, может конфликтовать | WooCommerce Dynamic Pricing |