WPBono

Как отключить отложенные товары в корзине WooCommerce при изменении остатков

Сценарий типичный для магазина с живым складом: клиент добавил товар в корзину, потом остаток изменился, а на checkout товар уже недоступен или доступен не в том количестве. В результате появляются ошибки оформления, лишние возвраты к корзине и вопросы в поддержку. Если у вас включено управление запасами в WooCommerce, это можно обработать без тяжелых костылей — на этапе обновления корзины и перед оформлением заказа.

Когда проблема действительно возникает

Чаще всего это видно в магазинах с синхронизацией из 1С, МойСклад, ERP или просто при ручном изменении остатков администратором. WooCommerce не всегда мгновенно «вычищает» корзину у уже зашедшего пользователя: товар может остаться в сессии, хотя на складе его уже нет. Если не вмешаться, покупатель увидит ошибку только на checkout.

Признаки, что дело именно в корзине, а не в оплате

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

Диагностика: что проверить до правки кода

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

Дальше проверьте, не мешает ли кэш. Если у вас есть кэш страниц, корзина и checkout должны быть исключены из кэширования. Иначе вы можете лечить не ту проблему: товар не исчезает не из-за склада, а из-за старого HTML.

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

Рабочий подход: проверять остаток при загрузке корзины и перед checkout

Самый надежный вариант — не ждать ошибки на оплате, а удалить недоступные позиции из корзины сразу после ее инициализации и повторно проверить перед оформлением заказа. Так пользователь видит проблему раньше и может заменить товар без лишних действий.

Ниже пример для functions.php дочерней темы или небольшого mu-plugin. Код проходит по корзине, проверяет остаток у каждого товара и удаляет позицию, если товара больше нет в наличии или доступного количества не хватает.

<?php
add_action( 'woocommerce_before_calculate_totals', 'wpbono_remove_unavailable_cart_items', 20 );
add_action( 'woocommerce_check_cart_items', 'wpbono_remove_unavailable_cart_items' );

function wpbono_remove_unavailable_cart_items() {
    if ( ! function_exists( 'WC' ) || ! WC()->cart ) {
        return;
    }

    $cart = WC()->cart;
    $removed = false;

    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        $product = $cart_item['data'];

        if ( ! $product || ! is_a( $product, 'WC_Product' ) ) {
            continue;
        }

        if ( ! $product->managing_stock() ) {
            continue;
        }

        $stock_quantity = $product->get_stock_quantity();
        $in_cart_qty    = (int) $cart_item['quantity'];

        if ( $product->is_in_stock() === false || ( is_numeric( $stock_quantity ) && $in_cart_qty > (int) $stock_quantity ) ) {
            $cart->remove_cart_item( $cart_item_key );
            $removed = true;
        }
    }

    if ( $removed && ! is_admin() ) {
        wc_add_notice( __( 'Некоторые товары были удалены из корзины, потому что их остаток изменился.', 'woocommerce' ), 'notice' );
    }
}

Этот вариант простой, но у него есть важная оговорка: woocommerce_before_calculate_totals может вызываться несколько раз за запрос. Поэтому не стоит внутри него делать тяжелые запросы к внешнему API или сложную логику синхронизации. Для проверки уже загруженных данных WooCommerce этого достаточно.

Если остатки приходят из внешней системы

Когда склад живет не в WooCommerce, а в другой системе, лучше не пытаться «угадывать» остаток из карточки товара. Надежнее хранить актуальное значение в мета-поле и обновлять его по крону или по webhook. Тогда корзина будет проверять уже локальное число, а не делать запрос в ERP на каждом открытии страницы.

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

<?php
// Пример: ручное обновление остатка у товара.
$product_id = 123;
$new_stock   = 0;

$product = wc_get_product( $product_id );

if ( $product ) {
    $product->set_manage_stock( true );
    $product->set_stock_quantity( $new_stock );
    $product->set_stock_status( $new_stock > 0 ? 'instock' : 'outofstock' );
    $product->save();
}

Сравнение подходов: плагин, код или только настройки

ПодходЧто решаетМинус
Только настройки WooCommerceБазовый учет остатковНе убирает товар из уже созданной корзины
Код в теме или mu-pluginУдаление недоступных позиций до checkoutНужна аккуратная проверка и тестирование
Плагин синхронизации складаАвтоматическое обновление данных из внешней системыЗависимость от стороннего решения и его логики

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

Проверка должна быть не «на глаз», а по сценарию. Сначала добавьте товар в корзину, затем в админке уменьшите остаток до нуля или ниже количества в корзине. После этого обновите корзину и перейдите к checkout. Если код работает, товар исчезнет из корзины или WooCommerce покажет уведомление до оформления заказа.

  • товар удаляется из корзины после обновления страницы;
  • на checkout не появляется ошибка о недоступности этого же товара;
  • сообщение в корзине объясняет, что произошло;
  • итоговая сумма пересчитывается без ручного вмешательства.

Если у вас включен лог ошибок, проверьте, что в нем нет предупреждений о пустом объекте товара или о вызове метода у несуществующего объекта. Это особенно важно на магазинах с вариативными товарами и нестандартными плагинами доставки.

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

Проверяют только is_in_stock()

Этого недостаточно, если товар в наличии, но количество в корзине больше доступного остатка. Нужно смотреть и на get_stock_quantity(), и на количество в корзине.

Ставят код в родительскую тему

После обновления темы правка исчезает. Для такой логики лучше использовать дочернюю тему или отдельный mu-plugin.

Не исключают checkout из кэша

Если checkout отдается из кэша, пользователь может видеть старую корзину и старые сообщения. Исключите корзину, checkout и страницу «Мой аккаунт» из кэширования на уровне плагина или сервера.

Проверяют остаток в каждом запросе к внешнему API

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

Что еще стоит учесть для производительности и безопасности

Не делайте удаление товаров из корзины «тихим», если это влияет на сумму заказа. Пользователь должен понимать, почему корзина изменилась. Иначе вы получите лишние обращения в поддержку и недоверие к оформлению заказа.

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

Для магазинов, где важна чистота фронтенда и отсутствие лишних дублей в шаблонах, полезно дополнительно проверить настройки SEO и технической оптимизации. Если нужен инструмент для чистки лишнего кода и системных дублей, можно посмотреть Clearfy Pro: https://wpshop.ru/plugins/clearfy?utm_source=wpbono.ru&utm_medium=article&utm_campaign=woocommerce-otklyuchit-otkladannye-tovary-v-korzine-pri-izmenenii-sklada

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

×

AI-плагин от WPShop.ru

анализирует конкурентов

пишет статьи

готовит SEO

генерирует изображения

и еще кое-что...
WPGPT
Плагин, который наполняет ваш сайт WordPress
Узнать больше