Интеграция WooCommerce с Новой Почтой: доставка, отделения, ТТН и API

Автор:vkuzyomko

Интеграция WooCommerce с Новой Почтой: доставка, отделения, ТТН и API

Краткий ответ: интеграция WooCommerce с Новой Почтой нужна, чтобы покупатель мог выбрать город, отделение, почтомат или адресную доставку прямо на checkout, а магазин мог автоматически сохранять данные доставки, рассчитывать стоимость, создавать экспресс-накладную, получать статус посылки и передавать информацию менеджеру. Сделать это можно через готовый плагин, API Новой Почты или кастомный модуль WooCommerce.

Причина

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

Из-за этого владелец магазина часто сталкивается с проблемами:

  • покупатель вводит отделение вручную с ошибками;
  • менеджер тратит время на ручное создание ТТН;
  • в заказе нет точного города или отделения;
  • адресная доставка работает отдельно от checkout;
  • стоимость доставки считается вручную;
  • статус посылки не обновляется в WooCommerce;
  • данные доставки не передаются в CRM;
  • после оформления заказа менеджеру приходится копировать телефон, город, склад и товары вручную.

Правильная интеграция решает не только выбор отделения. Она связывает checkout WooCommerce, API Новой Почты, заказ, оплату, CRM, уведомления и обработку доставки.

Диагностика

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

Задача Что нужно подключить Что проверить
Выбор города и отделения API справочников Новой Почты Города, отделения, почтоматы, язык
Адресная доставка Поля улицы, дома, квартиры Валидация адреса и обязательные поля
Расчёт стоимости Вес, объём, город отправителя и получателя Вес товаров, габариты, тип доставки
Создание ТТН / ЭН API InternetDocument Отправитель, получатель, места, вес, стоимость
Отслеживание посылки TrackingDocument Номер накладной и cron-обновление
Уведомления менеджеру Email, Telegram или CRM Куда отправлять номер ТТН и статус
Передача в CRM Webhook или REST API Маппинг полей заказа и доставки

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

Нужно быстро решить проблему на сайте?

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

Оставить заявку

Решение

1. Получить API-ключ Новой Почты

API-ключ нужен для работы с кабинетом отправителя. Через него сайт может обращаться к API Новой Почты и получать данные для доставки.

Обычно ключ получают в бизнес-кабинете Новой Почты:

  • зайти в кабинет Новой Почты;
  • открыть настройки;
  • найти раздел безопасности или API;
  • создать новый ключ;
  • сохранить ключ в закрытом месте;
  • не вставлять ключ в JavaScript или HTML.

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

2. Выбрать способ подключения

Есть три нормальных варианта интеграции WooCommerce с Новой Почтой.

Вариант Когда подходит Минусы
Готовый плагин Нужно быстро добавить выбор отделений и базовую доставку Может не хватать гибкости, логов и точной логики
Кастомный PHP-код Нужно добавить отдельную функцию или исправить конкретную проблему Нужно аккуратно тестировать checkout
Отдельный мини-плагин Нужны настройки, ТТН, статусы, логи, CRM, Telegram Требует разработки

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

3. Настроить поля checkout

На странице оформления заказа покупатель должен выбрать:

  • тип доставки: отделение, почтомат или адрес;
  • город получателя;
  • отделение или почтомат;
  • телефон получателя;
  • имя и фамилию;
  • комментарий, если он нужен менеджеру.

Плохой вариант — одно текстовое поле “Введите отделение”. В заказах быстро появятся ошибки: “НП 5”, “отд 7”, “склад возле рынка”, “новая почта центр”. Такие данные нельзя стабильно использовать для автоматического создания накладной.

Хороший вариант — выпадающий список или поиск по API, где в заказ сохраняется не только текст, но и технический Ref города и отделения.

4. Настроить доставку как метод WooCommerce

Для правильной архитектуры доставка Новой Почтой должна быть не просто набором полей, а отдельным shipping method WooCommerce.

Так можно:

  • показывать метод только для нужных зон доставки;
  • управлять стоимостью доставки;
  • делать бесплатную доставку от суммы заказа;
  • передавать выбранный метод в заказ;
  • корректно работать с checkout и оплатой;
  • не ломать стандартные механизмы WooCommerce.

5. Сохранять данные доставки в заказ

После оформления заказа нужно сохранить в meta заказа:

  • тип доставки Новой Почты;
  • название города;
  • Ref города;
  • название отделения;
  • Ref отделения;
  • номер ТТН / ЭН после создания;
  • статус доставки;
  • дату последнего обновления статуса.

Если сохранять только текст отделения, потом будет сложно создавать накладную, обновлять статус и передавать доставку в CRM.

Код

Важно: код ниже — пример технической основы. Он обращается к API Новой Почты и может влиять на checkout, заказы и доставку. Не вставляйте API-ключ в JavaScript или HTML. Проверяйте сначала на копии сайта.

