Как отправлять SMS о доставке через SMPP: API, DLR и повторы

Как отправлять SMS о доставке через SMPP: API, DLR и повторы

SMS-уведомления о заказах через SMPP строятся вокруг связки из трёх компонентов: API службы доставки, внутреннего обработчика статусов и SMS-шлюза. API передаёт событие, например создание отправления или готовность к выдаче, а SMPP доставляет текст на телефон клиента. В статье разберём архитектуру интеграции для служб доставки, настройку DLR, правила повторных попыток и контроль ошибок. Такой подход подходит интернет-магазину, пункту выдачи и сервису, который отправляет сообщения через Европочту, СДЭК или другую службу.

Как связать API службы доставки с SMPP?

Служба доставки обычно отдаёт статусы отправления через API. В зависимости от конкретной документации система может получать их по запросу или принимать через webhook. В обоих случаях бизнес-приложению нужен отдельный обработчик событий. Он сопоставляет номер заказа с телефоном клиента, выбирает шаблон SMS и передаёт сообщение в SMPP-шлюз.

Логика выглядит так: заказ получает статус «создан», «принят перевозчиком», «прибыл в пункт выдачи» или «передан курьеру». Обработчик проверяет, отправлялось ли уведомление по этому статусу, и формирует задачу на отправку. После этого приложение открывает SMPP-сессию, выполняет bind и передаёт сообщение командой submit_sm.

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

Если магазин уже отправляет SMS через HTTP API, переход на SMPP можно подготовить поэтапно: сначала вынести отправку в отдельный сервис, затем заменить транспорт, сохранив очередь и шаблоны. Практические вопросы такой миграции разобраны в материале как перейти с HTTP API на SMPP без потери SMS.

Какие параметры SMPP нужны для уведомлений о заказе?

До подключения разработчик получает от SMS-провайдера параметры SMPP-сессии: адрес шлюза, порт, логин, пароль, тип bind и допустимый sender. Приложение должно поддерживать соединение, обрабатывать ответы шлюза и восстанавливать сессию после разрыва. Пароль и настройки подключения хранят в конфигурации сервера, а не в исходном коде.

Команда submit_sm подтверждает, что шлюз принял сообщение на обработку. Она сама по себе не доказывает доставку на телефон. Для контроля результата провайдер возвращает DLR, то есть отчёт о статусе сообщения. Поэтому в запросе нужно включить получение delivery receipt и передать собственный идентификатор сообщения.

При кодировке текста учитывайте кириллицу. Длинное уведомление может разделиться на несколько SMS, а итоговое число частей зависит от выбранной кодировки и длины текста. В шаблоне оставляют только данные, которые нужны клиенту: статус, способ получения, ориентир по времени и номер заказа. Ссылку на страницу отслеживания лучше сокращать заранее, чтобы не расходовать длину сообщения на длинный адрес.

КомпонентЧто делаетЧто проверить при тестировании
API службы доставкиПередаёт изменение статуса отправленияЕсть ли идентификатор заказа, статус и время события
Обработчик событийВыбирает шаблон и ставит SMS в очередьНе создаётся ли повторная задача для одного статуса
SMPP-сессияПередаёт сообщение SMS-шлюзуОбрабатываются ли bind, submit_sm_resp и разрыв соединения
DLR-обработчикФиксирует результат доставкиСопоставляется ли receipt с исходным message_id

Как настроить DLR и отличить доставку от принятия?

DLR нужно сохранять отдельно от ответа на submit_sm. В базе полезно иметь как минимум состояния «создано», «принято шлюзом», «доставлено», «не доставлено» и «истёк срок ожидания». Ответ шлюза подтверждает приём сообщения, а DLR позже показывает результат попытки доставки. Разбор этой разницы и кодов ошибок приведён в статье почему SMS не доходит до клиента: разбор DLR в SMPP.

Обработчик DLR получает идентификатор сообщения, статус и технический текст ошибки, если оператор его передал. Идентификаторы иногда имеют разный формат: один шлюз возвращает число, другой добавляет префикс или меняет регистр. Поэтому при сопоставлении лучше нормализовать значение, но исходный DLR сохранять полностью для диагностики.

Для клиента достаточно понятного результата. Внутри системы сохраняют технический код, время получения отчёта и номер попытки. Если сообщение не доставлено, оператор интернет-магазина видит причину в журнале, а покупатель не получает несколько одинаковых уведомлений подряд.

Когда запускать повторную попытку отправки?

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

Для очереди задают ограничение по числу попыток и паузу между ними. Первая повторная отправка выполняется через короткий интервал, следующая через более длинный. Точное значение зависит от нагрузки и требований бизнеса, поэтому его проверяют на тестовом трафике. Одновременный запуск нескольких обработчиков не должен отправлять одну задачу дважды: помогает блокировка записи или уникальный идентификатор операции.

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

Как протестировать интеграцию до запуска?

Начните с тестового заказа и одного номера. Проверьте, что событие из API создаёт одну задачу, SMPP возвращает ответ, а DLR связывает результат с правильным заказом. Затем отдельно смоделируйте повторное событие от службы доставки и убедитесь, что второе SMS не появляется.

Проверьте четыре сценария: успешную доставку, временную ошибку, постоянную ошибку и разрыв SMPP-сессии. В журнале должны быть видны время события, идентификатор заказа, message_id, номер попытки и итоговый статус. Телефон клиента в технических логах лучше маскировать, чтобы оператор видел только необходимую часть номера.

Шаблоны проверяют на коротком и длинном тексте, с латиницей и кириллицей. Отдельно смотрят, сколько частей SMS сформировал шлюз. Для автоматизации статусов интернет-магазина полезно сопоставить эту схему с материалом как автоматизировать SMS-статусы доставки интернет-магазина через SMPP.

Типичные ошибки

  • Считать ответ submit_sm_resp подтверждением доставки абоненту.
  • Не сохранять message_id и потом не уметь связать DLR с заказом.
  • Отправлять SMS при каждом повторном событии API без проверки предыдущего статуса.
  • Повторять сообщение после постоянной ошибки номера.
  • Не ограничивать длину шаблона и получать несколько частей SMS вместо одной.
  • Перезапускать SMPP-сессию без контроля уже отправленных задач.

3 шага, которые можно сделать на этой неделе:

  1. Описать карту статусов службы доставки и выбрать, какие события действительно требуют SMS.
  2. Добавить очередь с message_id, номером попытки и отдельным обработчиком DLR.
  3. Провести тесты на успешной доставке, временной ошибке, постоянном отказе и повторном событии API.