Как настроить отправку заказов WooCommerce в Telegram

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

Когда это действительно нужно

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

Есть три нормальных варианта реализации:

ВариантКогда подходитМинус
Плагин уведомленийНужно быстро без кодаМеньше контроля над текстом и логикой
Свой код через wp_remote_post()Нужен точный формат и фильтрацияНужно поддерживать код
Внешний webhook-сервисЕсть несколько каналов и маршрутизацияДополнительная зависимость

Если задача узкая — отправлять только новые заказы в один чат — код обычно надежнее и прозрачнее.

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

Прежде чем писать код, проверьте, что именно должно уходить в Telegram и откуда брать данные. В WooCommerce заказ может создаваться в разных статусах, а не только в processing. Если уведомление нужно именно при создании, лучше привязаться к событию создания заказа, а не к смене статуса.

Что проверить в первую очередь

  • Создается ли заказ в админке и какой у него начальный статус.
  • Есть ли у бота доступ к чату или каналу.
  • Известен ли корректный chat_id.
  • Не блокирует ли хостинг исходящие HTTP-запросы.
  • Не отключены ли внешние запросы через security-плагины или firewall.

Если вы не уверены в chat_id, сначала отправьте тестовое сообщение вручную через API Telegram. Без этого отладка превращается в угадайку.

Пошаговое решение через хук WooCommerce

Для отправки уведомления удобно использовать хук woocommerce_new_order. Он срабатывает после создания заказа и дает ID заказа, из которого можно собрать нужные данные.

1. Создайте мини-плагин или добавьте код в mu-plugin

Лучше не класть такую логику в functions.php темы: уведомления относятся к бизнес-логике, а не к оформлению. Если тема сменится, код не должен исчезнуть.

