Диагностика проблемы: почему нужно блокировать оплату по атрибутам товаров
В интернет-магазинах на WooCommerce иногда требуется запретить покупку товаров с определёнными атрибутами. Например, запретить оплату, если в корзине есть товары с атрибутом "высокая цена" или товары, требующие дополнительной проверки, чтобы избежать конфликтов, ошибок доставки или соблюдения специфических правил.
Без такой блокировки пользователь может оформить заказ с товарами, которые нельзя продавать вместе или с которыми невозможна корректная обработка платежа.
Как проверить наличие проблемы
- Откройте корзину и добавьте товар с нужным атрибутом.
- Перейдите к оформлению заказа.
- Если оплата доступна, хотя должна быть заблокирована, значит, проблема актуальна.
Пошаговое решение: блокировка оплаты на основании атрибутов товаров в корзине
Реализуем запрет оплаты через хук woocommerce_checkout_process, который срабатывает при нажатии кнопки оформления заказа. В функции проверим все товары в корзине на наличие заданного атрибута и, если такой товар найден, добавим ошибку, блокирующую оформление.
1. Получение товаров и проверка атрибутов
function block_checkout_for_attribute() {
$blocked_attribute_slug = 'material'; // замените на ваш слаг атрибута
$blocked_terms = array('restricted', 'prohibited'); // слаги терминов-атрибутов, блокирующих оплату
foreach ( WC()->cart->get_cart() as $cart_item ) {
$product = $cart_item['data'];
$terms = wp_get_post_terms($product->get_id(), 'pa_' . $blocked_attribute_slug, array('fields' => 'slugs'));
if ( array_intersect($terms, $blocked_terms) ) {
wc_add_notice(__('Оплата невозможна: в корзине есть товары с запрещённым атрибутом.'), 'error');
break;
}
}
}
add_action('woocommerce_checkout_process', 'block_checkout_for_attribute');2. Настройка атрибутов
В этом примере атрибут называется material (материал), а блокируются товары с терминами restricted и prohibited. Чтобы узнать слаг атрибута и терминов:
- Перейдите в WooCommerce > Продукты > Атрибуты.
- Найдите нужный атрибут, например, "Материал" — его слаг будет
material. - Нажмите "Настроить термины" и посмотрите слаги терминов.
Проверка результата после внедрения
- Очистите корзину.
- Добавьте товар с атрибутом, не входящим в блокирующий список — оформление заказа должно пройти.
- Добавьте товар с заблокированным атрибутом — при попытке оформить заказ появится сообщение об ошибке, и оплата не будет доступна.
Частые ошибки и как исправить
- Неверный слаг атрибута или терминов. Ошибка: блокировка не срабатывает. Решение: проверьте правильность слагов в админке WooCommerce.
- Добавлен не тот хук. Например, использование
woocommerce_before_checkout_formвместоwoocommerce_checkout_processне блокирует оплату, а только отображает предупреждение. - Кэширование корзины. Если в магазине используется кэширование, оно может мешать обновлению состояния корзины. Решение: отключить кэширование для страниц корзины и оформления заказа.
- Отсутствие товара в корзине в момент проверки. Убедитесь, что функция вызывается после загрузки корзины и продуктов.
Практические советы по безопасности и производительности
- Не используйте сложные запросы внутри цикла товаров — wp_get_post_terms достаточно быстрый, но при большом каталоге можно кэшировать результаты.
- Выводите понятное и чёткое сообщение пользователю, чтобы он понимал причину блокировки.
- Для расширения функционала можно добавить вывод предупреждения и на странице корзины с помощью
woocommerce_check_cart_items, чтобы пользователь увидел предупреждение раньше.
Дополнительный пример: предупреждение на странице корзины
function warn_on_cart_for_attribute() {
$blocked_attribute_slug = 'material';
$blocked_terms = array('restricted', 'prohibited');
foreach ( WC()->cart->get_cart() as $cart_item ) {
$product = $cart_item['data'];
$terms = wp_get_post_terms($product->get_id(), 'pa_' . $blocked_attribute_slug, array('fields' => 'slugs'));
if ( array_intersect($terms, $blocked_terms) ) {
wc_print_notice(__('Внимание: в вашей корзине есть товары, оформление заказа с которыми невозможно.'), 'notice');
break;
}
}
}
add_action('woocommerce_check_cart_items', 'warn_on_cart_for_attribute');Сравнение способов реализации блокировки оплаты
| Метод | Где срабатывает | Плюсы | Минусы |
|---|---|---|---|
| woocommerce_checkout_process | Оформление заказа | Надёжная блокировка, предотвращает оплату | Пользователь узнаёт об ошибке поздно |
| woocommerce_check_cart_items | Страница корзины | Предупреждение заранее, UX лучше | Не блокирует оплату, нужна доп. проверка |
| JavaScript-валидация | На клиенте | Быстрая реакция пользователя | Можно обойти, небезопасно |