Проблема: оформление заказа при отсутствии товара на складе
В стандартной установке WooCommerce покупатели могут оформить заказ даже если товар отсутствует на складе, если не активировано соответствующее ограничение. Это приводит к необходимости вручную обрабатывать такие заказы и недовольству клиентов, когда доставка задерживается или невозможна.
Задача — автоматически блокировать кнопку "Добавить в корзину" и оформление заказа для товаров, которые отсутствуют на складе, чтобы исключить такие ситуации.
Диагностика проблемы
Для начала проверьте, что у товара корректно настроена опция управления складом и актуальное количество:
- В карточке товара в админке WooCommerce на вкладке "Инвентарь" включена опция "Управление запасами".
- Количество товара указано как 0 или меньше.
- Опция "Разрешить заказы при отсутствии на складе" выключена (в настройках WooCommerce).
Если при выполнении этих условий кнопка "Добавить в корзину" не блокируется, значит либо тема или плагин переопределяют этот функционал, либо настройка отсутствия товаров обрабатывается некорректно.
Пошаговое решение: отключение оформления заказа для отсутствующих товаров
1. Запретить добавление товаров с нулевым запасом
Добавим проверку в функцию, чтобы скрыть кнопку "Добавить в корзину" для товаров с запасом 0 или меньше. Для этого используем фильтр woocommerce_is_purchasable:
add_filter('woocommerce_is_purchasable', 'disable_purchase_if_out_of_stock', 10, 2);
function disable_purchase_if_out_of_stock($purchasable, $product) {
if (!$product->is_in_stock()) {
return false;
}
return $purchasable;
}2. Отключить оформление заказа, если в корзине есть отсутствующие товары
Добавим проверку при оформлении заказа, чтобы блокировать процесс, если в корзине есть товары с запасом 0:
add_action('woocommerce_check_cart_items', 'block_checkout_if_out_of_stock_in_cart');
function block_checkout_if_out_of_stock_in_cart() {
foreach (WC()->cart->get_cart() as $cart_item) {
$product = $cart_item['data'];
if (!$product->is_in_stock()) {
wc_add_notice(sprintf('Товар "%s" отсутствует на складе и не может быть заказан.', $product->get_name()), 'error');
break;
}
}
}Проверка результата после внедрения
- Перейдите на страницу товара с нулевым запасом. Кнопка "Добавить в корзину" должна отсутствовать или быть неактивной.
- Добавьте товар с наличием в корзину, а затем вручную добавьте товар с нулевым запасом через админку (или используйте разные вкладки браузера). Попытка оформить заказ должна прерваться с сообщением об ошибке.
- Проверьте, что товары с запасом >0 доступны для покупки и оформления заказа.
Частые ошибки и как исправить
- Кнопка "Добавить в корзину" не скрывается для отсутствующих товаров: Проверьте, не переопределяет ли тема или плагин функцию
woocommerce_is_purchasable. Попробуйте временно переключиться на дефолтную тему Storefront. - Ошибка не появляется при оформлении заказа с отсутствующим товаром: Убедитесь, что хук
woocommerce_check_cart_itemsне отключён и не конфликтует с другими плагинами. - В настройках WooCommerce включена опция "Разрешить заказы при отсутствии на складе": Это нужно выключить в WooCommerce → Настройки → Товары → Запасы.
Практические советы по безопасности и производительности
- При добавлении кастомного кода используйте дочернюю тему или собственный плагин, чтобы избежать потери изменений при обновлении.
- Проверяйте совместимость с кеширующими плагинами — наличие кэша страниц может мешать обновлению кнопок в зависимости от наличия товара.
- Если у вас много товаров и активная нагрузка — рассмотрите использование AJAX для динамического обновления кнопки покупки без полной перезагрузки страницы.
Сравнение подходов к ограничению покупки отсутствующих товаров
| Метод | Плюсы | Минусы |
|---|---|---|
| Встроенные настройки WooCommerce | Простота настройки, не требует кода | Не всегда блокирует кнопку на фронтенде, требует правильной настройки |
Код с фильтром woocommerce_is_purchasable | Гибкость, точечное отключение кнопки | Требует навыков разработки, может конфликтовать с темой |
Проверка в woocommerce_check_cart_items | Защита оформления заказа, дополнительный уровень контроля | Не предотвращает добавление в корзину, только блокирует заказ |