WooCommerce: автоматическое изменение стоимости товаров по условиям на разных страницах

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

В WooCommerce часто возникает задача изменять цену товара в зависимости от контекста — например, на странице категорий показывать скидку, а на странице товара — другую цену, или же менять цену в корзине в зависимости от количества или роли пользователя. Стандартных настроек WooCommerce для таких сценариев нет, поэтому приходится использовать код.

Типичные симптомы, что нужна динамическая корректировка цены:

  • Цена на странице товара отличается от цены в списке товаров;
  • Необходима скидка для определенных пользователей или ролей только на определенных страницах;
  • Хочется показывать специальные цены во время акций только на странице категории, не меняя цену в карточке товара;
  • Нужно менять цену в корзине под условия (например, при заказе от определенной суммы или количества).

Обзор подходов к изменению цены по условиям

Варианты реализации

МетодОписаниеПлюсыМинусы
Использование фильтра woocommerce_product_get_priceИзменение цены на уровне объекта товара при вызовеГибко, работает во всех местах, где цена запрашиваетсяНеобходимо учитывать условия, чтобы не изменить цену везде одинаково
Изменение цены в корзине через woocommerce_before_calculate_totalsКоррекция цены только в корзине и на кассеЧётко воздействует на итоговую сумму заказаНе влияет на вывод цены на страницах товаров и каталога
Использование JavaScript для замены цены на фронтендеДинамическая подмена цены без изменения данных на сервереБыстро реализуется, не затрагивает серверЦена не меняется в заказе, только визуально; можно обойти

Пошаговое решение: динамическое изменение цены по условиям страниц

1. Изменяем цену на основе типа страницы

Для примера изменим цену товара на странице категории и на странице товара по-разному.

add_filter('woocommerce_product_get_price', 'custom_dynamic_price_by_page', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_dynamic_price_by_page', 10, 2);
function custom_dynamic_price_by_page($price, $product) {
    if (is_admin()) return $price; // Не трогаем админку

    if (is_product_category()) {
        // Например, скидка 10% на странице категории
        $price = $price * 0.9;
    } elseif (is_product()) {
        // На странице товара скидка 5%
        $price = $price * 0.95;
    }
    return $price;
}

2. Корректируем цену в корзине и на странице оформления заказа

Чтобы цена в корзине соответствовала изменённой цене, нужно использовать хук woocommerce_before_calculate_totals.

add_action('woocommerce_before_calculate_totals', 'custom_dynamic_cart_price', 20, 1);
function custom_dynamic_cart_price($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;

    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        $product = $cart_item['data'];
        $price = $product->get_price();

        // Здесь можно повторить логику из фильтра цены или вынести в отдельную функцию
        if (current_user_can('wholesale_customer')) {
            // Допустим, дополнительная скидка для оптовиков
            $price = $price * 0.85;
        }

        $cart_item['data']->set_price($price);
    }
}

3. Вынос логики в отдельную функцию для удобства

Чтобы не дублировать код, создадим функцию, которая рассчитывает цену по условиям, и используем её в фильтрах и в корзине.

function get_dynamic_price_for_product($product) {
    $price = $product->get_regular_price();

    if (is_product_category()) {
        $price *= 0.9;
    } elseif (is_product()) {
        $price *= 0.95;
    }

    if (current_user_can('wholesale_customer')) {
        $price *= 0.85;
    }

    return $price;
}

add_filter('woocommerce_product_get_price', function($price, $product) {
    if (is_admin()) return $price;
    return get_dynamic_price_for_product($product);
}, 10, 2);

add_filter('woocommerce_product_get_regular_price', function($price, $product) {
    if (is_admin()) return $price;
    return get_dynamic_price_for_product($product);
}, 10, 2);

add_action('woocommerce_before_calculate_totals', function($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;
    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        $price = get_dynamic_price_for_product($cart_item['data']);
        $cart_item['data']->set_price($price);
    }
});

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

Чтобы проверить, что цена меняется корректно:

  • Откройте страницу категории — цены должны быть на 10% ниже обычных.
  • Откройте страницу товара — цена должна быть снижена на 5%.
  • Добавьте товар в корзину и проверьте итоговую цену: если пользователь с ролью wholesale_customer, цена должна быть дополнительно снижена на 15%.
  • Проверьте админ-панель — цены не должны изменяться.

Для проверки используйте инструменты разработчика браузера и дебаг-выводы (например, error_log()).

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

  • Цена меняется в админке или REST API: всегда проверяйте is_admin() и defined('DOING_AJAX'), чтобы не ломать административные функции.
  • Изменения цены не применяются в корзине: не забудьте использовать хук woocommerce_before_calculate_totals и правильно устанавливать цену через set_price().
  • Дублирование логики: вынесите расчёт цены в отдельную функцию, чтобы избежать рассогласованности.
  • Кеширование цен: если используете кеширование (например, объектный кеш или плагин кеша), очищайте кеш после внесения изменений.

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

  • Не выполняйте дорогостоящие операции в фильтрах изменения цены, особенно если это происходит для каждого товара на странице.
  • Используйте кэширование результатов расчёта цены, если логика сложная.
  • Не изменяйте цену напрямую в базе данных, только через хуки и методы объектов WooCommerce.
  • Проверяйте права пользователя, чтобы не допустить утечки информации или неправильных скидок.
Как удалить неиспользуемые типы записей в базе данных WordPress
07.01.2026
WooCommerce: автоматическое создание купонов при заказах
27.04.2026
Автоматическое удаление старых записей и данных в WordPress через CRON
26.03.2026
WooCommerce: автоматическое продление статусов заказов по статусу оплаты
31.05.2026
Как создать настройку автоматического удаления спама в WordPress
28.12.2025