Интеграция · через API и вебхуки

WhatsApp-уведомления о заказах WooCommerce через вебхуки

Обновлено

Письма о статусе заказа покупатели читают через раз, а WhatsApp открывают сразу. Если связать WooCommerce с wapi.kz, покупатель получает сообщение с номера магазина в момент, когда заказ принят, оплачен, собран или отменён. Ответить он может в тот же чат — и попадёт к живому менеджеру.

Страница для владельцев магазинов на WordPress и разработчиков. Нужен доступ к настройкам WooCommerce и место для PHP-файла — подойдёт тот же хостинг, где стоит сайт.

Из WooCommerce в WhatsApp
  1. Статус заказа изменился
  2. вебхук WooCommerce
  3. проверка подписи X-WC-Webhook-Signature
  4. POST /messages/send
  5. покупатель в WhatsApp
Из WhatsApp в WooCommerce
  1. Покупатель отвечает в WhatsApp
  2. вебхук wapi.kz
  3. ваш обработчик
  4. заметка к заказу

Что можно автоматизировать

  • Заказ принят (processing) — номер заказа, сумма и что будет дальше.
  • Ждём оплату (on-hold) — для оплаты переводом: реквизиты или куда прислать чек.
  • Заказ выполнен (completed) — спасибо за покупку и контакт для вопросов.
  • Заказ отменён (cancelled) — коротко о причине и предложение помочь оформить заново.
  • Новый заказ — менеджеру. Отдельный вебхук на тему «Заказ создан» присылает менеджеру в WhatsApp состав и сумму заказа.
  • Счёт или чек файлом. Если плагин создаёт PDF по публичной ссылке, его можно отправить документом (про файлы).

Как это устроено

Со стороны WooCommerce: вебхуки настраиваются в разделе WooCommerce → Настройки → Дополнительно → Webhooks. Тема «Заказ обновлён» срабатывает на любое изменение заказа и присылает его целиком в JSON: id, number, status, total, currency, billing.first_name, billing.phone. Каждый запрос подписан: заголовок X-WC-Webhook-Signature содержит base64 от HMAC-SHA256 тела с вашим секретом. Проверка подписи гарантирует, что запрос пришёл от вашего магазина, а не от того, кто узнал адрес.

Со стороны wapi.kz — POST /messages/send (документация).

Важный нюанс: «Заказ обновлён» приходит и при смене статуса, и при правке адреса или заметки. Предыдущего статуса в теле нет, поэтому обработчик хранит, о каком статусе уже сообщил, и не пишет покупателю дважды.

Обратный путь — по желанию: вебхук номера wapi.kz присылает ответ покупателя, обработчик находит его последний заказ по телефону и добавляет заметку через REST API WooCommerce (POST /wp-json/wc/v3/orders/{id}/notes).

Настройка по шагам

  1. Подключите номер магазина в wapi.kz (как подключить) и выпустите ключ номера.
  2. Положите обработчик (код ниже) рядом с сайтом, задайте переменные окружения WC_SECRET и WAPI_KEY.
  3. В WooCommerce → Настройки → Дополнительно → Webhooks добавьте вебхук: статус «Активен», тема «Заказ обновлён», URL доставки — адрес обработчика, секрет — длинная случайная строка.
  4. Сохраните. WooCommerce отправит пробный запрос — обработчик ответит 200.
  5. Оформите тестовый заказ со своим телефоном и смените статус в админке.

Пример кода

PHP
<?php
// wc-hook.php — вебхук WooCommerce «Заказ обновлён»
$raw = file_get_contents('php://input');
if (str_starts_with($raw, 'webhook_id=')) exit; // пробный запрос при сохранении вебхука — просто 200
$sig = base64_encode(hash_hmac('sha256', $raw, getenv('WC_SECRET'), true));
if (!hash_equals($sig, $_SERVER['HTTP_X_WC_WEBHOOK_SIGNATURE'] ?? '')) {
    http_response_code(401);
    exit;
}

$order = json_decode($raw, true);
if (empty($order['id'])) exit;

$texts = [
    'processing' => 'Заказ №%s на %s принят. Сообщим, когда передадим в доставку.',
    'on-hold'    => 'Заказ №%s на %s ждёт оплаты. Пришлите чек в ответ на это сообщение.',
    'completed'  => 'Заказ №%s на %s выполнен. Спасибо за покупку!',
    'cancelled'  => 'Заказ №%s на %s отменён. Если это ошибка — ответьте, поможем.',
];
$status = $order['status'];
if (!isset($texts[$status])) exit;

