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

Диагностика проблемы с ценами при изменении атрибутов WooCommerce

В стандартной конфигурации WooCommerce цена товара, особенно вариативного, фиксируется в вариациях и не изменяется динамически при выборе определённых атрибутов на фронтенде. Это вызывает сложности, если нужно рассчитывать цену по формуле или учитывать дополнительные параметры, влияющие на стоимость. Часто пользователи жалуются, что цена не обновляется автоматически при смене атрибутов, либо приходится создавать множество вариаций с разными ценами вручную, что неудобно и не масштабируется.

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

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

1. Создайте пользовательские поля для атрибутов

Допустим, у вас есть атрибут "Размер" и "Материал", и цена должна меняться в зависимости от выбора. Добавьте дополнительные параметры стоимости к атрибутам через пользовательские поля или отдельный массив в коде.

2. Используйте JavaScript для отслеживания выбора атрибутов

Вам нужно перехватывать событие изменения атрибутов и рассчитывать цену.

jQuery(function($) {
    $('.variations_form').on('woocommerce_variation_select_change', function() {
        let size = $('select[name="attribute_pa_size"]').val();
        let material = $('select[name="attribute_pa_material"]').val();
        let basePrice = parseFloat($('.single_variation_wrap .woocommerce-Price-amount').first().text().replace(/[^0-9.,]/g, '').replace(',', '.')) || 0;

        // Пример логики: добавляем цену за материал
        let materialPrice = 0;
        if (material === 'cotton') materialPrice = 10;
        else if (material === 'silk') materialPrice = 25;

        // Добавляем цену за размер
        let sizePrice = 0;
        if (size === 'large') sizePrice = 15;
        else if (size === 'medium') sizePrice = 7;

        let newPrice = basePrice + materialPrice + sizePrice;

        // Обновляем отображение цены
        $('.single_variation .price').html('<span class="woocommerce-Price-amount amount">' + newPrice.toFixed(2) + ' ₽</span>');
    });
});

3. Обновите цену в корзине и на сервере

Для корректного пересчёта цены при добавлении в корзину придется применить серверную обработку через фильтр woocommerce_add_cart_item_data и woocommerce_get_cart_item_from_session, чтобы сохранить пользовательские данные и цену.

add_filter('woocommerce_add_cart_item_data', 'custom_price_add_cart_item_data', 10, 3);
function custom_price_add_cart_item_data($cart_item_data, $product_id, $variation_id) {
    if (isset($_POST['attribute_pa_size']) && isset($_POST['attribute_pa_material'])) {
        // Формируем дополнительную цену
        $extra_price = 0;
        $material = sanitize_text_field($_POST['attribute_pa_material']);
        $size = sanitize_text_field($_POST['attribute_pa_size']);

        if ($material === 'cotton') $extra_price += 10;
        elseif ($material === 'silk') $extra_price += 25;

        if ($size === 'large') $extra_price += 15;
        elseif ($size === 'medium') $extra_price += 7;

        $cart_item_data['custom_price'] = $extra_price;
    }
    return $cart_item_data;
}

add_filter('woocommerce_get_cart_item_from_session', 'custom_price_get_cart_item_from_session', 20, 2);
function custom_price_get_cart_item_from_session($cart_item, $values) {
    if (isset($values['custom_price'])) {
        $cart_item['custom_price'] = $values['custom_price'];
    }
    return $cart_item;
}

add_action('woocommerce_before_calculate_totals', 'custom_price_before_calculate_totals');
function custom_price_before_calculate_totals($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;

    foreach ($cart->get_cart() as $cart_item) {
        if (isset($cart_item['custom_price'])) {
            $original_price = $cart_item['data']->get_price(false);
            $new_price = $original_price + $cart_item['custom_price'];
            $cart_item['data']->set_price($new_price);
        }
    }
}

Проверка результата после внедрения

  1. Откройте страницу вариативного товара, выберите разные атрибуты и убедитесь, что цена меняется динамически на фронтенде без перезагрузки.
  2. Добавьте товар в корзину с разными комбинациями атрибутов и проверьте, что в корзине и на странице оформления заказа цена соответствует выбранным параметрам.
  3. Проверьте, что цена сохраняется в сессии и корректно отображается при переходе между страницами.

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

  • Цена не обновляется на фронтенде: Проверьте, что скрипт подключён и что селекторы атрибутов соответствуют вашим названиям (проверяйте в инспекторе браузера).
  • Цена сбрасывается при добавлении в корзину: Убедитесь, что данные о дополнительной цене передаются через POST и сохраняются в сессии через фильтры WooCommerce.
  • Пересчет цены не происходит в AJAX-обновлениях корзины: Добавьте обработку хука woocommerce_before_calculate_totals именно с проверкой на админку и AJAX.
  • Некорректное форматирование цены: Используйте функции WooCommerce для форматирования, например, wc_price(), чтобы поддерживать валюту и локализацию.

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

  • Санитизируйте все входящие данные, особенно данные из $_POST, чтобы избежать XSS и инъекций.
  • Минимизируйте количество запросов и сложную логику в JavaScript, чтобы не замедлять загрузку страницы.
  • Если логика расчёта цены сложная, рассмотрите перенос части вычислений на сервер с использованием AJAX-запросов, чтобы не раскрывать бизнес-логику на клиенте.
  • Кэшируйте результаты, если цена зависит от внешних данных, чтобы уменьшить нагрузку.

Сравнение подходов: Плагин vs Кастомный код

КритерийПлагинКастомный кодКомпромисс
ГибкостьОграничена настройкамиПолная свободаТребуется поддержка
Скорость разработкиБыстроДольшеЗависит от навыков
ПроизводительностьМожет быть избыточнойОптимальнаОптимизация нужна
БезопасностьЗависит от плагинаЗависит от реализацииТестирование обязательно
ОбновленияАвтоматическиеРучныеКонтроль качества кода
Как добавить динамические атрибуты товара в WooCommerce с примерами кода
01.05.2026
Автоматическое удаление старых записей в WordPress через WP-Cron
10.01.2026
Как создать динамическое меню в WordPress с примерами кода
03.04.2026
Как отключить автоматическое обновление WooCommerce без переопределения файлов
09.05.2026
Как создать успешный плагин для WordPress: практические советы и примеры кода
01.01.2026