WooCommerce: как автоматически менять стоимость товара при изменении атрибутов

Проблема: стоимость товара не обновляется при выборе разных атрибутов

В WooCommerce часто возникает задача динамически изменять цену товара в зависимости от выбранных пользователем атрибутов, например, цвета или размера. По умолчанию, если используются простые товары с вариациями, цена меняется автоматически. Но если товар настроен как один простой товар с атрибутами, цена не меняется, что вводит пользователя в заблуждение и снижает конверсию.

Диагностика проблемы

Чтобы понять, почему цена не меняется, проверьте следующее:

  • Тип товара — это simple с атрибутами или variable с вариациями?
  • Если это простой товар с атрибутами, то WooCommerce не умеет менять цену автоматически без доработок.
  • Нет ли плагинов, которые блокируют обновление цены через AJAX?
  • Проверить консоль браузера на наличие ошибок JavaScript при смене атрибутов.

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

Задача: при выборе пользователем атрибута на странице товара менять цену на соответствующую.

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

В метаданных товара или через отдельный массив в коде прописываем соответствие атрибутов и цен:

add_action('woocommerce_before_add_to_cart_button', function() {
    global $product;
    // Пример: цены для атрибута "color"
    $prices_for_attributes = [
        'red' => 1200,
        'blue' => 1300,
        'green' => 1100,
    ];
    ?>
    <script>
    jQuery(function($) {
        var prices = <?php echo json_encode($prices_for_attributes); ?>;
        $('#pa_color').on('change', function() {
            var selected = $(this).val();
            if(prices[selected]) {
                $('.woocommerce-Price-amount.amount').text(prices[selected] + ' ₽');
            }
        });
    });
    </script>
    <?php
});

Здесь #pa_color — ID селектора атрибута цвета. Не забудьте заменить на актуальный ID вашего атрибута.

2. Обновление цены при смене атрибута на фронтенде

В приведенном скрипте мы слушаем событие изменения селектора атрибута и меняем текст с ценой в блоке отображения цены товара.

Если у вас несколько атрибутов, нужно расширить логику суммирования или выбора нужной цены.

3. Обновление цены при добавлении товара в корзину и в админке

Чтобы цена сохранялась и учитывалась при оформлении заказа, необходимо изменить цену перед добавлением в корзину:

add_filter('woocommerce_add_cart_item_data', function($cart_item_data, $product_id, $variation_id) {
    if (isset($_POST['attribute_pa_color'])) {
        $color = sanitize_text_field($_POST['attribute_pa_color']);
        $prices_for_attributes = [
            'red' => 1200,
            'blue' => 1300,
            'green' => 1100,
        ];
        if (isset($prices_for_attributes[$color])) {
            $cart_item_data['custom_price'] = $prices_for_attributes[$color];
        }
    }
    return $cart_item_data;
}, 10, 3);

add_action('woocommerce_before_calculate_totals', function($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;
    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        if (isset($cart_item['custom_price'])) {
            $cart_item['data']->set_price($cart_item['custom_price']);
        }
    }
});

Этот код берет цену из выбранного атрибута и устанавливает ее в объект товара в корзине, что гарантирует правильный расчет итогов.

Проверка результата

  • На странице товара выберите разные значения атрибута — цена должна меняться без перезагрузки.
  • Добавьте товар в корзину с выбранным атрибутом — в корзине и на оформлении заказа цена должна совпадать с выбранной.
  • В админке заказа проверьте, что цена правильная.
  • Проверьте консоль браузера и логи сервера на отсутствие ошибок.

Частые ошибки и их исправления

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

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

  • Код изменения цены лучше размещать в дочерней теме или кастомном плагине, чтобы сохранить изменения при обновлениях.
  • Используйте sanitize_text_field для любых данных из форм во избежание XSS.
  • Минимизируйте количество JavaScript и интегрируйте его через отдельный файл для кэширования и удобства поддержки.
  • Если атрибутов много, рассмотрите реализацию через вариации товаров — это штатный механизм WooCommerce для динамических цен.

Сравнение подходов изменения цены по атрибутам

МетодПреимуществаНедостатки
Использование вариаций WooCommerceСтандартный функционал, динамическая цена, поддержка складского учетаСложнее в настройке, может перегрузить админку при большом количестве вариаций
Кастомный скрипт и фильтры для простого товараГибкость, меньше затрат ресурсов, подходит для небольших наборов атрибутовТребует кастомной разработки, возможны ошибки при обновлениях WooCommerce
Плагины для кастомных цен по атрибутамБыстрая установка, поддержка и обновленияДополнительная нагрузка, зависимость от стороннего кода, плата за лицензии

Сервис определения шаблона и плагинов на сайте