<?php
/**
 * Plugin Name: WC Telegram Order Notifications
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

add_action( 'woocommerce_new_order', 'wpmarket_send_order_to_telegram', 10, 1 );

function wpmarket_send_order_to_telegram( $order_id ) {
    $order = wc_get_order( $order_id );

    if ( ! $order ) {
        return;
    }

    $bot_token = '123456789:AAExampleTokenReplaceMe';
    $chat_id   = '-1001234567890';

    $items = array();
    foreach ( $order->get_items() as $item ) {
        $items[] = $item->get_name() . ' × ' . $item->get_quantity();
    }

    $message = sprintf(
        "Новый заказ #%1$s\nСумма: %2$s\nКлиент: %3$s\nТелефон: %4$s\nТовары: %5$s\nСсылка: %6$s",
        $order->get_order_number(),
        $order->get_formatted_order_total(),
        $order->get_formatted_billing_full_name(),
        $order->get_billing_phone(),
        implode( ', ', $items ),
        admin_url( 'post.php?post=' . $order_id . '&action=edit' )
    );

    $response = wp_remote_post(
        'https://api.telegram.org/bot' . $bot_token . '/sendMessage',
        array(
            'timeout' => 10,
            'body'    => array(
                'chat_id' => $chat_id,
                'text'    => $message,
            ),
        )
    );

    if ( is_wp_error( $response ) ) {
        error_log( 'Telegram error: ' . $response->get_error_message() );
    }
}

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

2. Добавьте защиту от дублей и вынесите настройки

Минимально безопасная доработка — хранить токен и chat_id в опциях и помечать заказ как уже отправленный. Тогда повторная отправка не будет происходить при редактировании заказа или повторных событиях.

<?php
add_action( 'woocommerce_new_order', 'wpmarket_send_order_to_telegram_safe', 10, 1 );

function wpmarket_send_order_to_telegram_safe( $order_id ) {
    if ( get_post_meta( $order_id, '_telegram_notified', true ) ) {
        return;
    }

    $bot_token = get_option( 'wpmarket_telegram_bot_token' );
    $chat_id   = get_option( 'wpmarket_telegram_chat_id' );

    if ( empty( $bot_token ) || empty( $chat_id ) ) {
        return;
    }

    $order = wc_get_order( $order_id );
    if ( ! $order ) {
        return;
    }

    $message = sprintf(
        "Новый заказ #%s\nСумма: %s\nИмя: %s\nТелефон: %s",
        $order->get_order_number(),
        wp_strip_all_tags( $order->get_formatted_order_total() ),
        $order->get_formatted_billing_full_name(),
        $order->get_billing_phone()
    );

    $response = wp_remote_post(
        'https://api.telegram.org/bot' . $bot_token . '/sendMessage',
        array(
            'timeout' => 10,
            'body'    => array(
                'chat_id' => $chat_id,
                'text'    => $message,
            ),
        )
    );

    if ( ! is_wp_error( $response ) ) {
        update_post_meta( $order_id, '_telegram_notified', current_time( 'mysql' ) );
    }
}

Если хотите хранить настройки в админке, используйте стандартные поля опций и register_setting(). Это не ускорит отправку, но сильно упростит поддержку.

Как проверить, что уведомления реально работают

Проверка должна идти не по ощущениям, а по факту доставки и по логам. Сначала создайте тестовый заказ в магазине, затем откройте чат в Telegram и убедитесь, что сообщение пришло именно от вашего бота.

  1. Оформите тестовый заказ с реальными данными.
  2. Проверьте, что заказ появился в WooCommerce.
  3. Посмотрите, не записалась ли ошибка в debug.log.
  4. Убедитесь, что в Telegram пришло одно сообщение без дублей.
  5. Откройте заказ в админке и проверьте, что мета-поле _telegram_notified установлено.

Если сообщения нет, сначала проверьте ответ Telegram API. Для этого временно залогируйте тело ответа:

<?php
if ( is_wp_error( $response ) ) {
    error_log( 'Telegram error: ' . $response->get_error_message() );
} else {
    error_log( wp_remote_retrieve_body( $response ) );
}

В ответе Telegram обычно видно, что именно не так: неверный токен, неправильный chat_id, бот не добавлен в группу или у него нет прав на отправку сообщений.

Частые ошибки и как их исправить

Неверный chat_id

Для групп и каналов chat_id часто начинается с -100. Если подставить ID пользователя вместо ID чата, сообщение уйдет не туда или не уйдет вообще. Проверяйте ID через getUpdates или через тестовый webhook.

Хук срабатывает не в тот момент

Если уведомление нужно только после успешной оплаты, woocommerce_new_order может быть слишком ранним. В таком случае логичнее использовать woocommerce_order_status_processing или woocommerce_order_status_completed — в зависимости от вашей бизнес-логики.

Сообщение уходит дважды

Это бывает, если код повешен на несколько хуков или заказ повторно сохраняется. Решение — флаг в метаданных заказа, как в примере выше, либо отдельная таблица логов отправки.

Падает форматирование текста

Telegram не любит «грязный» HTML и спецсимволы без экранирования. Если отправляете HTML-разметку, задайте parse_mode и экранируйте данные. Если формат не критичен, проще отправлять plain text.

Безопасность и производительность

Не храните токен бота в публичном репозитории и не вставляйте его в JS на фронтенде. Для продакшена лучше вынести секреты в wp-config.php или в настройки, доступные только администраторам.

Если заказов много, не отправляйте уведомление в рамках тяжелой синхронной операции. Telegram API обычно отвечает быстро, но в пиковые моменты лучше выносить отправку в очередь или хотя бы в отложенную задачу через wp_schedule_single_event(). Это уменьшает шанс, что пользователь увидит задержку на оформлении заказа.

Еще один практический момент: если на сайте стоит плагин безопасности, проверьте, не режет ли он исходящие запросы к api.telegram.org. На некоторых хостингах это тоже ограничено на уровне firewall.

Если нужен более гибкий сценарий

Когда уведомления нужны не только в Telegram, но и в другие каналы, удобнее строить логику через один внутренний обработчик и несколько отправителей. Тогда вы не размазываете бизнес-логику по разным хукам. Для магазинов, где важны еще и блоки доверия на карточках товара, можно дополнительно использовать решения вроде Clearfy Pro для чистки лишнего и снижения технического шума в админке, но саму отправку заказов он, конечно, не заменяет.

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

⭐⭐⭐⭐⭐