Диагностика задачи: зачем менять цену товара динамически
Иногда в WooCommerce возникает необходимость автоматически менять цену товара в зависимости от условий. Например, при покупке определённого количества, для конкретных ролей пользователей, по акциям или сезонным скидкам. Встроенного механизма для таких сценариев нет, поэтому приходится использовать хуки и кастомный код.
Как работать с ценами в WooCommerce через хуки
Для изменения цены товара в корзине и на странице товара применяют фильтр woocommerce_get_price или woocommerce_product_get_price. Они позволяют изменить цену динамически без сохранения в базе. Однако важно использовать их правильно, чтобы не сломать логику расчетов.
Пример: скидка 10% для пользователей с ролью "оптовик"
add_filter('woocommerce_product_get_price', 'custom_price_for_wholesale_users', 10, 2);
function custom_price_for_wholesale_users($price, $product) {
if (is_user_logged_in()) {
$user = wp_get_current_user();
if (in_array('wholesale_customer', $user->roles)) {
$price = $price * 0.9; // Скидка 10%
}
}
return $price;
}Этот код меняет цену для пользователя с ролью wholesale_customer на 90% от базовой.
Пошаговое решение: автоматическая смена цены при покупке более 5 штук
Допустим, нужно автоматически снижать цену на 15%, если в корзине товара больше 5 штук.
- Подключаемся к фильтру
woocommerce_before_calculate_totals, который срабатывает при пересчёте корзины. - Проходим по товарам в корзине, проверяем количество.
- Если количество больше 5, меняем цену для этого товара.
add_action('woocommerce_before_calculate_totals', 'bulk_discount_for_cart_items', 20);
function bulk_discount_for_cart_items($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
$quantity = $cart_item['quantity'];
if ($quantity > 5) {
$original_price = $cart_item['data']->get_regular_price();
$discounted_price = $original_price * 0.85; // 15% скидка
$cart_item['data']->set_price($discounted_price);
}
}
}Как проверить, что цена изменилась
- Добавьте в корзину более 5 штук одного товара.
- Перейдите в корзину и посмотрите итоговую цену товаров — должна примениться скидка 15%.
- Для роли пользователя с ролью
wholesale_customerобновите цену на странице товара — должна примениться скидка 10%. - Очистите кэш и отключите другие плагины, если изменения не видны.
Частые ошибки при изменении цен в WooCommerce и как их исправить
- Цены не меняются в корзине: возможно, код подключен не к тому хуку. Используйте
woocommerce_before_calculate_totals, а не фильтры для получения цены. - Изменения цены не отображаются на странице товара: убедитесь, что используете правильный фильтр
woocommerce_product_get_priceи что нет кэша. - Цена меняется для всех пользователей: проверьте условия в коде, возможно, пропущена проверка роли пользователя или количества товаров.
- Проблемы с совместимостью плагинов скидок: отключите другие плагины скидок, чтобы проверить конфликты.
Практические советы по производительности и безопасности
- Не изменяйте цену в базе данных — используйте хуки для динамической подмены.
- Кэшируйте результаты, если условия сложные, чтобы не нагружать сервер.
- Проверяйте пользовательские роли через
wp_get_current_user()безопасно, избегайте прямого обращения к $_SESSION. - Всегда тестируйте код на staging-сайте перед внедрением в продакшн.
Сравнение вариантов решения автоматической смены цены
| Метод | Преимущества | Недостатки | Код / Плагин |
|---|---|---|---|
| Фильтры WooCommerce (код) | Гибкость, контроль, бесплатно | Требует навыков программирования | Код из статьи |
| Плагины скидок (например, WooCommerce Dynamic Pricing) | Простой интерфейс, много настроек | Платно, возможные конфликты | Плагин |
| Сохранение цены в мета-полях товара | Постоянное изменение, подходит для фиксированных скидок | Требуется обновлять базу данных, сложнее менять динамически | Кастомный скрипт |