Сценарий типичный: вы продаёте консультации, доступы, цифровые файлы или подписки, и лишний шаг с корзиной только мешает. Пользователь добавляет товар, потом ещё раз идёт в корзину, хотя ему нужен один быстрый сценарий — сразу на оформление заказа. В WooCommerce это можно решить без тяжёлых плагинов: либо точечно кодом, либо настройкой шаблона поведения для виртуальных товаров.
Ниже разберём, как безопасно убрать корзину именно для виртуальных позиций, не ломая обычные товары с доставкой.
Когда это действительно нужно
Не стоит отключать корзину глобально только потому, что «так быстрее». Для физических товаров корзина часто нужна: там покупатель меняет количество, видит доставку, применяет купоны. А вот для цифровых товаров корзина обычно создаёт лишний шаг и повышает шанс бросить оформление.
Подход подходит, если у вас:
- цифровые товары без доставки;
- один товар в заказе почти всегда;
- нужно ускорить переход к checkout после клика «Купить»;
- смешанный каталог, где виртуальные и физические товары должны вести себя по-разному.
Диагностика: что именно сейчас происходит
Перед правкой кода проверьте, где возникает лишний шаг. Иногда проблема не в корзине как таковой, а в теме или плагине, который переопределяет кнопку покупки.
Проверьте настройки товара
Откройте товар в админке WooCommerce и убедитесь, что отмечены флаги Virtual и, если нужно, Downloadable. Если товар не виртуальный, WooCommerce будет ожидать сценарий с доставкой и корзиной.
Проверьте поведение кнопки добавления
После добавления товара в корзину посмотрите, куда ведёт сайт:
- на страницу корзины;
- сразу на оформление заказа;
- на текущую страницу с уведомлением.
Если редирект уже есть, но корзина всё равно показывается, значит нужно менять не редирект, а сам сценарий отображения корзины и ссылок.
Рабочий вариант: редирект на checkout для виртуальных товаров
Самый надёжный способ — отправлять пользователя сразу на страницу оформления заказа, если в корзине только виртуальные товары. Для этого можно использовать фильтр woocommerce_add_to_cart_redirect. Он срабатывает после добавления товара в корзину и позволяет подменить адрес перехода.
<?php
add_filter( 'woocommerce_add_to_cart_redirect', 'wpmod_redirect_virtual_products_to_checkout' );
function wpmod_redirect_virtual_products_to_checkout( $url ) {
if ( ! function_exists( 'WC' ) || ! WC()->cart ) {
return $url;
}
$cart = WC()->cart->get_cart();
if ( empty( $cart ) ) {
return $url;
}
$has_physical_product = false;
foreach ( $cart as $cart_item ) {
if ( empty( $cart_item['data'] ) ) {
continue;
}
$product = $cart_item['data'];
if ( ! $product->is_virtual() ) {
$has_physical_product = true;
break;
}
}
if ( ! $has_physical_product ) {
return wc_get_checkout_url();
}
return $url;
}
Что делает код:
- проверяет, что корзина доступна;
- просматривает товары в корзине;
- если все товары виртуальные, отправляет на checkout;
- если есть хотя бы один физический товар, оставляет стандартное поведение.
Этот вариант безопаснее, чем жёстко отключать корзину для всех товаров сразу.
Если нужно убрать ссылку на корзину в интерфейсе
Иногда редиректа недостаточно: в теме остаётся иконка корзины, мини-корзина или ссылка в меню. Тогда нужно отдельно скрыть переход на страницу корзины для виртуального сценария. Делать это лучше точечно, а не через удаление всех шаблонов WooCommerce.
<?php
add_filter( 'woocommerce_get_cart_url', 'wpmod_cart_url_for_virtual_products' );
function wpmod_cart_url_for_virtual_products( $cart_url ) {
if ( ! function_exists( 'WC' ) || ! WC()->cart ) {
return $cart_url;
}
$cart = WC()->cart->get_cart();
if ( empty( $cart ) ) {
return $cart_url;
}
foreach ( $cart as $cart_item ) {
if ( ! empty( $cart_item['data'] ) && ! $cart_item['data']->is_virtual() ) {
return $cart_url;
}
}
return wc_get_checkout_url();
}
Такой подход не убирает корзину физически, но меняет точку входа. Для пользователя это выглядит как «корзины нет», хотя технически WooCommerce продолжает работать штатно.
Сравнение подходов
| Подход | Когда подходит | Минус |
|---|---|---|
| Редирект кодом | Если нужны быстрые покупки цифровых товаров | Нужно проверить тему и кэш |
| Плагин для кастомизации checkout | Если не хотите трогать код | Часто добавляет лишние зависимости |
| Отключение корзины целиком | Только для магазина без физических товаров | Ломает обычный сценарий покупок |
Если у вас смешанный каталог, код почти всегда предпочтительнее. Он даёт контроль по условиям и не вмешивается в остальные товары.
Проверка результата после внедрения
После добавления кода проверьте не только сам переход, но и несколько соседних сценариев. Ошибка часто проявляется не сразу.
- Добавьте виртуальный товар и убедитесь, что открывается checkout.
- Добавьте физический товар и проверьте, что корзина остаётся доступной.
- Откройте сайт в приватном окне, чтобы исключить влияние старой сессии.
- Проверьте мобильную версию: некоторые темы по-разному обрабатывают мини-корзину.
- Если используется кэш, очистите его после правок.
Для быстрой проверки можно временно включить логирование в wp-config.php и посмотреть, не возникает ли ошибок PHP:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
Если после этого в wp-content/debug.log появляются ошибки, сначала исправьте их, а уже потом тестируйте редирект.
Частые ошибки и как их исправить
Редирект срабатывает для всех товаров
Обычно это значит, что проверка на виртуальность написана слишком грубо. Не ориентируйтесь только на один товар в корзине, если каталог смешанный. Нужно проходить по всем позициям и проверять каждую.
После добавления товара ничего не происходит
Частая причина — конфликт с темой или AJAX-кнопкой. Некоторые темы перехватывают добавление в корзину и не дают стандартному фильтру сработать как ожидается. В таком случае проверьте, не отключён ли AJAX add to cart для каталога, и протестируйте код на стандартной теме.
Мини-корзина всё ещё показывает ссылку на cart
Это отдельный шаблон темы. Редирект после добавления товара не меняет ссылки в хедере. Нужно либо править шаблон темы, либо фильтровать URL корзины, как в примере выше.
Checkout открывается, но заказ не создаётся
Проблема обычно не в редиректе, а в платёжном шлюзе, обязательных полях или конфликте с плагином доставки. Для виртуальных товаров проверьте, не требует ли тема адрес доставки там, где он не нужен.
Практические советы по безопасности и производительности
Не вставляйте такой код в functions.php родительской темы, если тема регулярно обновляется. Лучше использовать дочернюю тему или небольшой mu-plugin. Так вы не потеряете правку после обновления.
Если на сайте уже есть плагин для сниппетов, не дублируйте один и тот же фильтр в нескольких местах. Двойной редирект часто приводит к странным петлям переходов.
Для больших магазинов полезно проверить, не создаёт ли кэш страницы checkout проблемы с сессией WooCommerce. Страницы корзины и оформления заказа обычно должны быть исключены из кэширования на уровне сервера или плагина.
Когда лучше не отключать корзину
Если у вас есть комплекты товаров, апселлы, дополнительные услуги или часто покупают несколько позиций за раз, корзина остаётся полезной. В таких случаях лучше не убирать её полностью, а только ускорить сценарий для конкретных виртуальных товаров. Это даёт пользователю выбор и не ломает привычный путь покупки.
Если нужен более широкий контроль над служебными страницами, дублями и техническими настройками WooCommerce, иногда удобнее сначала навести порядок в базовой оптимизации сайта. Но сам сценарий «виртуальный товар → checkout без корзины» лучше решать точечным кодом, а не тяжёлой автоматизацией.