В WooCommerce остаток товара часто нужен не на карточке товара, а в корзине и на странице оформления заказа. Это полезно, когда покупатель сомневается, хватит ли товара, или когда менеджеру важно видеть складской статус прямо перед оплатой. Стандартно WooCommerce не показывает stock quantity в этих местах, поэтому задачу обычно решают кодом или через доработку шаблонов.
Когда это действительно нужно
Сценарий простой: товар есть в каталоге, но в корзине пользователь не видит, что осталось, например, 3 штуки. Для магазинов с ограниченным складом это снижает количество лишних вопросов и помогает избежать ситуации, когда клиент оформляет заказ на товар, которого уже почти нет.
Если у вас товары с вариациями, важно понимать, что остаток может быть разным для каждого варианта. В таком случае показывать общий остаток товара бессмысленно — нужен именно остаток выбранной вариации.
Диагностика: что проверить до внедрения
Перед правкой кода проверьте несколько вещей, иначе вывод может не появиться даже при корректной реализации:
- у товара включён учёт склада в настройках WooCommerce;
- для товара или вариации заполнено поле остатка;
- товар не помечен как
не в наличиибез фактического количества; - тема не переопределяет шаблоны корзины и checkout слишком агрессивно;
- кэш не отдаёт старую версию страницы оформления заказа.
Если остаток не ведётся, WooCommerce просто не отдаст число, и показывать будет нечего. Это не ошибка кода, а отсутствие данных.
Как вывести остаток товара в корзине через хук
Самый практичный вариант — добавить строку с остатком рядом с названием товара в корзине. Для этого подходит фильтр woocommerce_cart_item_name. Он позволяет дописать HTML после названия товара, не трогая шаблоны темы.
add_filter( 'woocommerce_cart_item_name', 'wpa_show_stock_in_cart', 10, 3 );
function wpa_show_stock_in_cart( $product_name, $cart_item, $cart_item_key ) {
if ( is_admin() && ! wp_doing_ajax() ) {
return $product_name;
}
if ( empty( $cart_item['data'] ) || ! is_a( $cart_item['data'], 'WC_Product' ) ) {
return $product_name;
}
$product = $cart_item['data'];
if ( ! $product->managing_stock() ) {
return $product_name;
}
$stock_quantity = $product->get_stock_quantity();
if ( $stock_quantity === null ) {
return $product_name;
}
$product_name .= '<br><small class="stock in-stock">Остаток на складе: ' . esc_html( $stock_quantity ) . '</small>';
return $product_name;
}Этот вариант работает для простых товаров. Если в корзину добавляют вариации, лучше выводить остаток именно у вариации, а не у родительского товара.
Если нужен остаток вариации
Для вариативных товаров используйте объект товара из корзины: WooCommerce обычно кладёт туда уже выбранную вариацию. В этом случае метод get_stock_quantity() вернёт остаток конкретного варианта, если складской учёт включён именно для него.
add_filter( 'woocommerce_cart_item_name', 'wpa_show_variation_stock_in_cart', 10, 3 );
function wpa_show_variation_stock_in_cart( $product_name, $cart_item, $cart_item_key ) {
if ( empty( $cart_item['data'] ) || ! is_a( $cart_item['data'], 'WC_Product' ) ) {
return $product_name;
}
$product = $cart_item['data'];
if ( ! $product->managing_stock() ) {
return $product_name;
}
$stock_quantity = $product->get_stock_quantity();
if ( $stock_quantity === null ) {
return $product_name;
}
return $product_name . '<br><small class="stock in-stock">Доступно: ' . esc_html( $stock_quantity ) . '</small>';
}Как показать остаток на странице оформления заказа
На checkout логика похожая, но лучше не перегружать интерфейс. Здесь обычно достаточно короткой строки в блоке заказа. Для этого удобно использовать woocommerce_checkout_cart_item_quantity — фильтр, который меняет отображение количества товара в списке заказа.
add_filter( 'woocommerce_checkout_cart_item_quantity', 'wpa_show_stock_in_checkout', 10, 3 );
function wpa_show_stock_in_checkout( $quantity_html, $cart_item, $cart_item_key ) {
if ( empty( $cart_item['data'] ) || ! is_a( $cart_item['data'], 'WC_Product' ) ) {
return $quantity_html;
}
$product = $cart_item['data'];
if ( ! $product->managing_stock() ) {
return $quantity_html;
}
$stock_quantity = $product->get_stock_quantity();
if ( $stock_quantity === null ) {
return $quantity_html;
}
$quantity_html .= '<br><small class="stock in-stock">Остаток: ' . esc_html( $stock_quantity ) . '</small>';
return $quantity_html;
}Если в вашей теме checkout сильно кастомизирован, этот фильтр может не попасть в нужное место. Тогда лучше проверить шаблон review-order.php и убедиться, что он не переопределён в теме.
Сравнение подходов: код, шаблон, плагин
| Подход | Когда подходит | Плюсы | Минусы |
|---|---|---|---|
| Хуки WooCommerce | Нужно быстро добавить остаток без правки шаблонов | Меньше риска сломать обновления | Не всегда удобно для сложной верстки |
| Переопределение шаблонов | Нужен точный контроль над HTML | Полный контроль над выводом | Сложнее сопровождать после обновлений |
| Плагин для кастомизации | Нет доступа к коду или нужен быстрый запуск | Быстро внедрить | Лишняя зависимость и риск конфликтов |
Если у вас уже стоит набор инструментов для чистки и оптимизации WooCommerce, например Clearfy Pro, проверьте, не скрывает ли он часть стандартных элементов интерфейса. Но сам вывод остатка лучше держать в коде: так проще контролировать поведение.
Проверка результата после внедрения
После добавления кода не ограничивайтесь визуальной проверкой на одной странице. Пройдите короткий чек-лист:
- добавьте в корзину простой товар со складским учётом;
- добавьте вариативный товар и проверьте выбранную вариацию;
- откройте корзину в обычном режиме и в режиме инкогнито;
- перейдите на checkout и убедитесь, что строка не ломает верстку;
- проверьте товар без учёта склада — остаток для него показываться не должен.
Если используете кэш на стороне сервера или CDN, очистите его после правки. Иначе вы можете видеть старую версию страницы и ошибочно думать, что код не сработал.
Частые ошибки и как их исправить
Остаток не выводится вообще
Чаще всего причина в том, что у товара выключен учёт склада. Проверьте настройки товара в админке WooCommerce и убедитесь, что поле остатка заполнено. Ещё одна типичная причина — код вставлен не в активную тему или не в рабочий сниппет.
Показывается не тот остаток
Такое бывает у вариативных товаров, если берут данные родительского товара вместо вариации. В корзине нужно работать с объектом товара из $cart_item['data'], а не с ID родителя.
Ломается верстка корзины
Обычно проблема в том, что в HTML добавили слишком тяжёлую разметку или вставили блок не в тот фильтр. Для начала используйте простой <small> без лишних контейнеров. Если нужно оформить красиво, добавляйте CSS отдельно.
На checkout текст дублируется
Это бывает, если тема уже выводит похожий блок через собственный шаблон. Тогда проверьте переопределённые файлы WooCommerce в теме и уберите дублирующий вывод либо перенесите логику в другой хук.
Безопасность и производительность
Для такого изменения не нужно трогать ядро WooCommerce. Лучше использовать дочернюю тему или отдельный сниппет-плагин, чтобы обновления темы не затёрли правку. В коде обязательно экранируйте вывод через esc_html(), даже если значение приходит из WooCommerce.
Не делайте лишних запросов к базе в цикле корзины. В примерах выше используется уже загруженный объект товара, поэтому решение не создаёт дополнительную нагрузку на каждый рендер страницы. Это важнее, чем кажется: корзина и checkout и так чувствительны к тяжёлым хукам и сторонним скриптам.
Если вам нужно не просто показать остаток, а ещё и предупредить о низком складе, лучше использовать стандартную логику WooCommerce для low stock и лишь аккуратно дополнять её текстом. Не дублируйте бизнес-логику в нескольких местах — потом сложно понять, почему сообщение меняется в одном шаблоне и не меняется в другом.
Что делать, если нужен более гибкий вариант
Если нужно показывать остаток только для отдельных категорий, только для авторизованных пользователей или только при низком складе, добавьте условие до вывода. Например, можно ограничить показ товарной категорией через has_term() или скрывать остаток для оптовых клиентов по роли пользователя. Но сначала проверьте базовый вариант: в большинстве магазинов этого достаточно.
Когда задача выходит за рамки простого текста в корзине, уже имеет смысл смотреть в сторону кастомного шаблона checkout или отдельного мини-плагина. Это даст больше контроля, чем попытка собрать всё на одном фильтре.