Диагностика задачи: когда и зачем менять цену товара динамически
В WooCommerce стандартные цены товаров фиксированы и задаются в админке. Но часто требуется изменить стоимость товара на лету, например, в зависимости от пользователя, количества, даты или других условий. Это важно для реализации акций, персональных скидок, оптовых тарифов без создания множества вариаций товара.
Проблема в том, что стандартные настройки WooCommerce не позволяют гибко менять цену товара без дополнительных плагинов или кастомного кода. При этом прямое изменение цены в базе данных опасно и неэффективно.
Пошаговое решение: как изменить цену товара программно с помощью фильтра
WooCommerce предоставляет фильтр woocommerce_get_price, который позволяет изменить цену товара в рантайме перед выводом на сайт и в корзину.
Пример: изменяем цену товара с ID 123, если покупатель авторизован и его роль – «оптовик» (custom role 'wholesale_customer'):
add_filter('woocommerce_get_price', 'custom_dynamic_price', 10, 2);
function custom_dynamic_price($price, $product) {
if (is_user_logged_in()) {
$user = wp_get_current_user();
if (in_array('wholesale_customer', $user->roles) && $product->get_id() === 123) {
$price = $price * 0.8; // скидка 20%
}
}
return $price;
}Этот код нужно добавить в functions.php вашей темы или в кастомный плагин. Он не изменит цену в базе, а только на вывод и в корзине.
Как изменить цену на основе количества товара
Пример: если в корзине больше 5 единиц товара с ID 123, цена снижается на 10%:
add_filter('woocommerce_get_price', 'quantity_based_price_discount', 10, 2);
function quantity_based_price_discount($price, $product) {
if ($product->get_id() === 123) {
$cart = WC()->cart;
if (!$cart) return $price;
$quantity = 0;
foreach ($cart->get_cart() as $cart_item) {
if ($cart_item['product_id'] === 123) {
$quantity += $cart_item['quantity'];
}
}
if ($quantity > 5) {
$price = $price * 0.9;
}
}
return $price;
}Проверка результата после внедрения
- Очистите кеш сайта и браузера.
- Зайдите на страницу товара с ID 123 (замените на ваш ID) под разными пользователями (неавторизованный и с ролью wholesale_customer).
- Проверьте, что цена изменилась для оптового покупателя (уменьшилась на 20%).
- Добавьте в корзину больше 5 штук товара и проверьте, что цена автоматически снижается.
- Проверьте корректность отображения цены в корзине и на странице оформления заказа.
Частые ошибки и как их исправить
- Неверный ID товара: убедитесь, что используете правильный
$product->get_id(), а не$product->id, который устарел. - Фильтр применяется слишком рано: код нужно размещать после инициализации WooCommerce, например, в functions.php темы или в плагине с приоритетом 10.
- Отсутствие проверки корзины: если пытаетесь получить количество из корзины, убедитесь, что объект
WC()->cartсуществует, иначе будет ошибка. - Конфликты с другими плагинами: убедитесь, что другие плагины не переопределяют цену после вашего фильтра.
Практические советы по производительности и безопасности
- Не используйте тяжелые запросы в фильтре
woocommerce_get_price, он вызывается очень часто. - Кэшируйте результаты, если вычисляете цену по сложным условиям.
- Не меняйте цену напрямую в базе, чтобы избежать проблем с отчетностью и учетом.
- Используйте дочернюю тему или отдельный плагин для кастомного кода, чтобы не потерять изменения при обновлении.
Альтернативные способы и сравнительная таблица
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
Фильтр woocommerce_get_price | Изменение цены на лету через PHP-фильтр | Гибко, без плагинов, работает с любыми условиями | Нужно писать код, возможны ошибки |
| Плагины скидок (например, WooCommerce Dynamic Pricing) | Готовые решения для сложных правил цен | Удобно, широкий функционал | Платные, могут замедлять сайт |
| Вариации товаров | Создание разных цен как вариаций | Просто для нескольких вариантов | Не подходит для динамических условий |