Диагностика задачи: когда и зачем менять цену товара программно
В WooCommerce стандартная цена товара задаётся в админке и отображается на витрине. Но бывают бизнес-сценарии, когда цену нужно менять динамически: например, для определённых пользователей, с учётом объёма заказа, даты или других условий. Встроенного функционала для таких настроек нет, поэтому требуется программное вмешательство.
Основные признаки задачи:
- Нужно показать на сайте цену, отличную от базовой, без изменения самой цены в базе.
- Изменённая цена должна учитываться при добавлении товара в корзину и оформлении заказа.
- Изменения должны работать корректно с кэшированием и не влиять на другие товары.
Пошаговое решение: изменение цены товара с помощью фильтра woocommerce_get_price
Для изменения цены товара в WooCommerce используем фильтр woocommerce_get_price, который позволяет переопределить цену перед выводом. Важно учесть, что цена должна меняться только для витрины и корзины, а не для всех запросов к объекту.
Пример кода: изменение цены для определённой роли пользователя
add_filter('woocommerce_get_price', 'custom_dynamic_price', 10, 2);
function custom_dynamic_price($price, $product) {
if (!is_admin() && is_user_logged_in()) {
$user = wp_get_current_user();
// Пример: для роли "wholesale_customer" скидка 20%
if (in_array('wholesale_customer', $user->roles)) {
$price = $price * 0.8;
}
}
return $price;
}
Код проверяет, что запрос не из админки, пользователь авторизован и принадлежит к роли wholesale_customer. В этом случае цена уменьшается на 20%.
Изменение цены в зависимости от количества товара в корзине
add_filter('woocommerce_get_price', 'custom_price_based_on_quantity', 10, 2);
function custom_price_based_on_quantity($price, $product) {
if (is_admin()) return $price;
$cart = WC()->cart;
if (!$cart) return $price;
$product_id = $product->get_id();
$quantity = 0;
foreach ($cart->get_cart() as $cart_item) {
if ($cart_item['product_id'] == $product_id) {
$quantity += $cart_item['quantity'];
}
}
if ($quantity >= 10) { // скидка 15% при покупке 10 и более
$price = $price * 0.85;
}
return $price;
}
Проверка результата после внедрения
Чтобы убедиться, что цена меняется как нужно, выполните следующие шаги:
- Авторизуйтесь под пользователем с нужной ролью (например, wholesale_customer) или добавьте в корзину нужное количество товара.
- Перейдите на страницу товара и проверьте отображаемую цену — она должна быть уменьшена согласно условию.
- Добавьте товар в корзину и убедитесь, что в корзине и на странице оформления заказа цена также соответствует изменённой.
- Перейдите под другим пользователем или в режиме инкогнито — цена должна быть базовой.
Частые ошибки и как их исправить
- Цена меняется в админке: добавьте проверку
if (is_admin()) return $price;в начале функции. - Цена не меняется в корзине или на странице заказа: убедитесь, что используете фильтр
woocommerce_get_price, а не толькоwoocommerce_product_get_price. Проверьте, что код подключён и не конфликтует с другими плагинами. - Кэширование показывает старую цену: отключите кэш для страниц корзины и оформления заказа или используйте AJAX-подгрузку цены.
- Проблемы с другими плагинами скидок: проверьте порядок подключения фильтров и приоритеты. Возможно, понадобится изменить приоритет или использовать более узкие хуки.
Практические советы по безопасности и производительности
- Не меняйте цену в базе данных напрямую — используйте фильтры для динамического переопределения.
- Избегайте сложных запросов внутри фильтра, чтобы не замедлять загрузку страниц.
- Если цена зависит от внешних API или данных, кешируйте результат на время выполнения запроса.
- Проверяйте, что код не ломает совместимость с WooCommerce и другими плагинами.
Сравнение способов изменения цены в WooCommerce
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
Фильтр woocommerce_get_price | Динамическое изменение цены перед выводом | Гибко, не меняет данные в базе, действует на фронтенде | Нужно внимательно проверять контекст, возможны конфликты |
| Изменение цены в мета-данных товара | Изменение цены через update_post_meta | Простая реализация | Меняет базу, сложнее откатить, влияет на все запросы |
| Использование плагинов скидок | Готовые решения для скидок и динамических цен | Удобно, много опций, поддержка | Может быть избыточным, нагрузка, ограниченная кастомизация |