// Храним, о каком статусе уже сообщили (в бою — таблица в базе)
$file = __DIR__ . '/wc-sent.json';
$sent = is_file($file) ? json_decode(file_get_contents($file), true) : [];
if (($sent[$order['id']] ?? '') === $status) exit;

$phone = preg_replace('/\D/', '', $order['billing']['phone'] ?? '');
if (strlen($phone) === 11 && $phone[0] === '8') $phone = '7' . substr($phone, 1);
if (strlen($phone) === 10) $phone = '7' . $phone;   // 701 123 45 67 без кода страны
if (strlen($phone) < 11) exit;

$sum = $order['total'] . ($order['currency'] === 'KZT' ? ' ₸' : ' ' . $order['currency']);
$name = trim($order['billing']['first_name'] ?? '');
$text = ($name !== '' ? "$name, " : '') . sprintf($texts[$status], $order['number'], $sum);

$ch = curl_init('https://wapi.kz/api/v1/messages/send');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('WAPI_KEY'), 'Content-Type: application/json'],
    CURLOPT_POSTFIELDS => json_encode(['to' => $phone, 'text' => $text], JSON_UNESCAPED_UNICODE),
    CURLOPT_TIMEOUT => 15,
]);
$res = json_decode(curl_exec($ch), true);

if (!empty($res['ok'])) {
    $sent[$order['id']] = $status;
    file_put_contents($file, json_encode($sent), LOCK_EX);
} else {
    error_log('wapi: ' . ($res['code'] ?? 'no_response') . ' — ' . ($res['error'] ?? ''));
}

Файл wc-sent.json держите вне публичной папки сайта или закройте к нему доступ. Если магазин на одном сервере с обработчиком, есть альтернатива без вебхуков — хук WordPress woocommerce_order_status_changed в своём плагине: он сразу передаёт старый и новый статус.

Ограничения

  • Готового плагина wapi.kz для WooCommerce нет — работает ваш обработчик или плагин, который мы настроим по заявке.
  • Телефон в заказе покупатели вводят как попало. Сделайте поле обязательным и подскажите формат, иначе часть сообщений не уйдёт с ошибкой invalid_to.
  • Лимиты номера: 1 сообщение в секунду, первые сообщения новым покупателям — не чаще раза в 5 секунд и с суточным потолком, в первые 2 недели — прогрев (лимиты). При распродаже с сотнями заказов в час часть уведомлений встанет в ошибку — ставьте отправку в очередь.
  • Если обработчик несколько раз подряд не ответил, WooCommerce может отключить вебхук — проверяйте его статус в настройках.
  • Входящие фото от покупателей (например, чек) в событии не приходят — там hasMedia: true, а сам файл сохраняется у нас: ссылка на него — в media.url сообщения GET /messages/{id}, и он виден на телефоне.

Не хотите писать код? Зарегистрируйтесь, подключите номер и оставьте заявку из кабинета — подключим уведомления. Номер — 9 900 ₸ в месяц, без платы за сообщения (цены). Больше идей для магазинов — на странице для интернет-магазинов.

Частые вопросы

Зачем проверять подпись, если адрес и так никто не знает?

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

Почему покупателю пришло два одинаковых сообщения?

«Заказ обновлён» срабатывает на любую правку заказа. Если обработчик не хранит отправленные статусы, каждое изменение даст новое сообщение. В коде выше это решено файлом wc-sent.json.

Можно ли писать покупателям о скидках и акциях?

Только тем, кто сам на это согласился и ждёт таких сообщений. Холодные массовые сообщения быстро снижают индекс доверия номера и ведут к блокировке.

Работает ли это с другими платёжными статусами и плагинами?

Да, если плагин ставит заказу свой статус — добавьте его в массив $texts. Названия статусов видны в поле status вебхука.

Подключите WhatsApp к WooCommerce

9 900 ₸ в месяц за номер, без платы за сообщения. Сервер в Казахстане, оплата Kaspi или счётом на ТОО/ИП. Подключение — около 5 минут.

Гайды по теме

Другие интеграции