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

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

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

Типичные задачи:

  • Изменение цены товара при выборе дополнительных опций;
  • Динамическое обновление статуса наличия при изменении количества;
  • Удаление товара из корзины и обновление цены без перезагрузки.

Как проверить, что стандартное поведение не подходит

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

Пошаговое решение: AJAX-изменение цены и наличия товара в WooCommerce

1. Добавляем обработчик AJAX в functions.php

Создаем PHP-функцию, которая будет принимать запрос, обрабатывать логику изменения цены и наличия, и возвращать JSON-ответ.

add_action('wp_ajax_update_product_info', 'update_product_info_callback');
add_action('wp_ajax_nopriv_update_product_info', 'update_product_info_callback');

function update_product_info_callback() {
    if ( ! isset($_POST['product_id']) ) {
        wp_send_json_error('Product ID missing');
    }
    $product_id = intval($_POST['product_id']);
    $product = wc_get_product($product_id);
    if (!$product) {
        wp_send_json_error('Product not found');
    }

    // Пример: изменяем цену в зависимости от переданного параметра
    $option = isset($_POST['option']) ? sanitize_text_field($_POST['option']) : '';

    $price = $product->get_price();
    $stock_status = $product->is_in_stock() ? 'instock' : 'outofstock';

    // Логика изменения цены и наличия
    if ($option === 'special') {
        $price = $price * 0.9; // скидка 10%
        $stock_status = 'instock';
    } elseif ($option === 'limited') {
        $stock_status = 'outofstock';
    }

    wp_send_json_success([
        'price' => wc_price($price),
        'stock_status' => $stock_status
    ]);
}

2. Добавляем JavaScript для отправки AJAX-запроса и обновления интерфейса

Подключаем скрипт и отправляем AJAX при смене опции. В ответе обновляем цену и статус наличия в DOM.

jQuery(document).ready(function($) {
    $('#product-option-select').on('change', function() {
        var option = $(this).val();
        var productId = $(this).data('product-id');

        $.ajax({
            url: wc_add_to_cart_params.ajax_url,
            type: 'POST',
            data: {
                action: 'update_product_info',
                product_id: productId,
                option: option
            },
            success: function(response) {
                if (response.success) {
                    $('#product-price').html(response.data.price);
                    if(response.data.stock_status === 'instock') {
                        $('#stock-status').text('В наличии').removeClass('outofstock').addClass('instock');
                    } else {
                        $('#stock-status').text('Нет в наличии').removeClass('instock').addClass('outofstock');
                    }
                } else {
                    console.error(response.data);
                }
            },
            error: function() {
                console.error('AJAX error');
            }
        });
    });
});

3. HTML-разметка примера

<select id="product-option-select" data-product-id="123">
    <option value="default">Обычная</option>
    <option value="special">Специальная</option>
    <option value="limited">Ограниченная</option>
</select>

<div id="product-price">₽1000</div>
<div id="stock-status" class="instock">В наличии</div>

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

  • При смене опции цена и статус наличия на странице меняются без перезагрузки;
  • В консоли браузера нет ошибок AJAX;
  • Если передать неверный product_id, возвращается ошибка;
  • При отключенном JavaScript изменения не происходят (нужно предусмотреть fallback).

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

  • Не подключен wp_localize_script для передачи ajax_url. Решение: добавить в enqueue скрипта wp_localize_script('script-handle', 'wc_add_to_cart_params', ['ajax_url' => admin_url('admin-ajax.php')]);.
  • Неверный product_id или пропущенный параметр в AJAX. Проверяйте наличие и типы параметров, используйте intval и sanitize_text_field.
  • Кэширование мешает обновлению цены. Очистите кэш браузера и серверный кэш, отключите плагин кэширования при тестах.
  • Отсутствие проверки nonce для безопасности. Рекомендуется добавить nonce и проверять его в обработчике AJAX.

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

  • Добавьте проверку nonce в AJAX-запросах для защиты от CSRF:
// В PHP (functions.php)
add_action('wp_enqueue_scripts', function() {
    wp_localize_script('custom-script', 'custom_ajax_obj', [
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('update_product_nonce')
    ]);
});

// В обработчике
if (!isset($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'update_product_nonce')) {
    wp_send_json_error('Invalid nonce');
}
  • Используйте минимально необходимые данные в ответах AJAX, чтобы уменьшить нагрузку.
  • Кэшируйте результаты, если логика сложная, чтобы снизить нагрузку на сервер.
  • Тестируйте совместимость с основными плагинами кэширования и оптимизации.

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

КритерийИспользование плагинаКастомный код (как в статье)
ГибкостьОграничена функционалом плагинаПолная, под любые условия
СкоростьЧаще тяжелее, из-за общего кодаОптимизированный код под задачу
БезопасностьЗависит от плагинаМожно встроить nonce и проверки
ОбновленияПлагин обновляется отдельноТребует поддержки разработчиком
Требования к навыкамМинимумТребует знаний PHP и JS
Как использовать омнинаправленные хуки в WordPress для распространённых задач
22.02.2026
Как создать и использовать промышленные поля в WordPress для настройки форм
22.02.2026
Как использовать REST API в WordPress для расширения функционала
21.11.2025
Как автоматизировать обновление контента в WordPress с помощью WPGPT
10.02.2026
Как использовать WPRemark для оценки комментариев в WordPress
06.01.2026

На оформлении, скоро здесь появится полноценный ресурс