На checkout в WooCommerce часто остаются лишние поля, которые мешают оформлению заказа: например, поле компании, второй адрес, индекс для самовывоза или дополнительные поля оплаты, которые не нужны при конкретном способе доставки. Если это не убрать, страница становится длиннее, а часть пользователей просто бросает оформление.
Ниже разберём рабочий сценарий: как скрывать поля оплаты и адреса в зависимости от выбранного способа доставки, как проверить результат и где чаще всего ломается логика.
Когда это действительно нужно
Сценарий обычно один из трёх:
- самовывоз — не нужны часть адресных полей;
- локальная доставка — можно убрать лишние поля, если они не влияют на расчёт;
- курьерская доставка через один конкретный метод — часть полей можно сделать необязательными или скрыть совсем.
Важно не путать визуальное скрытие и серверную валидацию. Если поле спрятано только на фронтенде, WooCommerce может всё равно потребовать его при отправке заказа. Поэтому решение должно включать и JavaScript, и PHP-проверку, если вы убираете обязательность.
Диагностика проблемы перед правкой
Сначала посмотрите, какие именно методы доставки у вас используются. В WooCommerce они часто имеют вид flat_rate:1, local_pickup:3, free_shipping:2. Номер после двоеточия зависит от зоны доставки и конкретного метода.
Проверить это можно прямо на странице оформления заказа:
- Откройте checkout в браузере.
- Выберите разные способы доставки.
- Посмотрите, меняется ли набор полей и не появляется ли ошибка валидации после отправки формы.
- Если используете кэш или минификацию, временно отключите их для checkout, чтобы исключить конфликт скриптов.
Если поля не скрываются, обычно причина одна из этих:
- не совпадает ID метода доставки;
- тема или плагин переопределяет шаблон checkout;
- скрипт не слушает событие обновления checkout;
- поле скрыто визуально, но остаётся обязательным на сервере.
Пошаговое решение через код
Надёжнее всего делать это в дочерней теме или через небольшой mu-plugin. Ниже пример, который скрывает часть полей при выборе самовывоза и возвращает их обратно для остальных способов доставки.
1. Скрываем поля на фронтенде
<script>
jQuery(function($) {
function toggleCheckoutFields() {
var shippingMethod = $('input[name^="shipping_method"]:checked').val() || '';
var isPickup = shippingMethod.indexOf('local_pickup') !== -1;
var fields = [
'#billing_company_field',
'#billing_address_2_field',
'#billing_postcode_field'
];
fields.forEach(function(selector) {
if (isPickup) {
$(selector).hide();
$(selector).find('input, select, textarea').prop('disabled', true);
} else {
$(selector).show();
$(selector).find('input, select, textarea').prop('disabled', false);
}
});
}
$(document.body).on('updated_checkout change', 'input[name^="shipping_method"]', toggleCheckoutFields);
toggleCheckoutFields();
});
</script>Этот вариант работает на уровне интерфейса: поля исчезают и не отправляются в форме, потому что мы отключаем их через disabled.
2. Убираем обязательность на сервере
Если поле у вас было обязательным, одной фронтенд-логики мало. Добавьте фильтр, который снимет обязательность для самовывоза:
<?php
add_filter('woocommerce_checkout_fields', function($fields) {
$chosen_methods = WC()->session ? WC()->session->get('chosen_shipping_methods') : array();
$shipping_method = isset($chosen_methods[0]) ? $chosen_methods[0] : '';
if (strpos($shipping_method, 'local_pickup') !== false) {
if (isset($fields['billing']['billing_company'])) {
$fields['billing']['billing_company']['required'] = false;
}
if (isset($fields['billing']['billing_address_2'])) {
$fields['billing']['billing_address_2']['required'] = false;
}
if (isset($fields['billing']['billing_postcode'])) {
$fields['billing']['billing_postcode']['required'] = false;
}
}
return $fields;
});Здесь логика завязана на выбранный способ доставки из сессии WooCommerce. Это не идеальная универсальная схема для всех кастомных checkout-плагинов, но для стандартного сценария работает предсказуемо.
3. Если нужен более точный контроль по конкретным методам
Иногда скрывать поля нужно не только для самовывоза, а для конкретной зоны или тарифа. Тогда лучше проверять полный ID метода, например flat_rate:1 или local_pickup:3.
<?php
add_filter('woocommerce_checkout_fields', function($fields) {
$chosen_methods = WC()->session ? WC()->session->get('chosen_shipping_methods') : array();
$shipping_method = isset($chosen_methods[0]) ? $chosen_methods[0] : '';
$target_methods = array('local_pickup:3', 'flat_rate:1');
if (in_array($shipping_method, $target_methods, true)) {
unset($fields['billing']['billing_company']);
}
return $fields;
});Такой подход полезен, если у вас несколько самовывозов в разных зонах и скрывать поля нужно только в одном из них.
Сравнение подходов
| Подход | Плюсы | Минусы | Когда брать |
|---|---|---|---|
| Только CSS | Быстро | Поле остаётся в форме и может валидироваться | Только для временного теста |
| JS + disabled | Поле не отправляется, удобно для UX | Нужна синхронизация с обновлением checkout | Обычный рабочий сценарий |
| JS + PHP-валидация | Надёжно | Чуть больше кода | Если поле было обязательным |
Как проверить, что решение сработало
После внедрения не ограничивайтесь визуальной проверкой. Пройдите чек-лист:
- выберите нужный способ доставки и убедитесь, что поля исчезают;
- попробуйте отправить заказ без скрытых полей — ошибок валидации быть не должно;
- переключите доставку на другой метод и проверьте, что поля возвращаются;
- посмотрите заказ в админке: данные не должны теряться в неожиданных местах;
- проверьте checkout в мобильной версии, особенно если тема перестраивает форму через AJAX.
Если используете кэширование HTML, очистите кэш страницы оформления заказа и кэш объекта, если он есть. На checkout лучше не полагаться на старую разметку.
Частые ошибки и как их исправить
Неверный ID способа доставки
Самая частая проблема — в коде указан local_pickup, а фактически выбран метод local_pickup:3. В результате условие не срабатывает. Сначала посмотрите реальное значение в DOM или через отладку.
Поле скрыто, но заказ не отправляется
Это значит, что поле осталось обязательным на сервере. Проверьте фильтр woocommerce_checkout_fields и снимите required для нужных полей.
Скрипт не срабатывает после смены доставки
WooCommerce обновляет checkout через AJAX. Если привязаться только к change, логика может сработать один раз и потом сломаться. Нужен обработчик updated_checkout.
Поле пропадает, но остаётся пустой отступ
Это уже вопрос верстки темы. Иногда контейнер поля скрывается не полностью, и остаётся место. В таком случае лучше скрывать именно блок _field, а не только input.
Практические советы по безопасности и производительности
Не вставляйте такой код в файл темы без необходимости. Лучше использовать дочернюю тему или отдельный мини-плагин, чтобы обновление темы не затёрло правки. Если у вас уже есть набор мелких правок для WooCommerce, их удобнее держать в одном файле с понятными комментариями.
Если задача шире и касается не только checkout, а ещё дублей, мусорных скриптов и лишних элементов WooCommerce, можно посмотреть в сторону Clearfy Pro. Но для конкретной логики скрытия полей код обычно надёжнее и прозрачнее.
Ещё один практический момент: не скрывайте поля, которые нужны для расчёта доставки или налога. Если убрать адрес там, где он участвует в расчёте, можно получить неверную стоимость заказа. Сначала проверьте, какие поля реально используются в вашей конфигурации WooCommerce.