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

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

В WooCommerce по умолчанию изменение атрибутов (например, цвет, размер) на странице товара не всегда приводит к автоматическому изменению цены, если не настроены вариации или кастомная логика. Это вызывает у пользователей путаницу и снижает конверсию. Как реализовать автоматическое обновление цены при выборе атрибутов без использования вариаций?

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

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

Проверьте, что атрибуты добавлены как пользовательские, а не для вариаций:

  • В админке: Товар → Атрибуты → убедитесь, что атрибуты не связаны с вариациями.
  • Страница редактирования товара → Атрибуты → флажок «Использовать для вариаций» не установлен.

Проверка консоли браузера

При выборе атрибутов в консоли разработчика (F12) не должно быть ошибок JavaScript.

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

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

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

1. Добавляем метаполе для хранения цены по атрибутам

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

add_action('woocommerce_process_product_meta', 'save_custom_attribute_prices');
function save_custom_attribute_prices($post_id) {
    if (isset($_POST['custom_attr_prices']) && is_array($_POST['custom_attr_prices'])) {
        update_post_meta($post_id, '_custom_attr_prices', $_POST['custom_attr_prices']);
    }
}

В админке можно добавить кастомное поле, например, JSON с ценами для каждого атрибута.

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

Пример скрипта в footer.php или подключаемом JS-файле темы:

jQuery(document).ready(function($){
    $('.variations_form select').on('change', function(){
        var data = {};
        $('.variations_form select').each(function(){
            data[$(this).attr('name')] = $(this).val();
        });
        var product_id = $('.variations_form').data('product_id');
        $.ajax({
            url: wc_add_to_cart_params.ajax_url,
            type: 'POST',
            data: {
                action: 'get_custom_price',
                product_id: product_id,
                attributes: data
            },
            success: function(response) {
                if(response.success) {
                    $('.woocommerce-Price-amount.amount').text(response.data.price_html);
                }
            }
        });
    });
});

3. Создаем обработчик AJAX на PHP

add_action('wp_ajax_get_custom_price', 'get_custom_price_callback');
add_action('wp_ajax_nopriv_get_custom_price', 'get_custom_price_callback');

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

    $prices = get_post_meta($product_id, '_custom_attr_prices', true);
    if (!$prices || !is_array($prices)) {
        wp_send_json_error(['message' => 'Цены не найдены']);
    }

    // Предположим, что $prices — массив вида ['color_red' => 1500, 'color_blue' => 1700]
    // Получаем ключ из выбранных атрибутов
    $price_key = '';
    foreach ($attributes as $key => $value) {
        $price_key .= $key . '_' . $value . '_';
    }
    $price_key = rtrim($price_key, '_');

    if (isset($prices[$price_key])) {
        $price = wc_price($prices[$price_key]);
        wp_send_json_success(['price_html' => $price]);
    } else {
        wp_send_json_error(['message' => 'Цена для выбранных атрибутов не задана']);
    }
    wp_die();
}

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

  • Перейдите в карточку товара и выберите различные атрибуты.
  • Цена должна мгновенно обновляться без перезагрузки.
  • В консоли браузера не должно быть ошибок.
  • При неправильных атрибутах возвращается сообщение об ошибке (можно улучшить UX).

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

  • Ошибка: AJAX запрос не работает.
    Причина: Не подключен wc_add_to_cart_params.ajax_url или неправильно оформлен JS.
    Решение: Проверьте подключение WooCommerce скриптов и используйте wp_enqueue_script с зависимостью от wc-add-to-cart.
  • Ошибка: Не обновляется цена.
    Причина: Неверный ключ для поиска цены в массиве.
    Решение: Проверьте формирование ключа, убедитесь, что имена атрибутов и значений совпадают с метаданными.
  • Ошибка: Нет цены для выбранных атрибутов.
    Причина: Отсутствуют данные в метаполе.
    Решение: Добавьте цены для всех необходимых комбинаций атрибутов.

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

  • Кэшируйте результаты AJAX запросов при большом количестве пользователей, чтобы снизить нагрузку на базу данных.
  • Используйте wp_verify_nonce для проверки подлинности AJAX запросов.
  • Убедитесь, что метаполя хранят цены в формате целых чисел (копейки) для точности и быстрого сравнения.
  • Минимизируйте JS и используйте события делегирования для повышения производительности.

Сравнение способов реализации

МетодПлюсыМинусы
Использование вариаций WooCommerceСтандартная функциональность, автоматическое обновление цены, поддержка складского учетаСложно при большом количестве комбинаций, больше нагрузки на базу
Кастомный AJAX для изменения цены по атрибутамГибкость, легко кастомизировать, подходит для нестандартных сценариевТребует дополнительной разработки и поддержки, возможны ошибки в логике
Плагины для динамических ценГотовые решения, поддержка и обновленияМогут быть платными, избыточны для простых задач
WooCommerce: как использовать хуки для добавления пользовательских полей в форму оформления заказа
18.05.2026
Отключение комментариев в REST API WordPress: пошаговое руководство
27.01.2026
Как использовать AJAX в WordPress для отправки формы без перезагрузки страницы
07.01.2026
Как отключить Gutenberg и вернуть классический редактор в WordPress
17.02.2026
Как автоматически удалять черновики старше 30 дней в WordPress
25.03.2026