Перейти к содержимому
DedicatedPHP Контакт

Пользовательские поля на странице оформления заказа WooCommerce: от покупки до панели администратора

Узнайте, как добавить поля в классическую форму оформления заказа или Checkout Block, проверить данные на сервере и убедиться, что они попадают в заказ и панель администратора.

Пользовательское поле оформления заказа WooCommerce сохранено в заказе и доступно в панели администратора

Добавить поле на страницу оформления заказа — ещё не значит решить задачу, даже если оно отображается на экране. Чтобы поле было полезным, оно должно отвечать конкретной потребности, проходить проверку на сервере, сохраняться вместе с заказом и быть доступным людям или процессам, которым оно необходимо. На каждом этапе возможен отдельный сбой.

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

Решите, нужно ли собирать данные при оформлении заказа

Решите, нужно ли собирать данные при оформлении заказа — guía visual de DedicatedPHP

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

Зафиксируйте назначение поля, кто будет использовать его значение, является ли оно обязательным и как долго его нужно хранить. Проверьте, нет ли в WooCommerce стандартного поля для этой информации: дублирование адреса или телефона без определения приоритетного значения приводит к расхождениям. Для чувствительных данных или данных, обработка которых может иметь серьёзные последствия, ограничьте сбор и доступ к ним, а также проверьте применимые требования к конфиденциальности.

Определите сценарий и добавьте поле

На странице оформления заказа проверьте, используется ли классический шорткод [woocommerce_checkout] или Checkout Block. Также проверьте шаблоны и расширения, изменяющие эту страницу. Одного визуального распознавания недостаточно: расширение может менять сценарий или обработку данных. Реализуйте и проверьте соответствующий механизм и не предполагайте, что поле, созданное для одного сценария, будет работать и в другом.

Классическая форма оформления заказа: хуки полей и заказа

В классической форме можно изменять поля с помощью woocommerce_checkout_fields, выполнять проверку с помощью woocommerce_after_checkout_validation и сохранять данные при создании заказа с помощью woocommerce_checkout_create_order. В этом примере регистрируется необязательное поле, отклоняются нескалярные значения, а длина текста ограничивается 120 символами Unicode:

add_filter('woocommerce_checkout_fields', function ($fields) {
    $fields['order']['delivery_instructions'] = [
        'type'      => 'text',
        'label'     => 'Инструкции по доставке',
        'required'  => false,
        'priority'  => 25,
        'maxlength' => 120,
        'class'     => ['form-row-wide'],
    ];
    return $fields;
});

add_action('woocommerce_after_checkout_validation', function ($data, $errors) {
    $raw = $data['delivery_instructions'] ?? '';
    if (! is_scalar($raw)) {
        $errors->add('delivery_instructions', 'Значение должно быть текстом.');
        return;
    }

    $value = trim(sanitize_text_field((string) $raw));
    if (preg_match_all('/./us', $value, $matches) === false) {
        $errors->add('delivery_instructions', 'Недопустимый формат текста.');
        return;
    }
    if (count($matches[0]) > 120) {
        $errors->add('delivery_instructions', 'Текст не может содержать более 120 символов.');
    }
}, 10, 2);

add_action('woocommerce_checkout_create_order', function ($order, $data) {
    $raw = $data['delivery_instructions'] ?? '';
    if (! is_scalar($raw)) {
        return;
    }
    $value = trim(sanitize_text_field((string) $raw));
    if ($value !== '') {
        $order->update_meta_data('_delivery_instructions', $value);
    }
}, 10, 2);

Атрибут maxlength задаёт ограничение в браузере, но не заменяет проверку на сервере. В примере считаются кодовые точки Unicode с помощью выражения, совместимого с UTF-8; некоторые символы, например отдельные эмодзи, занимают в браузере больше одной единицы UTF-16. Если их нужно разрешить, явно определите и протестируйте правило подсчёта длины, чтобы поведение на стороне клиента и сервера не различалось.

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

Checkout Block: API дополнительных полей

Для Checkout Block используйте API дополнительных полей WooCommerce, а не добавляйте HTML непосредственно в форму. Зарегистрируйте поле из совместимого плагина или темы, например во время выполнения хука woocommerce_init:

add_action('woocommerce_init', function () {
    if (! function_exists('woocommerce_register_additional_checkout_field')) {
        return;
    }

    woocommerce_register_additional_checkout_field([
        'id'       => 'mi-plugin/delivery-instructions',
        'label'    => 'Инструкции по доставке',
        'location' => 'order',
        'type'     => 'text',
        'required' => false,
    ]);
});

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

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

