WhatsApp-уведомления о заказах WooCommerce через вебхуки
Обновлено
Письма о статусе заказа покупатели читают через раз, а WhatsApp открывают сразу. Если связать WooCommerce с wapi.kz, покупатель получает сообщение с номера магазина в момент, когда заказ принят, оплачен, собран или отменён. Ответить он может в тот же чат — и попадёт к живому менеджеру.
Страница для владельцев магазинов на WordPress и разработчиков. Нужен доступ к настройкам WooCommerce и место для PHP-файла — подойдёт тот же хостинг, где стоит сайт.
- Статус заказа изменился
- вебхук WooCommerce
- проверка подписи X-WC-Webhook-Signature
- POST /messages/send
- покупатель в WhatsApp
- Покупатель отвечает в WhatsApp
- вебхук wapi.kz
- ваш обработчик
- заметка к заказу
Что можно автоматизировать
- Заказ принят (
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).
Настройка по шагам
- Подключите номер магазина в wapi.kz (как подключить) и выпустите ключ номера.
- Положите обработчик (код ниже) рядом с сайтом, задайте переменные окружения
WC_SECRETиWAPI_KEY. - В WooCommerce → Настройки → Дополнительно → Webhooks добавьте вебхук: статус «Активен», тема «Заказ обновлён», URL доставки — адрес обработчика, секрет — длинная случайная строка.
- Сохраните. WooCommerce отправит пробный запрос — обработчик ответит 200.
- Оформите тестовый заказ со своим телефоном и смените статус в админке.
Пример кода
<?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 минут.