WooCommerce: правильная настройка AJAX callback для обновления корзины без перезагрузки

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

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

Основные причины проблемы:

  • Отсутствие правильной регистрации AJAX-обработчиков в WordPress.
  • Некорректное использование нонсов для безопасности.
  • Пропущенный вызов функции WC_AJAX::get_refreshed_fragments() для обновления HTML-фрагментов корзины.
  • Конфликты с кэшированием на стороне сервера или браузера.
  • Несоответствие хуков и вызовов AJAX для авторизованных и неавторизованных пользователей (wp_ajax_ и wp_ajax_nopriv_).

Пошаговое решение: как правильно реализовать AJAX callback обновления корзины

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

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

jQuery(function($){
    $('body').on('change', '.qty', function(){
        var product_id = $(this).data('product_id');
        var quantity = $(this).val();
        $.ajax({
            url: wc_add_to_cart_params.ajax_url,
            type: 'POST',
            data: {
                action: 'update_cart_quantity',
                product_id: product_id,
                quantity: quantity,
                security: wc_add_to_cart_params.update_cart_nonce
            },
            success: function(response) {
                if(response.fragments) {
                    $.each(response.fragments, function(key, value) {
                        $(key).replaceWith(value);
                    });
                }
            },
            error: function() {
                console.log('Ошибка AJAX обновления корзины');
            }
        });
    });
});

2. Регистрируем AJAX обработчик в PHP

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

add_action('wp_ajax_update_cart_quantity', 'custom_update_cart_quantity');
add_action('wp_ajax_nopriv_update_cart_quantity', 'custom_update_cart_quantity');

function custom_update_cart_quantity() {
    check_ajax_referer('update-cart-nonce', 'security');

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

    if ($product_id && $quantity >= 0) {
        $cart = WC()->cart;
        foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
            if ($cart_item['product_id'] === $product_id) {
                if ($quantity === 0) {
                    $cart->remove_cart_item($cart_item_key);
                } else {
                    $cart->set_quantity($cart_item_key, $quantity, true);
                }
                break;
            }
        }

        WC()->cart->calculate_totals();

        // Возвращаем обновленные фрагменты корзины
        wp_send_json_success(array(
            'fragments' => WC_AJAX::get_refreshed_fragments(),
        ));
    }

    wp_send_json_error();
}

3. Локализация скрипта и передача nonce

Чтобы передать nonce и URL AJAX, добавьте в functions.php:

function enqueue_custom_scripts() {
    wp_enqueue_script('custom-cart-update', get_template_directory_uri() . '/js/custom-cart-update.js', array('jquery'), '1.0', true);

    wp_localize_script('custom-cart-update', 'wc_add_to_cart_params', array(
        'ajax_url' => admin_url('admin-ajax.php'),
        'update_cart_nonce' => wp_create_nonce('update-cart-nonce'),
    ));
}
add_action('wp_enqueue_scripts', 'enqueue_custom_scripts');

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

1. Откройте страницу корзины, откройте консоль браузера (F12 → Console).

2. Измените количество товара в поле .qty. Должен отправиться AJAX-запрос (проверьте вкладку Network).

3. После успешного ответа корзина должна обновиться без перезагрузки — изменится количество и итоговая сумма.

4. Если возникают ошибки, проверьте консоль на наличие сообщений и логи сервера.

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

  • Ошибка "0" или пустой ответ AJAX: скорее всего, не передан nonce или он не проверяется. Проверьте правильность check_ajax_referer и локализацию nonce.
  • Обновление страницы происходит, но корзина не меняется: убедитесь, что используете WC_AJAX::get_refreshed_fragments(), иначе обновленные HTML-фрагменты не возвращаются.
  • Изменения видны только после перезагрузки: проверьте кэширование, отключите плагин кэша для теста.
  • ajax_url не определен или неправильный: проверьте, что локализация скрипта происходит после регистрации и подключения скрипта.

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

  • Используйте nonce для защиты AJAX запросов от CSRF.
  • Обрабатывайте только валидные и ожидаемые данные, фильтруйте входящие переменные.
  • Минимизируйте объем возвращаемых данных — используйте только необходимые фрагменты.
  • Кэшируйте фронтенд-скрипты и стили с правильными версиями, чтобы избежать конфликтов.
  • Тестируйте на разных ролях пользователей (авторизованные и нет).

Сравнение способов обновления корзины через AJAX

МетодОписаниеПреимуществаНедостатки
Использование WC_AJAX::get_refreshed_fragments()Стандартный метод WooCommerce для возврата обновленных блоков корзиныСовместимость, простота, обновляет все необходимые элементыЗависит от внутреннего механизма WooCommerce
Самостоятельная генерация HTMLВозврат собственных HTML-фрагментов корзиныГибкость, можно изменить структуруСложность, риск неотображения важных элементов
Перезагрузка всей страницыОбновление корзины классическим способомПростота реализацииПлохой UX, медленное обновление
WooCommerce: как добавить собственные поля в форму оформления заказа
28.05.2026
WooCommerce: не отображаются товары после обновления — как быстро исправить
20.05.2026
Как автоматически отслеживать изменения в записях WordPress
24.02.2026
Как создать динамический список постов с фильтром в WordPress
27.12.2025
WooCommerce: как изменить шаблон письма при подтверждении заказа
12.05.2026