Диагностика задачи: зачем отключать оплату для товаров с определённым статусом
В WooCommerce бывают ситуации, когда необходимо временно или постоянно запретить покупку определённых товаров. Например, товары с пометкой "ожидается поступление" или "временно недоступен" должны отображаться в каталоге, но кнопка "Добавить в корзину" и возможность оплаты должны быть отключены, чтобы избежать ошибок и недовольства клиентов.
Без подобной фильтрации покупатели могут добавлять в корзину товары, которые нельзя купить, что ведёт к отменам заказов и дополнительной нагрузке на поддержку.
Как определить статус товара и отключить оплату: ключевые хуки и функции
Для решения задачи нам нужно:
- Определить, какой статус обозначает запрет на покупку. Это может быть пользовательское поле, мета-ключ или категория.
- Отключить кнопку "Добавить в корзину" и возможность оформить заказ для таких товаров.
В WooCommerce для изменения отображения кнопки и поведения корзины подходят хуки woocommerce_is_purchasable и woocommerce_variation_is_purchasable. Они позволяют вернуть false для запрета покупки.
Пример кода для отключения оплаты товаров с мета-полем _disable_purchase равным yes
add_filter('woocommerce_is_purchasable', 'disable_purchase_for_certain_status', 10, 2);
function disable_purchase_for_certain_status($purchasable, $product) {
$disable = get_post_meta($product->get_id(), '_disable_purchase', true);
if ($disable === 'yes') {
return false; // товар нельзя купить
}
return $purchasable;
}
add_filter('woocommerce_variation_is_purchasable', 'disable_purchase_for_certain_status', 10, 2);Этот код проверяет наличие мета-поля _disable_purchase у товара и если оно равно yes, делает товар непокупаемым.
Как отключить оплату на уровне оформления заказа
Даже если кнопка "Добавить в корзину" исчезнет, пользователь может попытаться отправить заказ, если товар уже в корзине. Для этого нужно дополнительно проверять содержимое корзины.
Пример проверки в корзине и блокировки оформления заказа
add_action('woocommerce_check_cart_items', 'block_checkout_for_disabled_products');
function block_checkout_for_disabled_products() {
foreach (WC()->cart->get_cart() as $cart_item) {
$product = $cart_item['data'];
$disable = get_post_meta($product->get_id(), '_disable_purchase', true);
if ($disable === 'yes') {
wc_add_notice(sprintf('Товар "%s" временно недоступен для покупки.', $product->get_name()), 'error');
// Можно автоматически удалить товар из корзины
WC()->cart->remove_cart_item($cart_item['key']);
}
}
}Этот код выводит ошибку и удаляет товар из корзины, если он запрещён к покупке.
Проверка результата после внедрения
- Перейдите на страницу товара с мета-полем
_disable_purchase=yes. Кнопка "Добавить в корзину" должна исчезнуть или быть недоступной. - Попытайтесь добавить такой товар в корзину вручную (например, через URL с параметром). При переходе к оформлению заказа должна появиться ошибка, и товар удалится из корзины.
- Для других товаров кнопка и оплата должны работать штатно.
Частые ошибки и как их исправить
- Кнопка "Добавить в корзину" не исчезает: проверьте, что хук
woocommerce_is_purchasableдобавлен правильно и приоритет 10 подходит; конфликт с темой или плагинами может перекрывать логику. - Товар остаётся в корзине, несмотря на ошибку: убедитесь, что используете
WC()->cart->remove_cart_item()правильно с ключом корзины, а не ID товара. - Ошибка не выводится на странице оформления заказа: проверьте, что вызов
wc_add_notice()происходит до рендера страницы и в правильном хуке. - Мета-поле не читается: убедитесь, что мета ключ
_disable_purchaseустановлен для нужных товаров и вызывается с правильным ID.
Практические советы по безопасности и производительности
- Не используйте в мета-полях слишком большие или часто изменяемые данные – это может замедлить запросы.
- Кешируйте результаты проверок, если товаров много и проверка сложная.
- Для массового управления статусами используйте WP-CLI или SQL-запросы, чтобы не тянуть логику на каждый запрос.
- Регулярно тестируйте отображение и заказ товаров после обновлений WooCommerce и темы, чтобы избежать конфликтов.
Сравнение способов отключения оплаты для товаров в WooCommerce
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
Фильтр woocommerce_is_purchasable |
Отключает кнопку покупки на страницах товаров | Легко реализовать, влияет на UI | Не защищает от прямого добавления в корзину |
Проверка корзины через woocommerce_check_cart_items |
Блокирует оформление заказа с запрещёнными товарами | Защищает от обходов, повышает безопасность | Нужно дополнительно удалять товары из корзины |
| Изменение статуса товаров (через UI) | Использование статусов WooCommerce или категорий для отключения | Удобно для админов без кода | Менее гибко, требует ручной работы |