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

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

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

Типичные проблемы при реализации

  • Изменения в корзине не применяются сразу — требуется ручная перезагрузка страницы.
  • Отсутствие синхронизации между фронтендом и сервером, из-за чего данные корзины расходятся.
  • Ошибки при работе с AJAX, связанные с неправильной обработкой nonce или хуков WooCommerce.
  • Потеря данных сессии при неверной работе с куками и ajax-запросами.

Пошаговое решение: автоматическое изменение корзины через AJAX

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

Для начала нужно создать PHP-функцию, которая будет обрабатывать AJAX-запросы и изменять корзину:

add_action('wp_ajax_update_cart_items', 'update_cart_items_callback');
add_action('wp_ajax_nopriv_update_cart_items', 'update_cart_items_callback');

function update_cart_items_callback() {
    if ( ! isset($_POST['nonce']) || ! wp_verify_nonce($_POST['nonce'], 'update_cart_nonce') ) {
        wp_send_json_error('Неверный nonce');
        wp_die();
    }

    // Получаем текущую корзину
    $cart = WC()->cart;

    // Условие: если сумма корзины больше 5000, добавляем подарок
    if ( $cart->subtotal > 5000 ) {
        $gift_product_id = 123; // ID подарочного товара
        $found = false;
        foreach ( $cart->get_cart() as $cart_item_key => $values ) {
            if ( $values['product_id'] == $gift_product_id ) {
                $found = true;
                break;
            }
        }
        if ( ! $found ) {
            $cart->add_to_cart( $gift_product_id );
        }
    } else {
        // Удаляем подарок, если сумма меньше
        foreach ( $cart->get_cart() as $cart_item_key => $values ) {
            if ( $values['product_id'] == 123 ) {
                $cart->remove_cart_item( $cart_item_key );
            }
        }
    }

    // Принудительное перерасчитывание
    $cart->calculate_totals();

    wp_send_json_success(array('message' => 'Корзина обновлена'));
    wp_die();
}

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

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

jQuery(document).ready(function($) {
    function updateCart() {
        $.ajax({
            url: wc_cart_params.ajax_url,
            type: 'POST',
            data: {
                action: 'update_cart_items',
                nonce: wc_cart_params.update_cart_nonce
            },
            success: function(response) {
                if(response.success) {
                    // Обновляем фрагменты корзины WooCommerce
                    $(document.body).trigger('wc_fragment_refresh');
                    console.log(response.data.message);
                } else {
                    console.error('Ошибка: ' + response.data);
                }
            },
            error: function() {
                console.error('AJAX запрос не удался');
            }
        });
    }

    // Запускаем обновление корзины при изменении количества товаров
    $(document.body).on('updated_wc_div', function() {
        updateCart();
    });

    // Или вызывайте updateCart() по другим событиям, например, клике по кнопке
});

3. Передаем nonce и локализуем скрипт

В functions.php добавляем локализацию скрипта, чтобы передать nonce и ajax_url:

function enqueue_custom_cart_script() {
    wp_enqueue_script('custom-cart-js', get_template_directory_uri() . '/js/custom-cart.js', array('jquery'), '1.0', true);
    wp_localize_script('custom-cart-js', 'wc_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_cart_script');

Как проверить, что решение работает

  • Добавьте товары в корзину так, чтобы сумма превысила 5000 — подарок должен автоматически добавиться.
  • Уменьшите сумму ниже 5000 — подарок должен автоматически удалиться.
  • Отслеживайте консоль браузера на предмет ошибок AJAX.
  • Проверьте, что обновляются фрагменты корзины без полной перезагрузки страницы.

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

  • Ошибка nonce: Убедитесь, что nonce передается и проверяется корректно. Если AJAX возвращает ошибку, проверьте wp_localize_script и wp_verify_nonce.
  • Корзина не обновляется на фронтенде: Вызовите $(document.body).trigger('wc_fragment_refresh'); после успешного AJAX, чтобы обновить видимые данные корзины.
  • Подарок добавляется несколько раз: Проверьте логику проверки наличия подарка в корзине перед добавлением.
  • Ошибка 500 или другие серверные ошибки: Проверьте логи сервера, убедитесь, что ID товара правильный и он доступен для покупки.

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

  • Не забывайте использовать wp_verify_nonce для защиты от CSRF при обработке AJAX.
  • Минимизируйте количество AJAX запросов — запускайте обновление корзины только при реальных изменениях.
  • Используйте кеширование WooCommerce фрагментов, чтобы не нагружать сервер лишними рендерами.
  • Проверяйте права пользователя, если изменения корзины должны быть доступны только авторизованным.

Сравнение подходов изменения корзины

МетодПлюсыМинусы
Изменение корзины через обычный PHP (без AJAX)Простота реализации,
не требует JS
Перезагрузка страницы,
хуже UX
Изменение корзины через AJAX и хуки WooCommerceДинамическое обновление без перезагрузки,
лучший UX
Сложнее в реализации,
требует JS и проверки nonce
Использование плагинов для автоматизации корзиныБыстрая настройка,
набор готовых функций
Зависимость от стороннего кода,
меньше контроля
WooCommerce: автоматическое отключение товаров при отсутствии наличия
04.06.2026
Как создать динамические формы в WordPress с помощью AJAX
23.12.2025
Как использовать REST API в WordPress для расширения функционала
21.11.2025
Как автоматизировать удаление старого контента в WordPress
25.02.2026
Как отключить REST API в WordPress без плагинов
07.12.2025

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