Реализация
Подтверждение номера телефона в мобильном приложении
В мобильном приложении подтверждение номера звонком удобнее, чем где-либо ещё: набор открывается одним касанием через системный диалер, пользователю не нужно ничего переписывать и вводить. Главное преимущество перед обычным flash call — приложению не требуются разрешения на чтение SMS и журнала вызовов, а их выдачу ограничивают и Google Play, и App Store. Проверка живёт 60 секунд, стоит 0,20 ₽ за состоявшийся звонок.
На мобильных сценарий подтверждения звонком раскрывается лучше всего: телефон, с которого нужно позвонить, — это то же устройство, где открыто приложение. Пользователю не приходится ничего переносить с экрана на экран.
Чем подтверждение в приложении отличается от сайта
Главное отличие одно, и оно решающее: приложение может открыть набор номера в одно касание. Пользователь нажимает кнопку — открывается системный диалер с уже подставленным номером, остаётся нажать вызов.
На сайте с десктопа так не получится: номер придётся переносить на телефон руками, и это худшая точка сценария. В приложении её просто нет.
Второе отличие — контроль над экраном. Приложение точно знает, когда пользователь вернулся из диалера, и может проверить статус именно в этот момент, а не по таймеру. Переход к следующему шагу получается мгновенным.
Третье — обратная сторона: приложение уходит на задний план во время вызова, и это надо учитывать в логике, а не считать сбоем.
Сценарий со звонком: что видит пользователь
- Экран ввода номера. Поле в международном формате, подсказка про код страны, кнопка «Продолжить».
- Экран подтверждения. Крупная кнопка «Позвонить», под ней — номер текстом на случай, если диалер не откроется. Пояснение: трубку брать не нужно, вызов оборвётся сам. Таймер на 60 секунд.
- Системный диалер. Открывается с подставленным номером. Пользователь нажимает вызов, соединение сбрасывается через мгновение.
- Возврат в приложение. Статус уже подтверждён — экран меняется сам, нажимать ничего не нужно.
- Если не сложилось. По истечении таймера — кнопка «Позвонить ещё раз» и ссылка на запасной способ.
Формулировки на втором экране важнее, чем кажется. «Позвоните на этот номер, трубку брать не нужно» пользователь понимает сразу. «Пройдите верификацию» — нет.
Реализация на 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. Вся логика проверки одинаковая: создать, показать номер, опросить статус.