Краткий ответ: интеграция WooCommerce с Новой Почтой нужна, чтобы покупатель мог выбрать город, отделение, почтомат или адресную доставку прямо на checkout, а магазин мог автоматически сохранять данные доставки, рассчитывать стоимость, создавать экспресс-накладную, получать статус посылки и передавать информацию менеджеру. Сделать это можно через готовый плагин, API Новой Почты или кастомный модуль WooCommerce.
Стандартный WooCommerce не знает, как работать с отделениями Новой Почты. Он умеет показывать зоны доставки и методы доставки, но не загружает города, отделения, почтоматы, адреса, стоимость доставки и статусы отправлений из API Новой Почты.
Из-за этого владелец магазина часто сталкивается с проблемами:
Правильная интеграция решает не только выбор отделения. Она связывает checkout WooCommerce, API Новой Почты, заказ, оплату, CRM, уведомления и обработку доставки.
Перед подключением нужно понять, какая именно интеграция нужна магазину. Иногда достаточно простого выбора отделения. Иногда нужна полноценная автоматизация с созданием ЭН, отслеживанием и передачей данных в CRM.
| Задача | Что нужно подключить | Что проверить |
|---|---|---|
| Выбор города и отделения | API справочников Новой Почты | Города, отделения, почтоматы, язык |
| Адресная доставка | Поля улицы, дома, квартиры | Валидация адреса и обязательные поля |
| Расчёт стоимости | Вес, объём, город отправителя и получателя | Вес товаров, габариты, тип доставки |
| Создание ТТН / ЭН | API InternetDocument | Отправитель, получатель, места, вес, стоимость |
| Отслеживание посылки | TrackingDocument | Номер накладной и cron-обновление |
| Уведомления менеджеру | Email, Telegram или CRM | Куда отправлять номер ТТН и статус |
| Передача в CRM | Webhook или REST API | Маппинг полей заказа и доставки |
Если доставка через Новую Почту должна передаваться в CRM вместе с заказом, лучше сразу проектировать общую схему обмена данными. Похожая логика подробно разобрана в статье Интеграция WooCommerce с CRM.
Если не хотите рисковать сайтом и тратить время на эксперименты, можно оставить заявку. Я посмотрю задачу и предложу аккуратное решение.
API-ключ нужен для работы с кабинетом отправителя. Через него сайт может обращаться к API Новой Почты и получать данные для доставки.
Обычно ключ получают в бизнес-кабинете Новой Почты:
API-ключ нельзя показывать на frontend. Если ключ попадёт в исходный код страницы, его сможет увидеть любой посетитель сайта.
Есть три нормальных варианта интеграции WooCommerce с Новой Почтой.
| Вариант | Когда подходит | Минусы |
|---|---|---|
| Готовый плагин | Нужно быстро добавить выбор отделений и базовую доставку | Может не хватать гибкости, логов и точной логики |
| Кастомный PHP-код | Нужно добавить отдельную функцию или исправить конкретную проблему | Нужно аккуратно тестировать checkout |
| Отдельный мини-плагин | Нужны настройки, ТТН, статусы, логи, CRM, Telegram | Требует разработки |
Если нужна только базовая доставка, готовый плагин может закрыть задачу. Если нужны нестандартные поля, несколько отправителей, разные склады, CRM, автоматическое создание ТТН и лог ошибок, лучше делать отдельную доработку WooCommerce.
На странице оформления заказа покупатель должен выбрать:
Плохой вариант — одно текстовое поле “Введите отделение”. В заказах быстро появятся ошибки: “НП 5”, “отд 7”, “склад возле рынка”, “новая почта центр”. Такие данные нельзя стабильно использовать для автоматического создания накладной.
Хороший вариант — выпадающий список или поиск по API, где в заказ сохраняется не только текст, но и технический Ref города и отделения.
Для правильной архитектуры доставка Новой Почтой должна быть не просто набором полей, а отдельным shipping method WooCommerce.
Так можно:
После оформления заказа нужно сохранить в meta заказа:
Ref города;Ref отделения;Если сохранять только текст отделения, потом будет сложно создавать накладную, обновлять статус и передавать доставку в CRM.
Важно: код ниже — пример технической основы. Он обращается к API Новой Почты и может влиять на checkout, заказы и доставку. Не вставляйте API-ключ в JavaScript или HTML. Проверяйте сначала на копии сайта.
Куда вставлять: файл wp-config.php, выше строки /* That's all, stop editing! */.
define( 'SC_NP_API_KEY', 'your_nova_poshta_api_key_here' );
define( 'SC_NP_API_URL', 'https://api.novaposhta.ua/v2.0/json/' );
Куда вставлять: лучше в отдельный мини-плагин. Для быстрого теста можно вставить в functions.php дочерней темы.
function sc_np_api_request( $model_name, $called_method, $method_properties = array() ) {
if ( ! defined( 'SC_NP_API_KEY' ) || ! defined( 'SC_NP_API_URL' ) ) {
return array(
'success' => false,
'data' => array(),
'errors' => array( 'Nova Poshta API constants are not defined.' ),
);
}
$body = array(
'apiKey' => SC_NP_API_KEY,
'modelName' => $model_name,
'calledMethod' => $called_method,
'methodProperties' => $method_properties,
);
$response = wp_remote_post(
SC_NP_API_URL,
array(
'timeout' => 12,
'headers' => array(
'Content-Type' => 'application/json',
),
'body' => wp_json_encode( $body ),
)
);
if ( is_wp_error( $response ) ) {
sc_np_log_error( 'API request error: ' . $response->get_error_message() );
return array(
'success' => false,
'data' => array(),
'errors' => array( $response->get_error_message() ),
);
}
$response_code = wp_remote_retrieve_response_code( $response );
$response_body = wp_remote_retrieve_body( $response );
$decoded = json_decode( $response_body, true );
if ( $response_code < 200 || $response_code >= 300 ) {
sc_np_log_error( 'Bad API response code: ' . $response_code . '. Body: ' . $response_body );
return array(
'success' => false,
'data' => array(),
'errors' => array( 'Bad API response code: ' . $response_code ),
);
}
if ( ! is_array( $decoded ) ) {
sc_np_log_error( 'Invalid API JSON response: ' . $response_body );
return array(
'success' => false,
'data' => array(),
'errors' => array( 'Invalid API JSON response.' ),
);
}
if ( empty( $decoded['success'] ) ) {
$errors = array();
if ( ! empty( $decoded['errors'] ) && is_array( $decoded['errors'] ) ) {
$errors = $decoded['errors'];
}
sc_np_log_error( 'Nova Poshta API error: ' . implode( '; ', $errors ) );
}
return $decoded;
}
function sc_np_log_error( $message ) {
if ( function_exists( 'wc_get_logger' ) ) {
wc_get_logger()->error(
$message,
array(
'source' => 'sc-nova-poshta',
)
);
}
}
Куда вставлять: в тот же мини-плагин или functions.php дочерней темы.
function sc_np_get_warehouses_by_city_ref( $city_ref ) {
$city_ref = sanitize_text_field( $city_ref );
if ( empty( $city_ref ) ) {
return array();
}
$cache_key = 'sc_np_warehouses_' . md5( $city_ref );
$cached = get_transient( $cache_key );
if ( is_array( $cached ) ) {
return $cached;
}
$result = sc_np_api_request(
'AddressGeneral',
'getWarehouses',
array(
'CityRef' => $city_ref,
)
);
if ( empty( $result['success'] ) || empty( $result['data'] ) || ! is_array( $result['data'] ) ) {
return array();
}
set_transient( $cache_key, $result['data'], 12 * HOUR_IN_SECONDS );
return $result['data'];
}
Кеширование здесь важно. Не нужно каждый раз загружать список отделений из API при каждом открытии checkout. Это может замедлить оформление заказа и создать лишнюю нагрузку.
Куда вставлять: в мини-плагин или functions.php дочерней темы. Поля np_city_name, np_city_ref, np_warehouse_name, np_warehouse_ref должны приходить из вашей формы checkout.
add_action( 'woocommerce_checkout_create_order', 'sc_np_save_checkout_delivery_fields', 20, 2 );
function sc_np_save_checkout_delivery_fields( $order, $data ) {
if ( ! $order instanceof WC_Order ) {
return;
}
$np_city_name = isset( $_POST['np_city_name'] ) ? sanitize_text_field( wp_unslash( $_POST['np_city_name'] ) ) : '';
$np_city_ref = isset( $_POST['np_city_ref'] ) ? sanitize_text_field( wp_unslash( $_POST['np_city_ref'] ) ) : '';
$np_warehouse_name = isset( $_POST['np_warehouse_name'] ) ? sanitize_text_field( wp_unslash( $_POST['np_warehouse_name'] ) ) : '';
$np_warehouse_ref = isset( $_POST['np_warehouse_ref'] ) ? sanitize_text_field( wp_unslash( $_POST['np_warehouse_ref'] ) ) : '';
if ( ! empty( $np_city_name ) ) {
$order->update_meta_data( '_sc_np_city_name', $np_city_name );
}
if ( ! empty( $np_city_ref ) ) {
$order->update_meta_data( '_sc_np_city_ref', $np_city_ref );
}
if ( ! empty( $np_warehouse_name ) ) {
$order->update_meta_data( '_sc_np_warehouse_name', $np_warehouse_name );
}
if ( ! empty( $np_warehouse_ref ) ) {
$order->update_meta_data( '_sc_np_warehouse_ref', $np_warehouse_ref );
}
}
Куда вставлять: в тот же мини-плагин или functions.php дочерней темы.
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'sc_np_show_delivery_data_in_admin' );
function sc_np_show_delivery_data_in_admin( $order ) {
if ( ! $order instanceof WC_Order ) {
return;
}
$city_name = $order->get_meta( '_sc_np_city_name' );
$warehouse_name = $order->get_meta( '_sc_np_warehouse_name' );
$ttn = $order->get_meta( '_sc_np_ttn' );
$status = $order->get_meta( '_sc_np_delivery_status' );
if ( empty( $city_name ) && empty( $warehouse_name ) && empty( $ttn ) ) {
return;
}
echo '<div class="sc-np-order-box">';
echo '<h3>Новая Почта</h3>';
if ( ! empty( $city_name ) ) {
echo '<p><strong>Город:</strong> ' . esc_html( $city_name ) . '</p>';
}
if ( ! empty( $warehouse_name ) ) {
echo '<p><strong>Отделение:</strong> ' . esc_html( $warehouse_name ) . '</p>';
}
if ( ! empty( $ttn ) ) {
echo '<p><strong>ТТН / ЭН:</strong> ' . esc_html( $ttn ) . '</p>';
}
if ( ! empty( $status ) ) {
echo '<p><strong>Статус:</strong> ' . esc_html( $status ) . '</p>';
}
echo '</div>';
}
После правильной интеграции WooCommerce с Новой Почтой магазин должен работать без ручного копирования данных доставки.
Хороший результат выглядит так:
Ref;Если после подключения доставки покупатель не может завершить заказ, нужно отдельно проверить checkout, оплату, кеш и JavaScript. Для этого подойдёт статья WooCommerce не оформляет заказ.
Готовый плагин подходит, если нужно быстро добавить выбор города и отделения без разработки.
Перед установкой проверьте:
Ref города и отделения;Кастомный shipping method нужен, если стандартные плагины не подходят.
Например:
Автоматическое создание накладной лучше делать не сразу при клике “Оформить заказ”, а после нужного статуса заказа.
Например:
Так меньше ошибок: накладная не создаётся для неоплаченного, ошибочного или тестового заказа.
Статус доставки не обязательно проверять при каждом открытии админки. Лучше запускать cron-задачу по расписанию и обновлять только активные отправления.
Проверять можно заказы, где:
Это снижает нагрузку и делает интеграцию стабильнее.
Если магазин работает через CRM, данные Новой Почты нужно передавать вместе с заказом.
В CRM обычно отправляют:
Без этих данных CRM будет видеть продажу, но менеджер всё равно будет возвращаться в WooCommerce за деталями доставки.
Это плохая идея. Список отделений большой, и его нельзя каждый раз грузить целиком. Лучше искать отделения по выбранному городу и кешировать результат.
API-ключ Новой Почты нельзя вставлять в frontend-код. Все запросы к API должны идти через сервер WordPress, а не напрямую из браузера покупателя.
Текст удобен человеку, но для API нужен технический идентификатор. Лучше сохранять и название, и Ref.
Если создавать накладную слишком рано, появятся лишние отправления для неоплаченных, тестовых и отменённых заказов.
Если нет логов, непонятно, почему не загрузились отделения или не создалась ТТН: неверный ключ, пустой город, ошибка формата, недоступность API или проблема хостинга.
Checkout, cart и AJAX-запросы WooCommerce нельзя кешировать как обычные страницы. Иначе доставка может показываться неправильно или не обновляться после выбора города.
Большая часть покупателей оформляет заказ с телефона. Если поиск города или отделения неудобен на мобильном, интеграция технически есть, но продажи всё равно теряются.
debug.log.CityRef.woocommerce_checkout_create_order.Можно установить готовый плагин или сделать интеграцию через API Новой Почты. Для базовой задачи нужен API-ключ, выбор города и отделения на checkout, сохранение данных в заказ и настройка метода доставки WooCommerce.
Да, если сайт должен получать города, отделения, создавать накладные, рассчитывать доставку или отслеживать отправления через API. Для простого ручного поля API-ключ не нужен, но такая схема неудобна и даёт много ошибок.
Да. Но лучше создавать ТТН / ЭН не сразу при оформлении заказа, а после нужного статуса: оплата прошла, менеджер подтвердил заказ или заказ готов к отправке.
Да. Правильный вариант — поле поиска города, затем список отделений или почтоматов по выбранному городу. В заказ нужно сохранять не только название, но и технический Ref.
Причина может быть в неверном API-ключе, пустом CityRef, ошибке JavaScript, блокировке внешних запросов на хостинге, проблеме кеша или неправильном формате API-запроса.
Да, но для расчёта нужны корректные данные: город отправителя, город получателя, вес, габариты, количество мест, объявленная стоимость и тип доставки. Если у товаров не заполнен вес, расчёт будет неточным.
Готовый плагин подходит для простой доставки. Кастомная интеграция лучше, если нужны несколько складов, CRM, Telegram, автоматическое создание ТТН, статусы доставки, логи, очереди и нестандартная логика checkout.
Чаще всего проблема в обязательных полях checkout, JavaScript, AJAX, кеше, конфликте плагинов или ошибке валидации доставки. Нужно проверить Console, Network, WooCommerce logs и debug.log.
Да. Обычно передают город, отделение, адрес, тип доставки, номер ТТН / ЭН, статус доставки и стоимость. Это помогает менеджеру работать с заказом без ручного копирования данных из WooCommerce.
Интеграция WooCommerce с Новой Почтой — это не только поле “выберите отделение”. Нормальная интеграция должна связывать checkout, API Новой Почты, заказ WooCommerce, доставку, ТТН, статусы, CRM и уведомления.
Минимальный вариант — готовый плагин с выбором города и отделения. Более надёжный вариант — отдельный модуль, который хранит API-ключ безопасно, кеширует справочники, сохраняет Ref в заказ, пишет ошибки в лог, создаёт ТТН после нужного статуса и не тормозит оформление заказа.
Если доставка влияет на продажи, её нельзя настраивать “примерно”. Покупатель должен быстро выбрать нужное отделение, менеджер должен видеть точные данные в заказе, а владелец магазина должен понимать, где искать ошибку, если доставка или API перестали работать.
Об авторе