1. Сохранить API-ключ в wp-config.php

Куда вставлять: файл 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/' );

2. Универсальная функция запроса к API Новой Почты

Куда вставлять: лучше в отдельный мини-плагин. Для быстрого теста можно вставить в 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',
            )
        );
    }
}

3. Получить список отделений по городу

Куда вставлять: в тот же мини-плагин или 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. Это может замедлить оформление заказа и создать лишнюю нагрузку.

4. Сохранить выбранное отделение в заказ

Куда вставлять: в мини-плагин или 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 );
    }
}

5. Показать данные Новой Почты в админке заказа

Куда вставлять: в тот же мини-плагин или 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 с Новой Почтой магазин должен работать без ручного копирования данных доставки.

Хороший результат выглядит так:

  • покупатель выбирает город и отделение на checkout;
  • в заказ сохраняется город, отделение и технические Ref;
  • менеджер видит данные Новой Почты в админке заказа;
  • стоимость доставки рассчитывается по понятным правилам;
  • ТТН / ЭН создаётся без ручного заполнения всех полей;
  • номер накладной сохраняется в заказе;
  • статус доставки можно обновлять автоматически;
  • ошибки API пишутся в WooCommerce logs;
  • checkout не тормозит из-за частых запросов к API;
  • данные можно передавать в CRM или Telegram.

Если после подключения доставки покупатель не может завершить заказ, нужно отдельно проверить checkout, оплату, кеш и JavaScript. Для этого подойдёт статья WooCommerce не оформляет заказ.

Дополнительные способы

Подключение через готовый плагин

Готовый плагин подходит, если нужно быстро добавить выбор города и отделения без разработки.

Перед установкой проверьте:

  • когда плагин обновлялся;
  • поддерживает ли он текущую версию WooCommerce;
  • есть ли выбор отделений и почтоматов;
  • есть ли адресная доставка;
  • создаёт ли плагин ТТН / ЭН;
  • сохраняет ли он Ref города и отделения;
  • есть ли лог ошибок API;
  • работает ли с кеш-плагином;
  • не ломает ли checkout;
  • можно ли передавать данные в CRM.

Подключение через кастомный shipping method

Кастомный shipping method нужен, если стандартные плагины не подходят.

Например:

  • нужно несколько отправителей;
  • разные склады для разных категорий товаров;
  • бесплатная доставка по сложным правилам;
  • отдельная логика для крупногабаритных товаров;
  • разные тарифы для разных городов;
  • интеграция с CRM, Telegram или учётной системой;
  • создание ТТН только после оплаты;
  • ручная повторная отправка API-запроса из заказа.

Автоматическое создание ТТН / ЭН

Автоматическое создание накладной лучше делать не сразу при клике “Оформить заказ”, а после нужного статуса заказа.

Например:

  • для оплаты картой — после успешной оплаты;
  • для наложенного платежа — после подтверждения менеджером;
  • для ручного заказа — после проверки данных;
  • для предзаказа — после появления товара на складе.

Так меньше ошибок: накладная не создаётся для неоплаченного, ошибочного или тестового заказа.

Обновление статуса доставки по cron

Статус доставки не обязательно проверять при каждом открытии админки. Лучше запускать cron-задачу по расписанию и обновлять только активные отправления.

Проверять можно заказы, где:

  • есть номер ТТН / ЭН;
  • заказ ещё не завершён;
  • доставка ещё не получена;
  • последняя проверка была достаточно давно;
  • нет постоянной ошибки API.

Это снижает нагрузку и делает интеграцию стабильнее.

Передача данных доставки в CRM

Если магазин работает через CRM, данные Новой Почты нужно передавать вместе с заказом.

В CRM обычно отправляют:

  • тип доставки;
  • город;
  • отделение;
  • адрес доставки;
  • номер ТТН / ЭН;
  • статус доставки;
  • стоимость доставки;
  • комментарий клиента.

Без этих данных CRM будет видеть продажу, но менеджер всё равно будет возвращаться в WooCommerce за деталями доставки.

Частые ошибки

Загружать все отделения сразу на checkout

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

Хранить API-ключ в JavaScript

API-ключ Новой Почты нельзя вставлять в frontend-код. Все запросы к API должны идти через сервер WordPress, а не напрямую из браузера покупателя.

Сохранять только текст отделения

Текст удобен человеку, но для API нужен технический идентификатор. Лучше сохранять и название, и Ref.

Создавать ТТН до подтверждения заказа

Если создавать накладную слишком рано, появятся лишние отправления для неоплаченных, тестовых и отменённых заказов.

Не логировать ошибки API

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

Не учитывать кеш checkout

Checkout, cart и AJAX-запросы WooCommerce нельзя кешировать как обычные страницы. Иначе доставка может показываться неправильно или не обновляться после выбора города.

