Диагностика задачи: зачем менять цену товара по атрибутам
В WooCommerce часто возникает необходимость автоматически корректировать цену товара в зависимости от выбранных пользователем атрибутов. Например, у футболки с разными размерами и цветами цена может варьироваться. В стандартном WooCommerce для вариативных товаров цены задаются вручную, но если нужно динамически менять цену на основе атрибутов, потребуется кастомный код.
Как WooCommerce работает с ценами вариаций и атрибутов
Вариации — отдельные товарные позиции с собственными ценами. Атрибуты — свойства товара, которые могут быть вариациями или просто фильтрами. По умолчанию цена вариации фиксирована и задаётся в админке. Для динамического изменения цены нам нужно перехватить процесс формирования цены на фронтенде и при добавлении в корзину.
Основные хуки для изменения цены товара
woocommerce_product_get_price— фильтр для изменения цены товара.woocommerce_before_calculate_totals— действие для корректировки цены в корзине.
Пошаговое решение: динамическая корректировка цены по атрибутам
Рассмотрим пример, когда цена футболки увеличивается на 10% при выборе размера XL и на 5% при выборе цвета красный.
1. Определяем атрибуты и их влияние на цену
В нашем примере:
- Размер (pa_size): XL — +10%
- Цвет (pa_color): красный — +5%
2. Добавляем фильтр для изменения цены на странице товара
add_filter('woocommerce_product_get_price', 'custom_dynamic_price_by_attributes', 10, 2);
function custom_dynamic_price_by_attributes($price, $product) {
if (!$product->is_type('variation')) {
return $price;
}
$attributes = $product->get_attributes();
$variation_attributes = $product->get_variation_attributes();
// Получаем атрибуты вариации
$size = isset($variation_attributes['attribute_pa_size']) ? $variation_attributes['attribute_pa_size'] : '';
$color = isset($variation_attributes['attribute_pa_color']) ? $variation_attributes['attribute_pa_color'] : '';
$new_price = $price;
if ($size === 'xl') {
$new_price *= 1.1; // +10%
}
if ($color === 'red') {
$new_price *= 1.05; // +5%
}
return round($new_price, 2);
}3. Корректируем цену в корзине перед подсчётом итогов
add_action('woocommerce_before_calculate_totals', 'custom_dynamic_price_cart', 20, 1);
function custom_dynamic_price_cart($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
$product = $cart_item['data'];
if (!$product->is_type('variation')) continue;
$variation_attributes = $product->get_variation_attributes();
$price = $product->get_regular_price();
$size = isset($variation_attributes['attribute_pa_size']) ? $variation_attributes['attribute_pa_size'] : '';
$color = isset($variation_attributes['attribute_pa_color']) ? $variation_attributes['attribute_pa_color'] : '';
$new_price = $price;
if ($size === 'xl') {
$new_price *= 1.1;
}
if ($color === 'red') {
$new_price *= 1.05;
}
$cart_item['data']->set_price(round($new_price, 2));
}
}Проверка результата после внедрения
- Перейдите на страницу вариативного товара.
- Выберите комбинацию атрибутов, например, размер XL и цвет красный.
- Цена должна автоматически пересчитываться с учётом наценок.
- Добавьте товар в корзину и проверьте итоговую стоимость там — она должна совпадать с отображаемой на странице товара.
Частые ошибки и как их исправить
- Цена не меняется на странице товара: убедитесь, что фильтр
woocommerce_product_get_priceподключён и срабатывает для вариаций. - В корзине цена не изменяется: проверьте действие
woocommerce_before_calculate_totalsи убедитесь, что цена задаётся черезset_price(). - Некорректные ключи атрибутов: используйте правильные имена атрибутов с префиксом
attribute_pa_, например,attribute_pa_size. - Изменения цены не видны из-за кэша: очистите кэш сайта и браузера.
Практические советы по производительности и безопасности
- Не используйте тяжелые запросы к базе данных внутри хуков изменения цены — все данные должны быть доступны из объекта товара.
- Кешируйте результаты сложных вычислений, если цена зависит от внешних источников.
- Избегайте прямого изменения базовых цен товаров — используйте только фильтры и действия WooCommerce для динамики.
Сравнение вариантов реализации динамической цены
| Метод | Плюсы | Минусы | Подходит для |
|---|---|---|---|
| Стандартные вариации WooCommerce | Простота, поддержка интерфейса, совместимость | Требуется ручное задание цен для каждой вариации | Небольшое количество вариаций |
| Кастомный код на хуках цены | Гибкость, автоматизация, динамическое ценообразование | Требует навыков PHP, возможны баги при обновлениях | Большое количество комбинаций, динамические правила |
| Плагины для динамических цен | Готовые решения, удобный интерфейс | Зависимость от стороннего ПО, дополнительные расходы | Быстрая реализация без разработки |