Как сделать обязательное поле комментария при выборе самовывоза в WooCommerce

Сценарий простой: клиент выбирает самовывоз, но не оставляет важную информацию — номер точки, желаемое время, имя получателя, ориентир для курьера внутри ТЦ. Если это поле не контролировать на стороне checkout, менеджер потом добирает данные вручную, а заказы зависают в уточнениях.

В WooCommerce это лучше решать не через «попросить клиента», а через явную валидацию на этапе оформления заказа. Тогда поле будет обязательным только при нужном способе доставки, а для курьерской доставки останется необязательным.

Когда это действительно нужно

Такой сценарий часто встречается в магазинах с несколькими точками выдачи, в пунктах самовывоза внутри торговых центров и в локальной рознице, где без комментария заказ нельзя собрать корректно. Если у вас самовывоз — это просто «забрать на складе», поле может быть лишним. Но если менеджеру нужен хотя бы один уточняющий параметр, обязательная проверка экономит время.

Что именно будем делать

Ниже — вариант без сторонних плагинов: добавим поле комментария на checkout, сделаем его обязательным только при выборе самовывоза и сохраним значение в заказе. Логика будет завязана на стандартные хуки WooCommerce, без выдуманных API и без правки шаблонов темы.

Диагностика проблемы перед правкой

Сначала проверьте, как у вас называется способ доставки. В WooCommerce самовывоз обычно имеет идентификатор local_pickup, но в конкретной установке он может быть частью метода с индексом, например local_pickup:3. Это важно: если в коде сравнивать не тот ID, условие не сработает.

Откройте страницу оформления заказа и посмотрите, какой метод выбирается по умолчанию. Если самовывоз уже активен, поле должно стать обязательным сразу. Если клиент переключается между доставкой и самовывозом, лучше проверить, обновляется ли checkout через AJAX без перезагрузки.

  • Проверьте, включён ли блок checkout в вашей теме или используется классический шаблон.
  • Убедитесь, что поле комментария не дублируется другим плагином.
  • Посмотрите, не скрывает ли кэш/оптимизатор скрипты WooCommerce на checkout.
  • Проверьте, что в заказе сохраняется мета-данные, а не только визуальное значение в форме.

Пошаговое решение через код

Ниже пример для functions.php дочерней темы или для собственного мини-плагина. Я рекомендую именно мини-плагин: так код не потеряется при смене темы.

1. Добавляем поле на checkout

add_action( 'woocommerce_after_order_notes', function( $checkout ) {
    woocommerce_form_field( 'pickup_comment', array(
        'type'        => 'textarea',
        'class'       => array( 'form-row-wide' ),
        'label'       => 'Комментарий для самовывоза',
        'placeholder' => 'Например: заберу после 18:00, нужен звонок за 10 минут',
        'required'    => false,
    ), $checkout->get_value( 'pickup_comment' ) );
} );

Поле пока необязательное. Обязательность зададим на этапе проверки, потому что она должна зависеть от выбранной доставки.

2. Проверяем выбранный способ доставки

add_action( 'woocommerce_checkout_process', function() {
    $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
    $chosen_method   = is_array( $chosen_methods ) && ! empty( $chosen_methods[0] ) ? $chosen_methods[0] : '';

    if ( strpos( $chosen_method, 'local_pickup' ) !== false ) {
        if ( empty( $_POST['pickup_comment'] ) ) {
            wc_add_notice( 'Для самовывоза укажите комментарий к заказу.', 'error' );
        }
    }
} );

Здесь используется проверка через strpos(), чтобы не зависеть от конкретного индекса метода. Это практичнее, чем жёстко сравнивать только local_pickup.

3. Сохраняем значение в заказе

add_action( 'woocommerce_checkout_create_order', function( $order, $data ) {
    if ( ! empty( $_POST['pickup_comment'] ) ) {
        $order->update_meta_data( '_pickup_comment', sanitize_textarea_field( wp_unslash( $_POST['pickup_comment'] ) ) );
    }
}, 10, 2 );

Санитизация обязательна. Даже если поле выглядит «обычным текстом», в заказ лучше сохранять уже очищенное значение.

4. Показываем комментарий в админке заказа

add_action( 'woocommerce_admin_order_data_after_billing_address', function( $order ) {
    $comment = $order->get_meta( '_pickup_comment' );

    if ( $comment ) {
        echo '<p><strong>Комментарий для самовывоза:</strong> ' . esc_html( $comment ) . '</p>';
    }
} );

Так менеджер увидит комментарий прямо в карточке заказа, без поиска по метаполям.

Если нужен более гибкий вариант

