Search by

waix / waix-php

ivanpukhov

WAIX WhatsApp API v1: messages, templates, OTP and signed webhooks

v0.2.0 2026-09-23 08:34 UTC

This package is auto-updated.

Last update: 2026-09-23 17:05:11 UTC


README

English

Клиент WAIX для PHP 8.1 и новее. Нужны расширения cURL и JSON. Установка через Composer, пространство имён Waix, автозагрузка PSR-4.

Установка

composer require waix/waix-php:^0.2

Пакет Packagist · Исходный код

Дополнительный VCS-репозиторий в настройках Composer не нужен.

Перед первым запросом

Подключите номер в WAIX, получите Connection ID и серверный ключ с правом messages:write. Пример использует одобренный шаблон order_ready на русском языке с одной переменной в теле.

Отправка шаблона

<?php
require 'vendor/autoload.php';

$waix = new Waix\Client(getenv('WAIX_API_KEY'));
// $eventId — UUID, уже сохранённый в записи заказа или очереди уведомлений.
$result = $waix->messages->send([
    'connection_id' => getenv('WAIX_CONNECTION_ID'),
    'to' => '+77071234567',
    'type' => 'template',
    'template' => [
        'name' => 'order_ready',
        'language' => ['code' => 'ru'],
        'components' => [['type' => 'body', 'parameters' => [['type' => 'text', 'text' => '42']]]],
    ],
], $eventId);

OTP: отправка и проверка

$otp = new Waix\Client(getenv('WAIX_OTP_PROJECT_KEY'));
$sent = $otp->otp->send(['to' => '+77071234567', 'ttl' => 300], $eventId);
// Сохраните $sent['data']['id'] в серверной сессии пользователя.
$status = $otp->otp->status($sent['data']['id']);
// $suppliedCode — код, введённый пользователем в той же сессии.
$verified = $otp->otp->verify($sent['data']['id'], $suppliedCode);

Ошибки, файлы и параметры клиента

Перехватывайте Waix\WaixError. Поля: status (0 при сетевой ошибке), errorCode, requestId, retryAfter, body. Таймаут задаётся в миллисекундах:

$waix = new Waix\Client(getenv('WAIX_API_KEY'), timeoutMs: 30000);

Загрузка файла: $waix->media->upload($connectionId, '/path/invoice.pdf', 'application/pdf', ['type'=>'document']).

Пагинация: $waix->messages->list(['limit'=>50, 'before'=>$cursor, 'before_id'=>$cursorId]).

Проверка вебхука: Waix\Webhook::verify($rawBody, $timestampHeader, $signatureHeader, $secret).

Разработка

Запустите composer validate --strict и composer test. Контрактные тесты подменяют транспорт и не отправляют сообщения клиентам. Проверка выпуска также запускает cURL против локального HTTP-сервера и проверяет запрет перенаправлений.

Какие методы есть

Раздел Возможности
Сообщения Отправка, список с пагинацией, просмотр, явный повтор
Подключения Список номеров, чтение и изменение профиля компании
Шаблоны Список, просмотр, создание, изменение, удаление, предварительный просмотр
Медиа Загрузка файла, список, получение URL, удаление
Вебхуки Чтение и изменение настроек, тест, удаление, смена секрета
OTP Отправка кода, проверка, статус запроса

Все запросы идут на https://waix.kz/api/v1. SDK возвращает полный JSON-ответ: data, а также pagination, если она есть. Для остальных операций API v1 можно использовать метод request с относительным путём. Не передавайте в него адрес, полученный от непроверенного пользователя.

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

Повторные запросы и доставка

Создайте UUID один раз при записи события в своей базе. Передайте его как ключ идемпотентности. При потере ответа повторяйте запрос с тем же UUID и теми же параметрами: новый ключ означает новое сообщение.

HTTP 202 означает, что сообщение поставлено в очередь. Доставку проверяйте по вебхуку, журналу WAIX или методу просмотра сообщения. У SDK нет автоматических повторов и переходов по HTTP redirect. Для 429 учитывайте Retry-After; ошибки 400, 401, 403 требуют исправления параметров или доступа. Сообщение со статусом outcome_unknown нельзя повторять вслепую.

Проверка подписи вебхука

Передавайте в функцию проверки исходные байты тела HTTP-запроса до разбора JSON, заголовки X-Waix-Timestamp, X-Waix-Signature и секрет вебхука. Подпись: HMAC-SHA256 от timestamp + "." + rawBody, с префиксом v1=. Сравнение выполняется за постоянное время; допустимое отклонение времени по умолчанию — 300 секунд.

