Реализация

Подтверждение номера телефона в мобильном приложении

В мобильном приложении подтверждение номера звонком удобнее, чем где-либо ещё: набор открывается одним касанием через системный диалер, пользователю не нужно ничего переписывать и вводить. Главное преимущество перед обычным flash call — приложению не требуются разрешения на чтение SMS и журнала вызовов, а их выдачу ограничивают и Google Play, и App Store. Проверка живёт 60 секунд, стоит 0,20 ₽ за состоявшийся звонок.

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

Чем подтверждение в приложении отличается от сайта

Главное отличие одно, и оно решающее: приложение может открыть набор номера в одно касание. Пользователь нажимает кнопку — открывается системный диалер с уже подставленным номером, остаётся нажать вызов.

На сайте с десктопа так не получится: номер придётся переносить на телефон руками, и это худшая точка сценария. В приложении её просто нет.

Второе отличие — контроль над экраном. Приложение точно знает, когда пользователь вернулся из диалера, и может проверить статус именно в этот момент, а не по таймеру. Переход к следующему шагу получается мгновенным.

Третье — обратная сторона: приложение уходит на задний план во время вызова, и это надо учитывать в логике, а не считать сбоем.

Сценарий со звонком: что видит пользователь

  1. Экран ввода номера. Поле в международном формате, подсказка про код страны, кнопка «Продолжить».
  2. Экран подтверждения. Крупная кнопка «Позвонить», под ней — номер текстом на случай, если диалер не откроется. Пояснение: трубку брать не нужно, вызов оборвётся сам. Таймер на 60 секунд.
  3. Системный диалер. Открывается с подставленным номером. Пользователь нажимает вызов, соединение сбрасывается через мгновение.
  4. Возврат в приложение. Статус уже подтверждён — экран меняется сам, нажимать ничего не нужно.
  5. Если не сложилось. По истечении таймера — кнопка «Позвонить ещё раз» и ссылка на запасной способ.

Формулировки на втором экране важнее, чем кажется. «Позвоните на этот номер, трубку брать не нужно» пользователь понимает сразу. «Пройдите верификацию» — нет.

Реализация на iOS и Android

Логика одинаковая, различается только открытие диалера.

Общая часть. Бэкенд создаёт проверку и получает выделенный номер; приложение показывает его и опрашивает статус. Сам механизм проверки разобран в статье про подтверждение номера телефона звонком — он одинаков для всех платформ. Ключ проекта в приложении хранить нельзя: его место на сервере, а мобильный клиент ходит в ваш собственный API. Веб-версия того же сценария описана в материале про подтверждение номера на сайте.

Открытие набора. На iOS — системная ссылка вида tel:, на Android — намерение набора номера. В обоих случаях открывается штатный диалер с подставленным номером; сам вызов инициирует пользователь. Автоматически совершать звонок за него не нужно и не следует: это требует отдельного разрешения и выглядит подозрительно.

Разрешения не нужны. Здесь ключевое отличие от обычного flash call, при котором приложение считывает номер входящего вызова из журнала. Такой доступ ограничен политиками магазинов: в Google Play выдача разрешения на журнал вызовов требует обоснования, а в iOS публичного API для чтения журнала нет вовсе. При обратном сценарии читать нечего — звонок видит сервис на своей стороне. Разбор разницы — в статье что такое flash call.

Опрос статуса. Периодический запрос с разумным интервалом плюс обязательная внеочередная проверка при возврате приложения на передний план. Опрос прекращается по CONFIRMED, по EXPIRED или по истечении таймера. Детали запросов — в материале про API подтверждения номера.

Обработка граничных случаев

СитуацияЧто делать
Приложение свёрнуто во время вызовапроверять статус при возврате на передний план, не только по таймеру
Пользователь отменил вызов в диалереоставить экран активным, таймер продолжает идти — он может позвонить снова
Звонок с другого номерапроверка не подтвердится; в подсказке заранее написать, что звонить нужно с указанного номера
Нет сигнала сотовой сетипредложить запасной способ подтверждения
Диалер не открылсяномер показан текстом, дать кнопку копирования
Истекли 60 секундпоказать «Позвонить ещё раз», создать новую проверку
Приложение закрыто до подтвержденияпри следующем запуске начинать сценарий заново

Что проверить перед отправкой в магазин

Короткий чек-лист по местам, где мобильная реализация обычно ломается.

  • Диалер открывается на реальном устройстве, а не только в эмуляторе. На части прошивок поведение отличается.
  • Номер показан текстом рядом с кнопкой. Если системный набор не открылся, пользователю нужен запасной путь — скопировать и набрать вручную.
  • Статус проверяется при возврате на передний план. Без этого пользователь возвращается на экран ожидания, который уже неактуален.
  • Опрос останавливается. Три условия: CONFIRMED, EXPIRED, истёкший таймер. Иначе запросы продолжатся в фоне и посадят батарею.
  • Ключ проекта не лежит в приложении. Даже в обфусцированном виде: мобильный клиент разбирается, а ключ тратит ваш баланс. Приложение ходит в ваш собственный API.
  • Экран переживает поворот и сворачивание. Идентификатор проверки и остаток таймера должны сохраняться.
  • Есть запасной способ подтверждения для тех, у кого номер не определяется.
  • Тексты понятны без терминов. «Позвоните на этот номер, трубку брать не нужно» вместо «пройдите верификацию».

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

Частые вопросы

Нужны ли разрешения на чтение SMS или журнала вызовов?

Нет, и это ключевое отличие сценария. Приложение только открывает системный диалер и опрашивает статус проверки по сети. Читать сообщения и журнал вызовов не требуется, поэтому и запрашивать соответствующие разрешения не нужно.

Пройдёт ли такое приложение модерацию в магазинах?

С этой стороны придираться не к чему: чувствительные разрешения не запрашиваются, фоновой активности нет, всё общение с сервисом идёт обычными HTTP-запросами. Именно из-за разрешений обычный flash call часто и не проходит.

Что если пользователь свернул приложение во время звонка?

Так и будет — набор номера сворачивает приложение по определению. Поэтому статус нужно проверять и при возврате на передний план, а не только по таймеру: к этому моменту проверка обычно уже подтверждена.

Нужен ли отдельный код для iOS и Android?

Отличается только способ открыть диалер — системная ссылка на iOS и намерение набора на Android. Вся логика проверки одинаковая: создать, показать номер, опросить статус.