Диагностика задачи: зачем и когда нужно менять цену автоматически
В интернет-магазинах на WooCommerce часто возникает необходимость динамически изменять цену товара на основе определённых условий: например, скидка для определённой группы пользователей, сезонные распродажи, специальные акции, изменения стоимости при покупке нескольких единиц товара или учет пользовательских метаданных. Встроенных средств WooCommerce для сложной логики изменения цены недостаточно, поэтому приходится использовать хуки и фильтры.
Используемые хуки для автоматического изменения цены
Основной фильтр для изменения цены товара в WooCommerce — woocommerce_get_price или woocommerce_product_get_price. Второй используется в новых версиях и более универсален.
Пример базового кода, который меняет цену товара в зависимости от ID пользователя:
add_filter('woocommerce_product_get_price', 'custom_dynamic_price', 10, 2);
function custom_dynamic_price($price, $product) {
$user_id = get_current_user_id();
if ($user_id) {
// Пример условия: если ID пользователя 123, цена снижена на 20%
if ($user_id === 123) {
$price = $price * 0.8;
}
}
return $price;
}Почему лучше использовать woocommerce_product_get_price
Этот фильтр срабатывает при получении цены объекта WC_Product, что учитывает разные варианты товара (вариации) и более надёжен для всех контекстов.
Пошаговое решение: динамическое изменение цены по условиям
1. Определяем условие изменения цены
Например, цена меняется при покупке больше 5 единиц товара или для пользователей с определённой ролью.
2. Реализуем функцию с фильтром
add_filter('woocommerce_product_get_price', 'change_price_based_on_quantity_and_role', 10, 2);
function change_price_based_on_quantity_and_role($price, $product) {
if (is_admin()) return $price; // Не меняем в админке
$user = wp_get_current_user();
$roles = (array) $user->roles;
// Пример: скидка для роли "wholesale_customer"
if (in_array('wholesale_customer', $roles)) {
$price = $price * 0.85; // 15% скидка
}
// Проверяем количество в корзине
foreach (WC()->cart->get_cart() as $cart_item) {
if ($cart_item['product_id'] === $product->get_id() && $cart_item['quantity'] > 5) {
$price = $price * 0.9; // 10% скидка при покупке больше 5 штук
break;
}
}
return $price;
}3. Добавляем фильтр для отображения цены на фронтенде
Чтобы цена изменилась на странице товара и в каталоге, добавим:
add_filter('woocommerce_get_price_html', 'custom_price_html', 10, 2);
function custom_price_html($price_html, $product) {
$price = $product->get_price();
$price_html = wc_price($price);
return $price_html;
}Проверка результата после внедрения
- Откройте страницу товара в режиме неавторизованного пользователя — цена должна быть базовой.
- Залогиньтесь под пользователем с ролью
wholesale_customer— цена должна измениться на 15% скидку. - Добавьте в корзину больше 5 единиц товара — цена должна стать на 10% меньше для этого товара.
- Проверьте в админке, что цены не изменяются.
Частые ошибки и как их исправить
- Изменение цены в админке: Это может привести к путанице — всегда проверяйте
is_admin()и исключайте изменение цены в административной части. - Неправильное использование хуков: Использование
woocommerce_get_priceвместоwoocommerce_product_get_priceможет не сработать для вариативных товаров. - Отсутствие проверки корзины: При обращении к корзине вне контекста WooCommerce может возникать ошибка — проверяйте, что корзина инициализирована.
- Кэширование цены: Кэш плагинов или серверный кэш могут показывать старую цену. Очистите кэш после внедрения.
Практические советы по производительности и безопасности
- Избегайте тяжелых запросов в функции изменения цены — используйте минимально необходимые данные.
- Проверяйте, что функции не вызываются в админке, API-запросах или CLI для предотвращения ошибок.
- Если меняете цены часто и по сложным условиям, рассмотрите использование transient для кеширования результатов.
- Для более сложных сценариев используйте плагины, поддерживающие динамические цены, или создайте отдельный плагин с вашей логикой.
Сравнение вариантов решения: код vs плагины
| Метод | Плюсы | Минусы |
|---|---|---|
| Код через хуки | Полный контроль, без зависимости от сторонних плагинов, гибкость | Требует навыков, возможны ошибки, нужно обновлять при изменениях WooCommerce |
| Плагины динамических цен | Готовые решения, удобный интерфейс, поддержка | Стоимость, избыточность для простых задач, нагрузка на сайт |