Отклоняйте неверную подпись. Повторные события определяйте по X-Waix-Delivery: верная подпись сама по себе не защищает от повторной доставки в пределах допустимого времени. Сначала надёжно сохраните событие, затем ответьте кодом 2xx.

Ключи, OTP и данные клиентов

  • Храните ключи на сервере. Не включайте их в код сайта, мобильного приложения или общий файл сценария. Выдавайте только нужные права.
  • Для первого сообщения клиенту обычно нужен одобренный шаблон. Произвольный текст разрешён в рамках действующего окна обслуживания Meta. Проверяйте согласие клиента и учитывайте отказ от сообщений.
  • OTP использует отдельный ключ проекта. Начните с sandbox: он возвращает test_code и не отправляет сообщение WhatsApp. Тестовый код нельзя показывать человеку, чью личность вы проверяете.
  • Сохраните ID OTP-запроса в серверной сессии пользователя. Проверять код должна именно эта сессия. Выдавайте доступ только после успешной проверки; ограничивайте попытки по аккаунту и IP.
  • Для рабочих OTP нужны доступный тариф и одобренный отправитель. Проверьте их состояние в кабинете WAIX до включения реальной отправки.
  • SDK не записывает ключи, сообщения и коды в лог. Если добавляете свои логи, скрывайте эти данные и сохраняйте request_id для диагностики.

Документация и поддержка

Документация WAIX · Поддержка · Тарифы.

SDK работает с API v1 WAIX. Это не клиент Meta Graph API. Версии SDK следуют SemVer. Лицензия — MIT.

Поведение версии 0.2.0

SDK не повторяет запрос за вас. HTTP-ошибка от прокси остаётся HTTP-ошибкой, даже если вместо JSON пришёл HTML: сохраняются статус, request ID и Retry-After. Перенаправления запрещены. Некорректный успешный ответ вызывает INVALID_RESPONSE; ответ больше установленного лимита — RESPONSE_TOO_LARGE. Лимит по умолчанию — 2 МиБ, его можно увеличить до 16 МиБ.

Ситуация Что делать
400 / 422 Исправить поля, формат телефона, шаблон или код OTP.
401 / 403 Проверить ключ, права и принадлежность подключения/OTP-проекта.
409 Проверить конфликт ключа идемпотентности: под одним ключом нельзя менять тело.
429 Отложить запрос на срок из Retry-After, сохранив прежний ключ и тело.
5xx, TIMEOUT, TRANSPORT_ERROR Результат отправки может быть неизвестен. Сначала проверить сохранённый ID; если ID не получен, повторять прежний запрос с прежним ключом через ограниченную очередь повторов.
INVALID_RESPONSE / RESPONSE_TOO_LARGE Проверить прокси, адрес API и размер страницы. Не создавать новую отправку.
OTP_INVALID Код неверен, истёк или уже использован. Не выдавать сессию приложения.

body исключения доступен для диагностики, но может содержать данные клиента. В журнал записывайте только безопасные метаданные из примера ниже. Не сериализуйте целиком ответ sandbox OTP.

Обновление с 0.1.x

Имена существующих методов сохранены. У otp.verify код должен быть строкой из шести цифр: '012345', а не число. Значения query — только строки, конечные числа и boolean; сложные объекты нужно разобрать на параметры. Ошибки HTML от прокси теперь имеют API_ERROR, а перенаправления — REDIRECT_DISALLOWED. При обработке ошибок ориентируйтесь также на HTTP-статус.

Пагинация и диагностика

$waix = new Waix\Client(getenv('WAIX_API_KEY'), timeoutMs: 30000, maxResponseBytes: 2097152);
foreach ($waix->messages->iterate(['connection_id' => $connectionId, 'limit' => 100], maxPages: 100) as $message) {
    saveStatus($message['id'], $message['status']);
}

Генератор запрашивает страницы по мере чтения, переносит оба курсора и сохраняет фильтры. Повторный курсор вызывает INVALID_PAGINATION; достижение maxPagesPAGINATION_LIMIT. По умолчанию предел — 1000 страниц.

try {
    $result = $waix->messages->get($savedMessageId);
} catch (Waix\WaixError $error) {
    error_log(json_encode($error, JSON_THROW_ON_ERROR)); // только безопасные метаданные
    $delayMs = $error->retryDelayMs(); // миллисекунды или null
    // Решение о повторе принимает ваша очередь.
}

SDK использует cURL с проверкой TLS. timeoutMs ограничивает весь запрос, подключение — максимум 10 секунд. Сертификаты на сервере должны быть актуальны; отключать их проверку не нужно.