Не проверять мобильную версию

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

Диагностика проблем

Не загружаются города Новой Почты

  • Проверьте API-ключ.
  • Проверьте endpoint API.
  • Проверьте WooCommerce logs.
  • Проверьте debug.log.
  • Проверьте, не блокирует ли хостинг внешние HTTP-запросы.
  • Проверьте, не истёк ли timeout запроса.
  • Проверьте формат JSON-запроса.

Не загружаются отделения

  • Проверьте, передаётся ли CityRef.
  • Проверьте, выбран ли город перед запросом отделений.
  • Проверьте кеш transient.
  • Проверьте, нет ли ошибки JavaScript на checkout.
  • Проверьте, не очищается ли поле города после обновления checkout.

Доставка не появляется на checkout

  • Проверьте зоны доставки WooCommerce.
  • Проверьте, включён ли метод доставки.
  • Проверьте страну доставки.
  • Проверьте вес и габариты товаров.
  • Проверьте, не скрывает ли метод кастомный код.
  • Проверьте конфликт с плагинами оплаты или скидок.

ТТН / ЭН не создаётся

  • Проверьте данные отправителя.
  • Проверьте данные получателя.
  • Проверьте телефон клиента.
  • Проверьте город и отделение.
  • Проверьте вес, количество мест и объявленную стоимость.
  • Проверьте ответ API Новой Почты.
  • Проверьте, не создаётся ли накладная раньше нужного статуса заказа.

Checkout стал медленным

  • Проверьте количество API-запросов на странице.
  • Добавьте кеширование городов и отделений.
  • Не загружайте все отделения сразу.
  • Не создавайте ТТН во время самого checkout.
  • Вынесите тяжёлые операции в фон.
  • Проверьте плагины кеша и оптимизации JavaScript.

Данные Новой Почты не попадают в заказ

  • Проверьте имена полей checkout.
  • Проверьте, отправляются ли поля в POST.
  • Проверьте хук woocommerce_checkout_create_order.
  • Проверьте sanitization полей.
  • Проверьте, не перезаписывает ли данные другой плагин доставки.

FAQ

Как подключить Новую Почту к WooCommerce?

Можно установить готовый плагин или сделать интеграцию через API Новой Почты. Для базовой задачи нужен API-ключ, выбор города и отделения на checkout, сохранение данных в заказ и настройка метода доставки WooCommerce.

Нужен ли API-ключ Новой Почты?

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

Можно ли создать ТТН автоматически?

Да. Но лучше создавать ТТН / ЭН не сразу при оформлении заказа, а после нужного статуса: оплата прошла, менеджер подтвердил заказ или заказ готов к отправке.

Можно ли добавить выбор отделения на checkout?

Да. Правильный вариант — поле поиска города, затем список отделений или почтоматов по выбранному городу. В заказ нужно сохранять не только название, но и технический Ref.

Почему отделения Новой Почты не отображаются?

Причина может быть в неверном API-ключе, пустом CityRef, ошибке JavaScript, блокировке внешних запросов на хостинге, проблеме кеша или неправильном формате API-запроса.

Можно ли рассчитать стоимость доставки Новой Почтой?

Да, но для расчёта нужны корректные данные: город отправителя, город получателя, вес, габариты, количество мест, объявленная стоимость и тип доставки. Если у товаров не заполнен вес, расчёт будет неточным.

Что лучше: готовый плагин или кастомная интеграция?

Готовый плагин подходит для простой доставки. Кастомная интеграция лучше, если нужны несколько складов, CRM, Telegram, автоматическое создание ТТН, статусы доставки, логи, очереди и нестандартная логика checkout.

Почему после подключения Новой Почты не оформляется заказ?

Чаще всего проблема в обязательных полях checkout, JavaScript, AJAX, кеше, конфликте плагинов или ошибке валидации доставки. Нужно проверить Console, Network, WooCommerce logs и debug.log.

Можно ли передавать данные Новой Почты в CRM?

Да. Обычно передают город, отделение, адрес, тип доставки, номер ТТН / ЭН, статус доставки и стоимость. Это помогает менеджеру работать с заказом без ручного копирования данных из WooCommerce.

Вывод

Интеграция WooCommerce с Новой Почтой — это не только поле “выберите отделение”. Нормальная интеграция должна связывать checkout, API Новой Почты, заказ WooCommerce, доставку, ТТН, статусы, CRM и уведомления.

Минимальный вариант — готовый плагин с выбором города и отделения. Более надёжный вариант — отдельный модуль, который хранит API-ключ безопасно, кеширует справочники, сохраняет Ref в заказ, пишет ошибки в лог, создаёт ТТН после нужного статуса и не тормозит оформление заказа.

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

Об авторе

vkuzyomko administrator