Частый сценарий: на странице товара или в отдельной форме клиент оставляет комментарий, номер договора, удобное время доставки или реквизиты, а эти данные нужно сохранить прямо в заказе WooCommerce. Не в письме, не в заметке менеджера, а в метаданных заказа, чтобы они были доступны в админке, в CRM-выгрузке и в дальнейшей обработке.
Если у вас уже есть форма WPForms и WooCommerce, самый надежный путь — сохранить нужные поля формы в заказ через пользовательский код. Это проще контролировать, чем пытаться «склеить» данные через уведомления или сторонние интеграции.
Когда это решение действительно нужно
Сценарий подходит, если форма используется как часть оформления заказа или как отдельная заявка, после которой создается заказ WooCommerce. Обычно это:
- дополнительные поля к заказу: комментарий к доставке, ИНН, название компании;
- предзаказ или заявка на расчет, где заказ создается вручную или автоматически;
- связка формы с конкретным товаром, вариантом доставки или услугой;
- сбор данных, которые должны храниться именно в заказе, а не в пользовательском профиле.
Если задача только в том, чтобы отправить письмо менеджеру, метаданные заказа не нужны. Если данные должны жить в заказе и быть доступны в админке WooCommerce, тогда этот вариант оправдан.
Диагностика: что проверить до правки кода
Перед внедрением убедитесь, что проблема не в самой форме или настройках WooCommerce. На практике чаще всего ломается не код, а привязка полей.
Проверьте саму форму WPForms
Нужно понять, какие поля вы хотите передавать. У каждого поля в WPForms есть ID, и именно по нему удобнее всего забирать значение из массива отправки. Откройте форму в конструкторе и запишите ID нужных полей: имя, телефон, комментарий, компания и т. д.
Проверьте, где создается заказ
Если заказ создается вручную после отправки формы, код должен срабатывать в момент создания заказа или при сохранении метаданных. Если заказ создается автоматически через кастомный обработчик, важно понимать, на каком этапе у вас уже есть объект WC_Order.
Проверьте, не дублируются ли данные
Если вы уже передаете эти же поля через checkout fields, не стоит сохранять их второй раз в разные мета-ключи без необходимости. Иначе в админке будет путаница: одно и то же поле окажется в нескольких местах.
Пошаговое решение: сохраняем поля WPForms в метаданные заказа
Ниже рабочая схема для случая, когда форма WPForms отправляется, а затем на ее основе создается заказ WooCommerce. Код можно разместить в мини-плагине или в functions.php дочерней темы. Для продакшена мини-плагин безопаснее.
1. Получите значения полей из отправки WPForms
WPForms передает данные формы в массиве, где значения доступны по ID полей. В примере ниже мы берем имя, телефон и комментарий. Замените ID на свои.
<?php
add_action( 'wpforms_process_complete', function( $fields, $entry, $form_data, $entry_id ) {
// Замените 123 на ID нужной формы.
if ( (int) $form_data['id'] !== 123 ) {
return;
}
// Пример: поля формы WPForms.
$customer_name = isset( $fields[1]['value'] ) ? sanitize_text_field( $fields[1]['value'] ) : '';
$customer_phone = isset( $fields[2]['value'] ) ? sanitize_text_field( $fields[2]['value'] ) : '';
$customer_note = isset( $fields[3]['value'] ) ? sanitize_textarea_field( $fields[3]['value'] ) : '';
// Здесь дальше можно передать данные в заказ.
// В этом примере мы сохраняем их в transient, чтобы использовать при создании заказа.
set_transient( 'wpforms_order_meta_' . $entry_id, array(
'customer_name' => $customer_name,
'customer_phone' => $customer_phone,
'customer_note' => $customer_note,
), 10 * MINUTE_IN_SECONDS );
}, 10, 4 );Этот кусок сам по себе еще не пишет данные в заказ. Он только сохраняет их временно, чтобы затем использовать при создании заказа. Такой подход полезен, если между отправкой формы и созданием заказа есть промежуточная логика.
2. Сохраните данные в order meta при создании заказа
Если у вас есть объект заказа, метаданные можно записать через update_meta_data(). Ниже пример, который добавляет данные в заказ и сохраняет их в базе WooCommerce.
<?php
add_action( 'woocommerce_checkout_create_order', function( $order, $data ) {
if ( ! is_a( $order, 'WC_Order' ) ) {
return;
}
// В реальном проекте данные обычно приходят из POST, сессии или временного хранилища.
if ( empty( $_POST['wpforms_entry_id'] ) ) {
return;
}
$entry_id = absint( wp_unslash( $_POST['wpforms_entry_id'] ) );
$meta = get_transient( 'wpforms_order_meta_' . $entry_id );
if ( empty( $meta ) || ! is_array( $meta ) ) {
return;
}
if ( ! empty( $meta['customer_name'] ) ) {
$order->update_meta_data( '_customer_name_from_wpforms', $meta['customer_name'] );
}
if ( ! empty( $meta['customer_phone'] ) ) {
$order->update_meta_data( '_customer_phone_from_wpforms', $meta['customer_phone'] );
}
if ( ! empty( $meta['customer_note'] ) ) {
$order->update_meta_data( '_customer_note_from_wpforms', $meta['customer_note'] );
}
}, 10, 2 );Здесь есть важный момент: woocommerce_checkout_create_order срабатывает на этапе создания заказа в checkout. Если заказ создается не через стандартную корзину, а из отдельной формы, вам нужно использовать тот хук, где у вас уже есть объект заказа. Логика записи в метаданные остается той же.
3. Покажите данные в админке заказа
Чтобы менеджер видел переданные поля не только в базе, но и в интерфейсе заказа, добавьте вывод в экран редактирования заказа.
<?php
add_action( 'woocommerce_admin_order_data_after_billing_address', function( $order ) {
if ( ! is_a( $order, 'WC_Order' ) ) {
return;
}
$name = $order->get_meta( '_customer_name_from_wpforms' );
$phone = $order->get_meta( '_customer_phone_from_wpforms' );
$note = $order->get_meta( '_customer_note_from_wpforms' );
if ( ! $name && ! $phone && ! $note ) {
return;
}
echo '<div class="wpforms-order-meta" style="margin-top:12px;">';
echo '<h4>Данные из WPForms</h4>';
if ( $name ) {
echo '<p><strong>Имя:</strong> ' . esc_html( $name ) . '</p>';
}
if ( $phone ) {
echo '<p><strong>Телефон:</strong> ' . esc_html( $phone ) . '</p>';
}
if ( $note ) {
echo '<p><strong>Комментарий:</strong> ' . nl2br( esc_html( $note ) ) . '</p>';
}
echo '</div>';
} );Если заказ создается не через checkout
На практике часто бывает так: WPForms используется как форма заявки, а заказ создается вручную менеджером или отдельным кодом. Тогда привязка к woocommerce_checkout_create_order не подойдет. В этом случае лучше сохранять данные формы в отдельную сущность, а потом переносить их в заказ при создании.
Самый простой вариант — хранить данные в post_meta или в пользовательской таблице, если заявок много и нужна отчетность. Для небольших проектов transient или post meta обычно достаточно.
Если заказ создается вручную, можно после создания вызвать:
<?php
$order->update_meta_data( '_customer_phone_from_wpforms', $phone );
$order->update_meta_data( '_customer_note_from_wpforms', $note );
$order->save();Это надежнее, чем пытаться «угадать» момент валидации формы или ловить отправку через JavaScript.
Проверка результата после внедрения
После добавления кода не ограничивайтесь тем, что форма просто отправилась без ошибки. Нужно проверить именно сохранение данных в заказе.
- Отправьте тестовую форму с уникальными значениями, которые легко найти в базе или в админке.
- Откройте созданный заказ в WooCommerce и проверьте блок с дополнительными данными.
- Если используете письма, убедитесь, что метаданные не попали в уведомление случайно дважды.
- Проверьте, что значения сохранились после повторного открытия заказа и после обновления страницы.
Если хотите убедиться на уровне базы, посмотрите таблицу wp_postmeta для нужного заказа. Метаключи должны быть записаны именно к ID заказа, а не к записи формы.
Частые ошибки и как их исправить
Неверный ID формы или поля
Самая банальная причина: код проверяет не тот ID формы или читает несуществующий ID поля. В результате условие срабатывает, но значения пустые. Сверьте ID в конструкторе WPForms и в массиве $fields.
Пытаются читать данные формы после редиректа без сохранения
Если вы не сохранили данные в transient, сессию или мета-запись, после редиректа они исчезнут. Нельзя рассчитывать, что значения формы останутся доступны сами по себе на следующем запросе.
Используют неподходящий хук WooCommerce
Если объект заказа еще не создан, update_meta_data() некуда применять. В таком случае нужно перенести код на более поздний этап, когда у вас уже есть WC_Order.
Не очищают и не экранируют значения
Даже если данные пришли из собственной формы, их нужно обрабатывать через sanitize_text_field() или sanitize_textarea_field(), а при выводе — через esc_html(). Это базовая защита от мусорных значений и проблем с разметкой.
Сохраняют все подряд без структуры
Если писать в заказ сырые массивы без понятных ключей, потом сложно поддерживать проект. Лучше сразу договориться о префиксе метаключей, например _customer_phone_from_wpforms, и использовать его везде одинаково.
Безопасность и производительность
Для такой интеграции не нужен тяжелый плагин-связка, если задача ограничена несколькими полями. Это уменьшает количество точек отказа и упрощает отладку.
- Не храните чувствительные данные в открытом виде, если это не требуется бизнес-процессом.
- Не дублируйте персональные данные в лишних мета-полях и письмах.
- Если форма доступна гостям, проверьте nonce и стандартную защиту WPForms от спама.
- Для сложной логики лучше вынести код в мини-плагин, а не в тему, чтобы он не пропал при смене шаблона.
Если на сайте уже много кастомной логики вокруг форм и заказов, полезно держать код в отдельном файле и подключать его через require_once. Так проще отключать и тестировать изменения без риска сломать тему.
Когда лучше использовать плагин, а когда код
| Подход | Плюсы | Минусы |
|---|---|---|
| Код в мини-плагине | Полный контроль, меньше зависимостей, легче отладка | Нужно поддерживать руками |
| Сторонний интегратор | Быстрый старт без разработки | Меньше гибкости, лишняя нагрузка, зависимость от обновлений |
| Кастомный checkout без WPForms | Единая логика оформления заказа | Не подходит, если форма уже используется в проекте |
Если у вас типовой сценарий с несколькими полями, код обычно выигрывает. Если же нужна сложная маршрутизация данных, лучше сначала проверить, не проще ли собрать это в одном checkout-потоке WooCommerce.
Для похожих задач по очистке дублирующихся данных и упрощению админки иногда полезно посмотреть инструменты вроде Clearfy Pro: https://wpshop.ru/plugins/clearfy. Но для самой передачи полей в заказ он не нужен — это именно вспомогательный инструмент, а не замена коду.