Поля оформления заказа и проверка
Форма оформления заказа состоит из полей: имя, адрес, телефон, комментарий. Лишние поля убирают, обязательность меняют, свои — добавляют. В классическом оформлении (шорткод [woocommerce_checkout]) всё это делает один фильтр; для блочного в конце урока есть замена.
Код урока пишется в includes/checkout.php.
Убрать и изменить поле
// wp-content/plugins/acme-shop/includes/checkout.php
add_filter('woocommerce_checkout_fields', function (array $fields): array {
unset($fields['billing']['billing_company']);
$fields['billing']['billing_phone']['required'] = true;
return $fields;
});Фильтр получает все поля формы, сгруппированные по разделам, и возвращает изменённый массив. Откройте /checkout/: поле «Название компании» исчезло, а у телефона появилась звёздочка обязательного поля.
Разделы формы
| Раздел | Что в нём | Пример ключа |
|---|---|---|
billing | Платёжные данные | billing_first_name, billing_email |
shipping | Адрес доставки | shipping_city, shipping_postcode |
order | Дополнительно | order_comments |
Своё поле
// wp-content/plugins/acme-shop/includes/checkout.php
add_filter('woocommerce_checkout_fields', function (array $fields): array {
$fields['order']['acme_delivery_note'] = [
'type' => 'textarea',
'label' => 'Комментарий курьеру',
'placeholder' => 'Код домофона, этаж',
'required' => false,
'priority' => 20,
];
return $fields;
});Под полем «Примечание к заказу» появится ещё одно. Параметр type принимает text, textarea, select, checkbox, email, tel; priority задаёт порядок внутри раздела.
Проверка
// wp-content/plugins/acme-shop/includes/checkout.php
add_action('woocommerce_after_checkout_validation', function (array $data, WP_Error $errors) {
$digits = preg_replace('/\D/', '', $data['billing_phone'] ?? '');
if (strlen($digits) < 10) {
$errors->add('acme_phone', 'Укажите телефон полностью, с кодом города.');
}
}, 10, 2);Хук срабатывает после стандартных проверок, когда покупатель нажал «Подтвердить заказ». В $data — значения полей, в $errors добавляют свои ошибки. Введите телефон 123: заказ не оформится, а над формой появится ваше сообщение.
Сохранение в заказ
Значение собственного поля нужно записать в заказ самим:
// wp-content/plugins/acme-shop/includes/checkout.php
add_action('woocommerce_checkout_create_order', function (WC_Order $order, array $data) {
if (!empty($data['acme_delivery_note'])) {
$order->update_meta_data('_acme_delivery_note', sanitize_textarea_field($data['acme_delivery_note']));
}
}, 10, 2);Хук вызывается перед сохранением заказа, поэтому save() не нужен.
Показ в панели
// wp-content/plugins/acme-shop/includes/checkout.php
add_action('woocommerce_admin_order_data_after_shipping_address', function (WC_Order $order) {
$note = $order->get_meta('_acme_delivery_note');
if ($note !== '') {
echo '<p><strong>Курьеру:</strong> ' . esc_html($note) . '</p>';
}
});Оформите заказ с комментарием и откройте его в «WooCommerce → Заказы»: текст виден под адресом доставки.
Блочное оформление
В блочном варианте фильтр woocommerce_checkout_fields и хук проверки не вызываются. Поле регистрируют отдельной функцией:
// wp-content/plugins/acme-shop/includes/checkout.php
add_action('woocommerce_init', function () {
woocommerce_register_additional_checkout_field([
'id' => 'acme/delivery-note',
'label' => 'Комментарий курьеру',
'location' => 'order',
'type' => 'text',
'required' => false,
]);
});Идентификатор состоит из приставки плагина и имени через косую черту. location — раздел формы: contact, address или order. Сохраняет значение и показывает его в заказе и письмах сам WooCommerce. Поддерживаются типы text, select и checkbox.
Частая ошибка
Поле добавили фильтром, а хук woocommerce_checkout_create_order — нет. Покупатель заполняет поле, заказ создаётся, но значение нигде не сохранено. В классическом оформлении сами сохраняются только стандартные поля адреса; для своих нужен отдельный хук.