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

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

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

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

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

Для начала нужно перехватить событие изменения атрибутов на странице товара и выполнить AJAX-запрос для получения обновлённой цены.

jQuery(document).ready(function($) {
    $('.variations_form').on('woocommerce_variation_select_change', function() {
        var form = $(this);
        var data = form.serialize();

        $.ajax({
            url: wc_add_to_cart_params.ajax_url,
            type: 'POST',
            data: {
                action: 'get_dynamic_price',
                data: data,
                product_id: form.data('product_id')
            },
            success: function(response) {
                if(response.success) {
                    $('.woocommerce-variation-price .price').html(response.data.price_html);
                }
            }
        });
    });
});

2. Обработка AJAX-запроса на сервере

В functions.php темы или в кастомном плагине нужно добавить обработчик AJAX, который будет вычислять цену с учётом выбранных атрибутов.

add_action('wp_ajax_get_dynamic_price', 'get_dynamic_price_callback');
add_action('wp_ajax_nopriv_get_dynamic_price', 'get_dynamic_price_callback');

function get_dynamic_price_callback() {
    parse_str($_POST['data'], $form_data);
    $product_id = intval($_POST['product_id']);

    if (!$product_id) {
        wp_send_json_error();
    }

    $product = wc_get_product($product_id);
    if (!$product) {
        wp_send_json_error();
    }

    // Формируем массив выбранных атрибутов
    $selected_attributes = [];
    foreach ($form_data as $key => $value) {
        if (strpos($key, 'attribute_') === 0) {
            $selected_attributes[$key] = sanitize_text_field($value);
        }
    }

    // Получаем вариацию по выбранным атрибутам
    $variation_id = find_matching_product_variation($product, $selected_attributes);
    if (!$variation_id) {
        wp_send_json_error();
    }

    $variation = wc_get_product($variation_id);
    if (!$variation) {
        wp_send_json_error();
    }

    $price_html = $variation->get_price_html();
    wp_send_json_success(['price_html' => $price_html]);
}

// Функция поиска вариации по атрибутам
function find_matching_product_variation($product, $selected_attrs) {
    if (!$product->is_type('variable')) {
        return false;
    }

    $available_variations = $product->get_available_variations();
    foreach ($available_variations as $variation) {
        $match = true;
        foreach ($selected_attrs as $attr_name => $attr_value) {
            $key = str_replace('attribute_', '', $attr_name);
            if (!isset($variation['attributes']['attribute_' . $key]) || $variation['attributes']['attribute_' . $key] !== $attr_value) {
                $match = false;
                break;
            }
        }
        if ($match) {
            return $variation['variation_id'];
        }
    }
    return false;
}

3. Внедрение кода в тему

JS можно подключить через enqueue_script в functions.php:

function enqueue_dynamic_price_script() {
    if (is_product()) {
        wp_enqueue_script('dynamic-price', get_stylesheet_directory_uri() . '/js/dynamic-price.js', ['jquery'], '1.0', true);
        wp_localize_script('dynamic-price', 'wc_add_to_cart_params', [
            'ajax_url' => admin_url('admin-ajax.php'),
        ]);
    }
}
add_action('wp_enqueue_scripts', 'enqueue_dynamic_price_script');

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

  • Откройте страницу товара с вариациями.
  • Выберите разные комбинации атрибутов.
  • Цена должна мгновенно обновляться без перезагрузки страницы.
  • Если цена не меняется, проверьте консоль браузера на ошибки JS и ответ от AJAX.

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

  • Цена не обновляется при выборе атрибута: Проверьте, что событие woocommerce_variation_select_change срабатывает. Если нет, измените селектор или используйте change на select.
  • AJAX возвращает ошибку 400 или 500: Убедитесь, что передаются все необходимые данные и что PHP-функция корректно обрабатывает запрос (используйте error_log для отладки).
  • Неверная цена или пустая: Проверьте, что функция поиска вариации корректно сопоставляет выбранные атрибуты и что вариации действительно существуют в WooCommerce.
  • Конфликты с другими плагинами: Отключите сторонние плагины, которые могут влиять на вариации или AJAX-запросы.

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

  • Всегда используйте sanitize_text_field и проверки типов для входящих данных в AJAX-обработчиках.
  • Кешируйте результат поиска вариации, если на сайте много трафика, чтобы снизить нагрузку.
  • Минимизируйте количество и вес JS-скриптов, чтобы не замедлять загрузку страницы.
  • Проверяйте, что обновление цены не ломает стандартный процесс добавления в корзину.

Сравнение способов динамического изменения цены

СпособПлюсыМинусыПрименимость
Создание вариаций вручнуюСтандартно, полностью поддерживается WooCommerceБольшое количество вариаций, сложности с управлениемМного вариаций с фиксированными ценами
Плагины динамического ценообразования (например, WooCommerce Dynamic Pricing)Большой функционал, готовые решенияСтоимость, возможные конфликтыСложные правила ценообразования
Кастомный код с AJAX (описанный метод)Гибкость, контроль, лёгкость, отсутствие доп. расходовТребует навыков разработки, поддержка кодаСредние проекты, уникальные сценарии
Как использовать хуки и фильтры WordPress для автоматизации задач
25.01.2026
Как добавить автоматическое обновление цен в WooCommerce при изменении атрибутов
24.04.2026
Как использовать фильтр pre_get_posts для правильной работы пагинации на страницах архива в WordPress
18.05.2026
Автоматическое создание Sitemap XML в WordPress: практическое руководство
15.02.2026
Как создать свой шорткод в WordPress с примером кода
06.11.2025