Как настроить callback для статуса доставки SMS
Пошагово: выберите сценарий, изучите модель провайдера, подготовьте HTTPS endpoint и сопоставьте данные payload со своей системой.

Выберите подходящий сценарий callback
Начните с одного вопроса: что именно callback должен изменить в вашем бизнесе? Для уведомлений о заказе, контроля доставки OTP или сообщений клиентам ответ обычно разный. Магазину может быть важно состояние «доставлено» до отправки чека. Банку может быть важно «не удалось» в течение 30 секунд, потому что код входа, который так и не дошёл, напрямую влияет на нагрузку поддержки.
Этот выбор важен ещё до того, как вы тронете настройки. Если вы хотите настроить callback статуса доставки SMS, сначала выберите один рабочий сценарий и сформулируйте результат простыми словами: подтвердить доставку, заметить сбои или отслеживать задержки. Позже один callback может поддерживать все три варианта, но первая версия должна отвечать на один практический вопрос.
Сузьте область применения. Команде доставки могут быть нужны обновления статуса только для финального SMS в цепочке, а не для каждого напоминания. Потоку сброса пароля callback может понадобиться только тогда, когда сообщение принято или отклонено, потому что состояние «в ожидании» бесполезно для пользователя, который уже смотрит на экран входа.
Уточните модель callback у вашего SMS-провайдера
У разных провайдеров логика не одинаковая. Одни используют delivery receipts, другие — webhooks, а третьи дают URL статуса, который нужно опрашивать. Изучите документацию провайдера, чтобы понять точные названия событий и доступные статусы. Если вам нужен webhook для статуса доставки SMS, проверьте, какие именно поля и события он передаёт.
Один провайдер может отправлять только финальные состояния. Другой — несколько обновлений по одному сообщению, и это позже меняет то, как вы будете хранить данные. Если провайдер поддерживает и callback на уровне сообщения, и callback на уровне аккаунта, выберите тот, который соответствует сценарию, определённому выше. Эта деталь избавит от путаницы, когда придёт первый тест и приложение увидит два события по одному SMS.
Здесь есть небольшая ловушка. В документации часто приводят один JSON-пример, а реальный аккаунт возвращает немного другую структуру для другого тарифного уровня. Сравните заметки по API, подписи в панели и любые примерные payloads, прежде чем подключать endpoint. Если у провайдера есть отдельная документация по delivery receipts, прочитайте и её. В некоторых командах это называют callback delivery receipts SMS, и смысл здесь тот же: сверить формат заранее.
Для команд, которые уже работают с другими событийными системами, шаблон покажется знакомым. Логика похожа на события email webhook для транзакционных писем: нужно понимать, какие события существуют, какие из них вам важны и какие никогда не должны запускать клиентскую логику.
Подготовьте публичный endpoint для callback
Endpoint для callback должен иметь публичный HTTPS-адрес. Не локальный порт. Не приватный IP. Провайдер должен достучаться до него из-за пределов вашей сети, и большинство SMS-платформ в продакшене не примут обычный HTTP. Часто используют структуру /webhooks/sms/status, потому что она остаётся понятной, когда логи и дашборды начинают заполняться.
Сделайте маршрут стабильным. Если вы будете переименовывать его каждую неделю, настройки в панели отстанут от кода. Для первой версии используйте один путь, один метод и один обработчик. Обычно выбирают POST.
Принимайте входящие запросы, не блокируя их на медленной обработке. Endpoint должен прочитать запрос, проверить базовые вещи и быстро ответить. Тяжёлая обработка должна уходить в очередь задач или фоновый процесс. Тогда всплеск callback-ов не будет держать соединение открытым настолько долго, чтобы начались повторные попытки.
Перед подключением провайдера проверьте маршрут простым телом запроса. Ответ 200 на тестовый POST говорит больше, чем длинная отладка позже. Если вы уже хорошо знакомы с проектированием callback-ов в других каналах, та же дисциплина проявляется в лучших практиках web push-уведомлений, особенно в части времени ответа и понятности endpoint.
Определите, какие данные из payload нужны вашему приложению
Не сохраняйте каждое поле только потому, что его прислал провайдер. Сначала сопоставьте callback с вашей внутренней моделью. Минимум большинству команд нужны ID сообщения, получатель, статус, время и код ошибки. Некоторые провайдеры также добавляют данные о операторе, стране или reference шлюза, и это может помочь при разборе обращений.
Сделайте сопоставление строгим. Если провайдер называет поле sms_id, а в вашей базе оно называется provider_message_id, один раз напишите перевод и используйте его повторно. Это избавляет от проблем «в staging работает», когда подключается вторая интеграция. Payload callback должен обновлять одну запись SMS, а не создавать загадочные дубликаты.
Думайте не только о текущем статусе, но и об истории состояний. Одно сообщение может пройти путь от accepted к sent и delivered, либо от queued к failed. Если слишком рано свести это к одному текстовому полю, вы потеряете след, объясняющий, почему код пришёл поздно. Этот след важен, когда клиент говорит: «Я его так и не получил», а поддержке нужно больше, чем пожатие плечами.
Для команд, которые уже управляют идентичностью отправителя и доверием к сообщениям в email, та же дисциплина полей встречается в настройке DKIM SPF DMARC для транзакционных и другой работе по аутентификации. Модель данных другая, но привычка та же: фиксировать поля, которые доказывают, что произошло.
Зарегистрируйте callback в настройках SMS
Большинство провайдеров позволяют указать URL callback в панели или через настройку API. Некоторые сначала требуют настройки на уровне аккаунта, а затем дают переопределения на уровне сообщений. Ищите подписи вроде delivery callback, status callback, webhook URL или receipt URL. Формулировка отличается, цель — нет.
Используйте точные названия полей провайдера, когда их запрашивает панель. URL для событий доставки может быть отдельным от URL для входящих ответов. Если смешать их, приложение может начать получать данные, которые не умеет интерпретировать. Это простая ошибка, и она достаточно распространена, чтобы включить её в чеклист.
Здесь могут иметь значение права доступа. Для изменения настроек callback может понадобиться аккаунт администратора, либо API-ключу может требоваться scope на запись. Если панель просит подтверждение перед сохранением, завершите этот шаг до запуска кода. Иначе callback может выглядеть «настроенным», хотя ни один запрос так и не дойдёт до endpoint.
После сохранения настройки отправьте одно сообщение из того же аккаунта или tenant, который используете в продакшене. Callback, настроенный не в том workspace, — это скучная ошибка, а скучные ошибки хороши только тем, что их проще исправить, чем те, которые молча проходят мимо.
Защитите и аутентифицируйте входящие запросы
Никогда по умолчанию не доверяйте телу запроса. Проверьте общий секретный токен, заголовок подписи, allowlist IP-адресов или подписанный timestamp — в зависимости от того, что поддерживает ваш провайдер. Одного из этих методов может быть достаточно, но многие команды комбинируют две проверки для лучшего контроля.
Проверка подписи должна происходить до любой записи в базу. Если подпись не проходит, отклоните запрос и залогируйте попытку. Если провайдер передаёт timestamp, сравните его с часами сервера, чтобы снизить риск повторной отправки. Callback, присланный вчера, не должен приниматься сегодня только потому, что формат всё ещё выглядит валидным.
Allowlist IP-адресов звучит просто, пока провайдер не поменяет инфраструктуру. Используйте его только если провайдер публикует фиксированные диапазоны и обновляет их. Секретные токены обычно проще поддерживать, а проверка подписи надёжнее, чем один статический токен. Небольшая ремарка: если ваша команда безопасности просит все три метода, это не потому, что они драматизируют.
Не забывайте и о защите канала передачи. HTTPS — это базовый уровень. Сертификаты должны быть действительными, а редиректов лучше избегать, если провайдер их не обрабатывает. Это один из тех шагов, который кажется скучным, пока первый злоумышленник не попытается отправлять в систему фальшивые обновления доставки.
Сохраняйте обновления доставки в своей системе
Сохраняйте каждый callback в исходной записи SMS, используя message ID провайдера и свой внутренний ID. Эта связь — ключ ко всем последующим отчётам. Без неё придётся искать по номеру телефона, а это быстро становится неудобным, когда в нескольких кампаниях используется один и тот же получатель.
Записывайте изменения статуса по порядку. Если провайдер отправляет queued, затем sent, затем delivered, сохраняйте именно эту последовательность. Если более старый callback приходит с опозданием, игнорируйте его или сравнивайте с последним известным состоянием перед сохранением. Запоздалое обновление «sent» не должно перезаписывать более новый статус «delivered».
Если возможно, храните и время провайдера, и локальное время получения. Первое помогает при внешнем трассировании. Второе помогает при инцидентах, когда ваш сервер сам был медленным или кратковременно недоступным. Такое сочетание даёт достаточно деталей, чтобы ответить на обращение в поддержку без догадок.
Небольшая таблица может помочь команде договориться о работе со статусами:
| Статус провайдера | Внутреннее действие | Пример последствия |
|---|---|---|
| queued | Сохранить начальную запись | Сообщение ожидает отправки |
| sent | Отметить начало передачи | Оператор принял сообщение |
| delivered | Отметить доставку завершённой | Пользователь, вероятно, получил SMS |
| failed | Сохранить код и причину ошибки | Запустить поддержку или логику повторной попытки |
Подумайте и о последующей аналитике. Если команде customer success нужны показатели доставки по кампаниям, храните рядом с сообщением ID кампании. Если финансам нужно сверять объём OTP, сохраняйте название шаблона. Маленькие поля экономят долгие совещания.
Настройте уведомления и резервную обработку
Callback-и ломаются предсказуемо: endpoint возвращает 500, проверка подписи начинает отклонять всё подряд, или провайдер перестаёт отправлять запросы для конкретного аккаунта. Поставьте алерт на каждый из этих случаев. Если callback не приходит по сообщению в разумный срок, это сигнал, который стоит отправить в pager или хотя бы по email.
Настройте один алерт на «callbacks остановились», второй на «проверка подписи не прошла» и третий на «получен статус ошибки». Это три разные проблемы. Отсутствие callback-а может означать сетевые неполадки. Неудачный статус может означать, что оператор отклонил SMS. Ошибка проверки может означать, что секрет был обновлён, а провайдера не предупредили.
Продумайте резервный путь. Если провайдер поддерживает polling, используйте его, когда callback-и отсутствуют или задерживаются. Polling не должен быть первым выбором, но он лучше слепых зон. Некоторые команды опрашивают статус только для сообщений высокой важности, например OTP или подтверждений платежей, чтобы лишний трафик оставался под контролем.
Если ваша команда уже отслеживает сигналы доставляемости в других каналах, похожие привычки применимы в лучших практиках обработки email bounce. Канал другой, но операционная реакция та же: следить за ошибками, аккуратно логировать их и решать, когда повторять попытку, когда отправлять алерт, а когда останавливаться.
Один раз опишите правило fallback и дайте его прочитать support-команде. Клиент не должен гадать, будет ли неудачное SMS отправлено повторно автоматически. Если ответ «не для OTP», скажите это прямо. Если ответ «проверить через 10 минут», запишите точное число один раз и используйте его везде.
На этой странице
← Все статьиОдин клик. По нему мы понимаем, о чём писать дальше.
Оценок пока нет — ваша будет первой.
Комментарии
Комментарии читаем перед публикацией.