Иногда поле должно появляться только при самовывозе и исчезать при других способах доставки без перезагрузки страницы. Тогда можно добавить небольшой JS, который будет переключать обязательность и видимость поля на лету. Это полезно, если checkout часто меняется и вы не хотите заставлять клиента отправлять форму с лишними ошибками.

add_action( 'wp_footer', function() {
    if ( ! is_checkout() ) {
        return;
    }
    ?>
    <script>
    (function($){
        function togglePickupComment() {
            var method = $('input[name^="shipping_method"]:checked').val() || '';
            var field = $('#pickup_comment_field');
            var input = $('#pickup_comment');

            if ( method.indexOf('local_pickup') !== -1 ) {
                field.show();
                input.attr('required', 'required');
            } else {
                field.hide();
                input.removeAttr('required');
            }
        }

        $(document.body).on('updated_checkout change', togglePickupComment);
        $(togglePickupComment);
    })(jQuery);
    </script>
    <?php
} );

Этот вариант не заменяет серверную проверку. JS нужен только для удобства пользователя, а настоящая защита должна оставаться в woocommerce_checkout_process.

Сравнение подходов

ПодходПлюсыМинусыКогда выбирать
Плагин для checkout-формБыстро, без кодаЛишняя зависимость, возможны конфликты с темойЕсли нет доступа к разработке и нужна простая настройка
Код через хуки WooCommerceКонтроль логики, минимум лишнегоНужно тестировать после обновленийЕсли нужно точечное правило для самовывоза
Правка шаблона checkoutПолный контроль над версткойСложнее поддерживать, легко сломать обновлениямиЕсли форма сильно кастомизирована

Как проверить, что решение сработало

После внедрения пройдите тестовый заказ в двух сценариях: с самовывозом и с курьерской доставкой. В первом случае пустое поле должно блокировать оформление и показывать понятную ошибку. Во втором — заказ должен проходить без обязательного комментария.

  • Откройте checkout в режиме инкогнито, чтобы исключить влияние сохранённых сессий.
  • Выберите самовывоз и отправьте форму без комментария.
  • Проверьте, что WooCommerce показывает notice с ошибкой.
  • Заполните поле и завершите заказ.
  • Откройте заказ в админке и убедитесь, что комментарий сохранён в метаданных.

Если поле видно в форме, но заказ всё равно проходит без текста, значит серверная проверка не срабатывает. Обычно причина в неверном ID метода доставки или в том, что код вставлен не туда.

Частые ошибки и как их исправить

Проверяют только local_pickup, а метод имеет суффикс

В реальных магазинах метод доставки часто выглядит как local_pickup:1 или local_pickup:2. Если сравнение жёсткое, условие не выполнится. Используйте проверку через strpos() или сравнивайте с полным ID, который реально возвращает checkout.

Ставят обязательность только через HTML-атрибут required

Это не защита. Пользователь может обойти её, отключить JS или отправить форму нестандартным способом. Обязательная проверка должна быть на сервере, в woocommerce_checkout_process.

Сохраняют значение без санитизации

Если записывать $_POST напрямую, в заказ может попасть мусор или лишняя разметка. Для textarea используйте sanitize_textarea_field() и wp_unslash().

Не проверяют конфликт с плагинами checkout

Плагины для кастомизации оформления заказа могут переименовывать поля, менять структуру формы или отключать стандартные хуки. Если код не работает, временно отключите такие плагины и проверьте базовый сценарий на стандартной теме.

Что учесть по безопасности и производительности

Это небольшая доработка, но и здесь есть практические моменты. Не вставляйте код в произвольный плагин с автогенерацией сниппетов, если не понимаете, как он хранит и исполняет PHP. Лучше использовать собственный мини-плагин или дочернюю тему. Так проще контролировать версию и откатывать изменения.

Если на checkout уже много скриптов, не добавляйте лишний JavaScript без необходимости. В большинстве случаев серверной проверки достаточно, а JS нужен только для UX. И ещё: не отключайте стандартные скрипты WooCommerce на странице оформления заказа, иначе AJAX-обновление доставки может перестать работать.

Если вам нужно не только обязательное поле, но и более сложная логика checkout — например, разные поля для разных зон доставки или автоматические уведомления менеджеру — лучше сразу закладывать это в отдельный мини-плагин. Так код не расползётся по теме и не потеряется при обновлении шаблона.

Как создать уникальный фильтрованный список постов в WordPress с помощью WP_Query и AJAX
01.03.2026
Как удалить неиспользуемые метаданные в WordPress: практические решения и примеры
11.04.2026
Использование хука before_add_to_cart в WooCommerce для проверки товара перед добавлением в корзину
19.04.2026
WooCommerce: как запретить повторное создание заказа при наличии активного
03.06.2026
Как сделать обязательное поле комментария при выборе самовывоза в WooCommerce
03.09.2026