OTP-код через SMPP отправляют так: приложение создаёт одноразовый код, передаёт его в SMS-шлюз по постоянному SMPP-соединению, а шлюз возвращает отчёт о доставке через DLR. В статье разберём схему интеграции, обязательные параметры SubmitSM, обработку статусов, повторные попытки и защиту соединения. После чтения разработчик сможет составить минимальный сценарий для регистрации, входа или подтверждения операции в сервисе малого бизнеса.
Как выглядит отправка OTP через SMPP?
В типовой схеме участвуют четыре компонента: приложение, OTP-сервис, SMPP-шлюз и мобильная сеть. Пользователь вводит номер телефона, приложение создаёт код и передаёт сообщение OTP-сервису. Тот формирует SMPP-запрос SubmitSM и отправляет его через установленное соединение.
Шлюз возвращает приложению message_id. Это значение нужно сохранить вместе с внутренним идентификатором операции: по нему позже связывают ответ шлюза с конкретной попыткой отправки. Отдельно приходит DLR, то есть Delivery Receipt. Он показывает, доставлено сообщение, отклонено, просрочено или ещё находится в обработке.
Для малого бизнеса удобнее начинать с одной простой операции: приложение создаёт код, отправляет его через отдельный сервисный модуль, а модуль возвращает результат постановки сообщения в очередь. Проверка кода должна происходить в приложении, потому что SMPP-шлюз отвечает за передачу SMS, а не за бизнес-логику авторизации.
Если соединение разрывается, модуль не должен автоматически считать OTP недоставленным. Сначала проверьте, был ли получен ответ на SubmitSM и сохранился ли идентификатор сообщения. Для наблюдения за реальной доставкой пригодится отдельный материал о мониторинге SMPP через DLR.
Какие параметры SubmitSM нужны для OTP?
Минимальный запрос содержит адресата, текст сообщения и параметры адресации. На практике разработчик также задаёт тип адреса отправителя, кодировку, срок действия и флаг запроса DLR. Точные значения зависят от настроек шлюза, поэтому их фиксируют в технической спецификации до начала тестов.
| Параметр | Зачем нужен | Что проверить |
|---|---|---|
| source_addr | Имя или номер отправителя | Разрешён ли такой Sender ID для маршрута |
| destination_addr | Номер получателя | Формат номера и отсутствие лишних символов |
| short_message | Текст с одноразовым кодом | Кодировка и длина сообщения |
| data_coding | Указывает кодировку текста | Совпадает ли значение с фактическим текстом |
| registered_delivery | Запрашивает отчёт о доставке | Возвращает ли шлюз DLR и в каком формате |
| validity_period | Ограничивает время жизни SMS | Не остаётся ли устаревший код в очереди |
| service_type | Передаёт назначение сообщения, если это поддерживает шлюз | Соответствует ли значение договорённой схеме |
Отдельно проверьте TON и NPI. Эти поля определяют тип и план нумерации адреса. Ошибка в них иногда выглядит как проблема маршрута: соединение установлено, SubmitSM принят, но сообщение не уходит дальше. Для белорусских номеров полезно заранее проверить параметры в руководстве по настройке TON/NPI в SMPP.
Текст OTP лучше сделать коротким: название сервиса, код и краткое ограничение по использованию. Не добавляйте в одно сообщение несколько действий. Например, приложение может сформировать строку вида: «Код для входа: 481927». Сам код должен быть связан с конкретной попыткой и иметь ограниченный срок действия.
Как обрабатывать ответ шлюза и DLR?
Ответ на SubmitSM подтверждает приём запроса шлюзом. Он не равен подтверждению доставки на телефон. Поэтому в базе или журнале интеграции нужны как минимум два события: результат постановки SMS в шлюз и итоговый статус из DLR.
| Событие | Что оно означает | Действие приложения |
|---|---|---|
| SubmitSM accepted | Шлюз принял запрос и вернул идентификатор | Сохранить message_id и ждать DLR |
| Delivery success | Шлюз получил подтверждение доставки | Закрыть попытку как доставленную |
| Temporary failure | Временная ошибка маршрута или сети | Запланировать повтор по правилам |
| Permanent failure | Шлюз отклонил сообщение окончательно | Остановить повторы и показать понятную ошибку |
| Expired | SMS не доставили до окончания срока жизни | Не отправлять устаревший код без нового запроса |
Формат DLR различается у шлюзов. Один провайдер передаёт отдельные поля, другой возвращает строку с кодом статуса, идентификатором и текстовым описанием. Поэтому обработчик должен сначала разобрать формат конкретного шлюза, затем привести статусы к единому внутреннему набору: delivered, temporary_failure, permanent_failure, expired и unknown.
Статус unknown нельзя автоматически считать успешным. Его лучше отправить в журнал для проверки. Если DLR пришёл с другим написанием идентификатора, система не найдёт сообщение и начнёт повторять отправку без необходимости. На тестовом стенде проверьте регистр символов, длину message_id и наличие дополнительных пробелов.
Для контроля соединения используйте Enquire Link. Этот служебный обмен помогает понять, отвечает ли SMPP-сессия, пока в очереди нет сообщений. Практическая настройка описана в материале про Enquire Link на SMPP-шлюзе.
Как настроить повторные попытки без дублирования?
Повтор нужен только при временной ошибке. Если шлюз вернул окончательный отказ или срок действия сообщения истёк, повтор того же OTP ухудшит сценарий: пользователь может получить несколько кодов и не понять, какой из них вводить.
Каждая попытка должна иметь свой внутренний идентификатор, время создания и причину повтора. При повторной отправке приложение обычно создаёт новую запись попытки, но связывает её с одной OTP-сессией. Так в журнале видно, сколько раз система обращалась к шлюзу и чем закончилась каждая попытка.
- Получите ответ SubmitSM и сохраните message_id.
- Дождитесь DLR в течение заданного приложением срока.
- Если статус временный, поставьте повтор в очередь с паузой.
- Перед повтором проверьте, не подтвердил ли шлюз доставку по первой попытке.
- После лимита повторов завершите OTP-сессию и предложите пользователю запросить новый код.
Пауза между попытками нужна для того, чтобы не отправлять одинаковые SMS подряд при кратковременном сбое. Её длительность задают в конфигурации, а не зашивают в код. Лимит также должен быть отдельным параметром. Это упрощает настройку для разных маршрутов и позволяет быстро остановить повторы при неполадках.
Если приложение не получило ответ на SubmitSM, ситуация неоднозначна: запрос мог не дойти до шлюза или шлюз мог принять его, но ответ потерялся. В таком случае повторная отправка создаёт риск двух одинаковых SMS. Для решения используют корреляцию запросов, журнал соединения и правила провайдера для повторной передачи. Без этих данных безопаснее завершить попытку технической ошибкой и попросить пользователя запросить новый код.
Как защитить SMPP-соединение и проверить интеграцию?
Учётные данные SMPP не стоит хранить в исходном коде. Их выносят в настройки окружения или защищённое хранилище конфигурации. Доступ к шлюзу ограничивают адресами сервера приложения, а журнал не должен содержать полный OTP-код.
Для соединения с внешним шлюзом настройте TLS, если его поддерживает согласованная конфигурация. Проверьте сертификат, имя узла и реакцию приложения на разрыв защищённой сессии. Отдельная инструкция по этой части собрана в материале о настройке TLS для SMPP.
Тестирование проводите по сценариям, а не одной успешной отправкой. Нужны минимум: успешная доставка, недоступный шлюз, временный отказ, окончательный отказ, истечение срока SMS, задержанный DLR и разрыв TCP-соединения. Для каждого сценария зафиксируйте ожидаемый статус, действие очереди и сообщение, которое увидит пользователь.
Какие ошибки чаще всего ломают OTP?
- Приложение считает ответ SubmitSM подтверждением доставки и не ждёт DLR.
- Обработчик не умеет сопоставлять DLR с message_id.
- Повтор запускается после любого сбоя, включая окончательный отказ.
- Для текста на кириллице выбрана неподходящая кодировка.
- Срок жизни SMS больше срока действия OTP, поэтому старый код приходит поздно.
- При переподключении система создаёт несколько SMPP-сессий и дублирует отправку.
Начните с небольшой тестовой очереди и подробного журнала событий. Когда SubmitSM, DLR, переподключение и повторы проходят проверку, вынесите параметры шлюза в конфигурацию и добавьте мониторинг задержек. Для бизнеса в Беларуси такой подход позволяет подключить техническую отправку OTP через SMPP без лишней логики внутри самого шлюза: приложение отвечает за код, SMPP — за передачу, DLR — за контроль результата.



