Диагностика задачи: когда и зачем изменять цену автоматически
В интернет-магазинах на WooCommerce часто возникает необходимость динамически корректировать цены товаров в зависимости от условий: акции, количество в корзине, роль пользователя, дата и время, регион и т.д. Встроенные возможности WooCommerce дают базовые скидки и купоны, но для более сложных сценариев нужна кастомизация.
Проверяем, что задача действительно требует программного решения, а не стандартных купонов или плагинов:
- Нужно менять цену не на этапе оформления заказа, а сразу на странице товара или в каталоге.
- Изменения зависят от сложных условий (например, роль пользователя + дата + наличие определённого товара в корзине).
- Требуется сохранить совместимость с другими плагинами и обновлениями WooCommerce.
Пошаговое решение: как автоматически изменить цену товара по условию
Шаг 1. Выбор правильного хука для изменения цены
Для динамического изменения цены в WooCommerce используется фильтр woocommerce_get_price — он вызывается при получении цены товара на фронтенде. Также можно использовать woocommerce_product_get_price и woocommerce_product_get_regular_price для более широкого охвата.
Шаг 2. Пример кода для изменения цены по роли пользователя
add_filter('woocommerce_get_price', 'custom_dynamic_price_by_user_role', 10, 2); function custom_dynamic_price_by_user_role($price, $product) { if (is_admin()) return $price; // Не менять в админке if (!is_user_logged_in()) return $price; $user = wp_get_current_user(); if (in_array('wholesale_customer', $user->roles)) { // Для оптовых клиентов делаем скидку 20% $price = $price * 0.8; } return $price; }Этот код уменьшит цену на 20% для пользователей с ролью wholesale_customer на всех страницах сайта.
Шаг 3. Условие по дате - акция в определённый период
add_filter('woocommerce_get_price', 'custom_price_date_based', 15, 2); function custom_price_date_based($price, $product) { $current_date = current_time('Y-m-d'); if ($current_date >= '2024-07-01' && $current_date <= '2024-07-07') { // В период акции уменьшаем цену на 15% $price = $price * 0.85; } return $price; }Шаг 4. Комбинация условий (роль + акция)
add_filter('woocommerce_get_price', 'custom_price_combined_conditions', 20, 2); function custom_price_combined_conditions($price, $product) { if (is_admin()) return $price; $user = wp_get_current_user(); $is_wholesale = in_array('wholesale_customer', $user->roles); $current_date = current_time('Y-m-d'); $is_promo_period = $current_date >= '2024-07-01' && $current_date <= '2024-07-07'; if ($is_wholesale && $is_promo_period) { // Дополнительная скидка 30% для оптовиков в период акции $price = $price * 0.7; } elseif ($is_wholesale) { $price = $price * 0.8; } elseif ($is_promo_period) { $price = $price * 0.85; } return $price; }Как проверить, что решение сработало
- Очистите кеш сайта и браузера, если активны кеширующие плагины.
- Зайдите под разными пользователями с нужными ролями и проверьте цену товара в каталоге и на странице товара.
- Изменяйте системную дату (локально или с помощью плагина для тестирования дат) и проверяйте цену в разные периоды.
- Проверьте корзину и оформление заказа — цена должна быть скорректирована и там.
Частые ошибки и как их исправить
- Не работает изменение цены в корзине и на странице оформления заказа. Фильтр
woocommerce_get_priceменяет цену на фронтенде, но для корзины используйтеwoocommerce_before_calculate_totalsи корректируйте цену через объект продукта в корзине. - Цена меняется в админке или REST API — нежелательно. Добавляйте проверку
is_admin()илиif (defined('REST_REQUEST') && REST_REQUEST), чтобы избежать нежелательных изменений. - Кеширование не позволяет увидеть изменения. Отключите кеширование, очистите кеш и попробуйте снова.
- Ошибки из-за некорректной роли пользователя. Проверьте, что роль действительно есть у пользователя и написана верно.
Практические советы по производительности и безопасности
- Не используйте тяжелые операции внутри фильтров, которые вызываются часто — кэшируйте результаты, если используете внешние запросы.
- Обязательно проверяйте, что функции не влияют на административную часть и API.
- Для сложных условий используйте отдельные функции и тестируйте логику отдельно.
- Учтите совместимость с плагинами кеширования и WooCommerce — после обновлений проверяйте работу кода.
Сравнение вариантов реализации динамического изменения цены
| Метод | Пример | Плюсы | Минусы |
|---|---|---|---|
Фильтр woocommerce_get_price | Изменение цены на фронтенде | Простота, меняет цену в каталоге и на страницах | Не влияет на цену в корзине и оформлении заказа |
Хук woocommerce_before_calculate_totals | Изменение цены в корзине | Управление ценой заказа, влияет на итоговую стоимость | Не меняет цену на страницах каталога |
| Использование плагинов скидок | Плагины для комплексных условий | Удобный интерфейс, много функций | Может быть избыточно, нагрузка, плата |