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

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

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

Типичные проблемы:

  • Необходимость менять цену без создания вариаций
  • Стандартные вариации оказываются слишком тяжелыми для админки
  • Цена не обновляется на фронтенде при изменении атрибутов

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

1. Добавляем пользовательский JavaScript для отслеживания изменений атрибутов

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

jQuery(document).ready(function($) {
    $('form.variations_form').on('change', 'select', function() {
        var attributes = {};
        $('form.variations_form select').each(function() {
            var name = $(this).attr('name');
            var val = $(this).val();
            if(val) {
                attributes[name] = val;
            }
        });

        var product_id = $('form.variations_form').data('product_id');

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

2. Создаем обработчик AJAX на стороне сервера

В functions.php темы или в плагине добавляем следующий код:

add_action('wp_ajax_custom_get_dynamic_price', 'custom_get_dynamic_price_callback');
add_action('wp_ajax_nopriv_custom_get_dynamic_price', 'custom_get_dynamic_price_callback');

function custom_get_dynamic_price_callback() {
    if ( empty($_POST['product_id']) || empty($_POST['attributes']) || !is_array($_POST['attributes']) ) {
        wp_send_json_error('Invalid data');
    }

    $product_id = intval($_POST['product_id']);
    $attributes = $_POST['attributes'];

    $product = wc_get_product($product_id);
    if (!$product) {
        wp_send_json_error('Product not found');
    }

    // Логика расчёта цены по выбранным атрибутам
    // Пример: если выбран атрибут 'pa_color' == 'red', добавляем 100 рублей
    $price = $product->get_regular_price();

    if (isset($attributes['attribute_pa_color'])) {
        if ($attributes['attribute_pa_color'] === 'red') {
            $price += 100;
        }
        if ($attributes['attribute_pa_color'] === 'blue') {
            $price += 50;
        }
    }

    // Можно добавить другую логику для разных атрибутов

    $price_html = wc_price($price);

    wp_send_json_success(array('price_html' => $price_html));
}

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

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

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

  • Не работает AJAX-запрос: проверьте, что wc_add_to_cart_params.ajax_url определён и правильный. Если нет — подключите скрипт с wp_localize_script.
  • Цена не меняется: убедитесь, что селекты имеют правильные имена атрибутов, например, attribute_pa_color, а не просто color.
  • Ошибка 400 или 500 в ответе сервера: проверьте в PHP логи ошибки, возможно, неверный формат данных или не найдена переменная.
  • Кэширование мешает обновлению цены: отключите кэширование на странице товара или добавьте AJAX-запросы в исключения.
  • Цена не соответствует логике: проверьте правильность ключей и значений в массиве атрибутов и логику расчёта.

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

  • Проверяйте и фильтруйте входящие данные в AJAX-обработчике, используйте sanitize_text_field и intval.
  • Добавьте nonce для защиты AJAX-запросов от CSRF-атак.
  • Минимизируйте количество AJAX-запросов — добавьте debounce на JS, чтобы не отправлять запрос при каждом изменении мгновенно.
  • Кэшируйте результат расчёта цены, если логика сложная и повторяется часто.
  • Используйте хук woocommerce_before_calculate_totals для применения динамической цены к корзине, если нужно учесть изменения в заказе.

Сравнение вариантов реализации

МетодПлюсыМинусы
Создание вариаций в WooCommerceСтандартная функциональность, поддержка цены и стоковМного вариаций усложняют админку, нагрузка на БД
Динамическое изменение цены через AJAX и кодГибкая логика, меньше вариаций, удобство для сложных правилТребует программирования, может быть сложнее для поддержки
Использование плагинов для динамических ценГотовые решения, поддержка и обновленияЦена плагина, ограниченная кастомизация
WooCommerce: автоматическое изменение цены товара при изменении атрибутов
19.07.2026
Автоматическое удаление записей и метаданных при удалении пользователя в WordPress
22.04.2026
WooCommerce: как автоматически изменять статус заказа при автоматическом возврате денег
04.06.2026
Как использовать PHPStan для анализа кода WordPress: практическое руководство
05.02.2026
Как создать собственный виджет в WordPress: подробное руководство с примерами кода
18.11.2025