Автоматическое изменение стоимости товаров в WooCommerce по заданным условиям

Диагностика задачи: почему нужно менять цены автоматически

В интернет-магазинах на WooCommerce часто возникает необходимость менять стоимость товаров динамически в зависимости от различных условий: например, даты акции, роли пользователя, объема заказа или регионов доставки. Ручное изменение цен неудобно и чревато ошибками, особенно при большом ассортименте или частых акциях.

Задача: настроить автоматическое изменение цены товара без установки громоздких плагинов, используя возможности WooCommerce и WordPress.

Как реализовать автоматическое изменение цены в WooCommerce

Какие хуки использовать для изменения цены

WooCommerce предоставляет фильтры, которые позволяют менять цену товара «на лету» при выводе и при добавлении в корзину. Основные хуки для этого:

  • woocommerce_product_get_price — для получения основной цены товара;
  • woocommerce_product_get_regular_price — для обычной цены (без скидок);
  • woocommerce_product_get_sale_price — для цены со скидкой;
  • woocommerce_before_calculate_totals — для изменения цены в корзине;
  • woocommerce_cart_item_price и woocommerce_cart_item_subtotal — для отображения цены в корзине.

Пошаговое решение: пример изменения цены по роли пользователя

Допустим, нужно сделать специальную цену для пользователей с ролью wholesale_customer. Для них цена товара будет снижена на 20%.

add_filter('woocommerce_product_get_price', 'custom_price_by_user_role', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_price_by_user_role', 10, 2);
add_filter('woocommerce_product_get_sale_price', 'custom_price_by_user_role', 10, 2);

function custom_price_by_user_role($price, $product) {
    if (is_admin()) return $price; // не менять в админке

    if (is_user_logged_in()) {
        $user = wp_get_current_user();
        if (in_array('wholesale_customer', (array) $user->roles)) {
            $price = $price * 0.8; // скидка 20%
        }
    }
    return $price;
}

// Обновляем цену в корзине
add_action('woocommerce_before_calculate_totals', 'custom_cart_price_by_user_role', 10, 1);
function custom_cart_price_by_user_role($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;

    if (is_user_logged_in()) {
        $user = wp_get_current_user();
        if (in_array('wholesale_customer', (array) $user->roles)) {
            foreach ($cart->get_cart() as $cart_item) {
                $original_price = $cart_item['data']->get_price();
                $new_price = $original_price * 0.8;
                $cart_item['data']->set_price($new_price);
            }
        }
    }
}

Этот код изменяет цену товара и в каталоге, и в корзине, если пользователь с нужной ролью.

Проверка результата после внедрения

  • Залогиньтесь под пользователем с ролью wholesale_customer и под обычным пользователем;
  • Проверьте отображение цены товара в каталоге и на странице товара — должна применяться скидка 20% только для wholesale_customer;
  • Добавьте товар в корзину и убедитесь, что цена там тоже пересчитана;
  • Для полного теста проверьте оформление заказа, чтобы скидка корректно сохранилась.

Частые ошибки и как их исправить

  • Изменение цены в админке. Если не проверять is_admin(), цена может стать некорректной при редактировании товара. Всегда добавляйте условие if (is_admin()) return $price;.
  • Цена не меняется в корзине. Не забывайте использовать хук woocommerce_before_calculate_totals и устанавливать цену через $cart_item['data']->set_price(). Если этого не сделать, измененная цена не отобразится при оформлении заказа.
  • Кэширование мешает обновлению цены. Если на сайте включено кэширование (например, через плагин или серверный кэш), цены могут не обновляться для разных пользователей. В этом случае настройте исключения по кукам или URL.

Практические советы по безопасности и производительности

  • Не используйте тяжелые запросы в фильтрах цены. Они вызываются при каждом отображении товаров, поэтому сложные запросы в базу данных или API лучше выносить в кеш или предварительно рассчитывать.
  • Кэшируйте результат вычисления скидки. Например, сохраните значение скидки для пользователя в сессии или transient, чтобы не вычислять при каждом вызове.
  • Ограничьте изменение цены только необходимыми страницами. Например, используйте is_product() || is_shop() || is_cart() || is_checkout() для уменьшения нагрузки.

Сравнение способов изменения цены в WooCommerce

МетодПлюсыМинусыКогда использовать
Фильтры woocommerce_product_get_priceПростая реализация, работает на фронтендеНе меняет цену в корзине автоматическиДля изменения цены при отображении товара
Хук woocommerce_before_calculate_totalsМеняет цену в корзине и при оформлении заказаНужно писать дополнительный код, сложнееДля динамического изменения цены в корзине
Плагины для скидокУдобный интерфейс, много функцийБольшой вес, может конфликтовать с кастомным кодомДля сложных акций и маркетинговых кампаний
Добавление коллекции атрибутов для товаров WooCommerce без плагинов: практическое руководство
21.06.2026
Как использовать Redis для ускорения WordPress: настройка и примеры
10.03.2026
Как оптимизировать базу данных WordPress для быстрой работы сайта
18.11.2025
Как решить проблему неработающих email-уведомлений WooCommerce
09.06.2026
Как изменить отображаемое авторское имя в WordPress без плагинов
11.02.2026