wp-lessons.ru wordpress WP-Lessons

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

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

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

Проверьте, что у вас нет конфликтующих плагинов для изменения цен и что WooCommerce обновлён. Для диагностики проблем с динамическими ценами полезно проверить, применяются ли фильтры WooCommerce woocommerce_product_get_price и woocommerce_product_get_regular_price.

Пошаговое решение: изменение цены через хуки WooCommerce

Для динамического изменения цены используйте фильтр woocommerce_product_get_price. Ниже пример, как уменьшить цену на 10% для зарегистрированных пользователей, если товар из категории "Акции".

add_filter('woocommerce_product_get_price', 'custom_dynamic_price', 10, 2);
function custom_dynamic_price($price, $product) {
    if (is_user_logged_in()) {
        if (has_term('akcii', 'product_cat', $product->get_id())) {
            $price = $price * 0.9; // скидка 10%
        }
    }
    return $price;
}

Обратите внимание, что для корректного отображения скидок нужно изменить и регулярную цену, если вы хотите, чтобы скидка отображалась корректно на странице товара и в корзине. Добавим:

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

Если вы хотите менять цену в зависимости от количества в корзине — это уже задача для фильтра woocommerce_before_calculate_totals:

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

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

        if ($quantity >= 5) {
            $new_price = $product->get_regular_price() * 0.85; // скидка 15% при покупке от 5 штук
            $product->set_price($new_price);
        }
    }
}

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

  • Зайдите на сайт под пользователем с разными ролями (гость и авторизованный).
  • Откройте товар из категории "Акции", убедитесь, что цена изменилась на 10% для залогиненного пользователя.
  • Добавьте в корзину 4 товара — цена без скидки, 5 и более — скидка 15% применяется.
  • Проверьте отображение цены на странице товара, в корзине и на странице оформления заказа.

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

  • Цена не меняется: не подключен фильтр или он с низким приоритетом. Проверьте, что хук подключён правильно и приоритет 10.
  • Скидка не отображается в корзине: Не меняйте цену напрямую через мета поля товара, используйте фильтр woocommerce_before_calculate_totals для изменения цены в корзине.
  • Конфликт с кэшированием: Кэш может показывать старую цену. Очистите кэш сайта и браузера.
  • Изменение цены влияет на регулярную цену товара: Не меняйте базовые данные товара в базе, только выводимые цены через фильтры.

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

  • Избегайте тяжелых запросов в фильтрах изменения цены — кешируйте результаты, если используете сложные условия.
  • Не изменяйте цены в базе данных напрямую — всегда через фильтры или действия WooCommerce.
  • Проверяйте, что пользователь имеет право на скидку через current_user_can() или дополнительные проверки ролей.
  • Используйте проверку is_admin() && !defined('DOING_AJAX') для исключения изменений цен в админке, чтобы избежать проблем с сохранением.

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

СпособПлюсыМинусыПример использования
Фильтр woocommerce_product_get_priceПростая реализация, изменяет цену на фронтендеНе влияет на цену в корзине автоматическиСкидка для залогиненных пользователей на странице товара
Действие woocommerce_before_calculate_totalsИзменяет цену в корзине и при оформлении заказаСложнее, требует осторожности, может повлиять на логику заказаСкидка в зависимости от количества в корзине
Плагин динамического ценообразованияГотовые настройки без кода, удобный интерфейсМожет влиять на производительность, лишние зависимостиБольшие магазины с разными скидками и акциями
×
ABC
Pagination
Улучшай навигацию на сайте за секунды!
-15%

на ABC Pagination плагин WordPress

Сделать красиво ⋙