wp-kurs.ru wordpress WP-Kurs

WooCommerce: программное изменение цены товара без изменения в админке

Проблема: зачем менять цену товара динамически без правки в админке?

В стандартном WooCommerce цена товара задаётся в админке и сохраняется в базе. Но иногда требуется изменить цену для пользователя или условия показа (например, в зависимости от роли, времени, акции), не меняя саму цену в карточке товара. Это полезно для динамических скидок, персонализации, тестирования цен или интеграции с внешними сервисами.

Диагностика: почему простая смена цены в админке не подходит?

  • Изменение цены в админке влияет на всех покупателей и сохраняется навсегда.
  • Может быть множество условий, которые невозможно учесть вручную.
  • При использовании кэширования и CDN важно менять цену на этапе вывода, а не в базе.

Пошаговое решение: как программно изменить цену на лету через фильтры WooCommerce

WooCommerce предоставляет фильтры woocommerce_get_price и woocommerce_product_get_price, с помощью которых можно динамически изменить цену товара при выводе.

Пример кода, который изменит цену для гостей, уменьшая её на 10%:

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

function custom_dynamic_price($price, $product) {
    if (!is_user_logged_in()) { // для гостей
        $new_price = $price * 0.9; // 10% скидка
        return round($new_price, 2);
    }
    return $price;
}

Если нужно менять цену только на витрине (каталоге), без изменения в корзине и на страницах заказа, можно добавить проверку контекста:

function custom_dynamic_price_catalog($price, $product) {
    if (is_admin()) {
        return $price; // не менять в админке
    }
    if (is_shop() || is_product_category() || is_product_tag()) {
        return $price * 0.9;
    }
    return $price;
}
add_filter('woocommerce_product_get_price', 'custom_dynamic_price_catalog', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_dynamic_price_catalog', 10, 2);
add_filter('woocommerce_product_get_sale_price', 'custom_dynamic_price_catalog', 10, 2);

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

  • Очистите кэш сайта и браузера.
  • Откройте страницу товара как гость — цена должна отображаться с учётом скидки.
  • Войдите под пользователем — цена должна быть стандартной.
  • Добавьте товар в корзину и проверьте цену там — она будет исходной, если не добавлять фильтры для корзины.

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

  • Цена меняется в админке или базе данных — фильтры работают только на вывод, не меняйте напрямую мета-данные _price.
  • Цена не меняется на страницах корзины и оформления заказа — добавьте фильтры woocommerce_cart_item_price и woocommerce_cart_item_subtotal или используйте woocommerce_before_calculate_totals для изменения цены в корзине.
  • Проблемы с кэшированием — отключите кэширование страниц или используйте AJAX для динамического обновления цены.
  • Неверное округление цены — используйте round() с двумя знаками после запятой.

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

  • Не храните динамические цены в базе данных, чтобы избежать рассинхронизации.
  • Используйте кеширование с умом — если цена зависит от пользователя, кэшируйте индивидуально или отключайте кэш для таких страниц.
  • Избегайте тяжелых запросов внутри фильтров цены — лучше заранее подготовить данные.

Сравнение вариантов реализации динамического изменения цены

МетодПлюсыМинусы
Фильтры WooCommerce (woocommerce_product_get_price) Просто, работает на выводе, не меняет базу Не меняет цену в корзине по умолчанию, надо дописывать
Изменение мета-данных товара (update_post_meta) Меняет цену для всех, можно интегрировать с внешними системами Меняет базу, приведёт к путанице, требует отката
Использование плагинов (например, Dynamic Pricing) Готовые решения с интерфейсом и поддержкой Тяжелее, может быть избыточно, платные
×
Сделай свой сайт крутым!

Скидка -20% на премиум плагины WordPress

Выбрать плагин сейчас ⋙