Проверяйте, нормализуйте и сохраняйте данные на сервере

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

В классическом сценарии $order->update_meta_data() использует CRUD API заказа и позволяет не записывать данные напрямую в таблицы и не зависеть от конкретной структуры хранения. В Checkout Block поручите API дополнительных полей связывание поля с заказом и получайте значение через API заказа или документированный для этой интеграции механизм; не предполагайте, что знаете внутренний ключ метаданных.

Чтобы проверить совместимость, выясните в настройках WooCommerce, включено ли высокопроизводительное хранилище заказов (HPOS) или хранение на основе таблиц записей. В тестовой среде с такой же конфигурацией создайте по одному заказу для каждого сценария, получите его как объект WC_Order с помощью wc_get_order($order_id) и проверьте данные через CRUD API — например, для классического поля используйте $order->get_meta('_delivery_instructions'). Обновите заказ и прочитайте его снова; не выполняйте прямые SQL-запросы к внутренним таблицам. Повторяйте проверки после смены хранилища или обновления расширений, участвующих в оформлении заказа.

Проверьте данные в панели администратора

Рабочий способ проверки: создать тестовый заказ, открыть WooCommerce > Заказы, перейти к его редактированию и сравнить отображаемое значение с отправленным. Для классической формы, если метаданные не отображаются на экране, которым пользуется команда, можно добавить их вывод в административной части с помощью следующего хука данных заказа:

add_action('woocommerce_admin_order_data_after_billing_address', function ($order) {
    $value = $order->get_meta('_delivery_instructions');
    if ($value !== '') {
        echo '<p><strong>Инструкции по доставке:</strong> '
            . esc_html($value) . '</p>';
    }
});

Этот хук и метаданные из примера относятся к классической форме; проверьте их отображение в административном интерфейсе, используемом магазином. При HPOS и в блочном интерфейсе редактирования заказов проверьте фактический результат: не предполагайте, что расширение для классической панели автоматически поддерживает новый интерфейс. Для чтения и редактирования данных всегда используйте объект заказа и CRUD API.

Поля, зарегистрированные через API Checkout Block, могут отображаться в сведениях о заказе. Проверьте это в WooCommerce > Заказы на тестовом заказе. Если значение должно считываться другим кодом, найдите в документации API сведения о расположении поля и способе чтения для установленной версии; не угадывайте ключ метаданных. Если значение не отображается, добавьте совместимый с этим интерфейсом административный вывод и протестируйте его с настроенным хранилищем и установленными административными расширениями.

Если требуется редактирование, определите, каким ролям оно разрешено, и сохраняйте изменения через CRUD API заказа. Не выводите данные автоматически в письмах, документах, экспорте или общедоступных интерфейсах: добавляйте каждый канал только при наличии операционной необходимости, ограничивайте доступ и всегда экранируйте вывод.

Проверьте весь цикл и предотвратите регрессии

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

  • Корректный заказ с заполненным полем: проверить данные, сохранить их в нужном заказе и найти в панели администратора.
  • Пустое необязательное поле и отсутствующее обязательное поле: проверить заданное поведение для каждого случая.
  • Подменённое, нескалярное, слишком длинное или не входящее в список допустимых вариантов значение: подтвердить, что сервер его отклоняет.
  • Текст с диакритическими знаками и многобайтовыми символами, включая проверку точного предельного значения; также проверить взаимодействие с maxlength.
  • Обновление заказа: проверить, что меняется, кто может это изменить и как изменения распространяются дальше.
  • Классическая форма и Checkout Block: протестировать активный сценарий и все запланированные переключения между вариантами.
  • Права и раскрытие данных: проверить, что значение получают только авторизованные пользователи и процессы.

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

Контрольный список перед развёртыванием

Контрольный список перед развёртыванием — guía visual de DedicatedPHP
  • Задокументированы назначение данных и момент их сбора.
  • Механизм соответствует активному сценарию оформления заказа: хуки классического сценария или API дополнительных полей для Block.
  • Сервер проверяет тип, формат и длину; нескалярные значения отклоняются, а для отсутствующих, пустых и недопустимых данных определена обработка.
  • Определены установка WooCommerce и используемое хранилище заказов; чтение и обновление проверены через CRUD API.
  • Тестовый заказ подтверждает, что данные доступны на используемом экране панели администратора, а доступ к ним ограничен.
  • Тесты охватывают символы Unicode, обновления, ошибки, интеграции и регрессии оформления заказа.
Хотите применить эти идеи в своем проекте?Давайте обсудим вашу PHP-платформу.
Посмотреть связанные услуги