Разбираем, как правильно проектировать интеграцию мобильного приложения с внешними сервисами — платёжными системами, картами, аналитикой, push-уведомлениями — чтобы она не превратилась в узкое место проекта.
Почти любое современное мобильное приложение — это не изолированная программа, а узел в сети сторонних сервисов: платёжный шлюз, push-уведомления, карты, аналитика, авторизация через соцсети, служба доставки. Заказчики часто представляют это как «подключить SDK и всё заработает», но на практике именно интеграции становятся источником большинства нестабильностей в приложении после релиза — не потому что SDK плохие, а потому что архитектура вокруг них спроектирована наспех.
Почему «просто подключить SDK» — это иллюзия простоты
У каждого внешнего сервиса — свой формат ответов, свои коды ошибок, свои лимиты запросов и своя политика повторных попыток при сбоях. Если интегрировать пять таких сервисов «в лоб», вызывая их SDK напрямую из экранов приложения, код быстро обрастает дублирующейся логикой обработки ошибок, а любое изменение в API одного из сервисов требует правок в нескольких не связанных друг с другом местах.
Правильный подход — вынести работу с каждым внешним сервисом в отдельный слой абстракции внутри приложения, а не размазывать вызовы SDK по экранам. Экран не должен знать, что оплата идёт через конкретного провайдера — он должен обращаться к внутреннему интерфейсу «оплатить заказ», за которым уже скрыта реализация конкретного платёжного шлюза. Это позволяет заменить провайдера или добавить второй способ оплаты, не переписывая логику экранов.
Собственный бэкенд-прокси против прямых вызовов из приложения
Ключевое архитектурное решение — где физически происходит обращение к стороннему API: напрямую из мобильного приложения или через собственный backend, который выступает прокси между приложением и внешним сервисом. У обоих подходов есть обоснованные сценарии применения.
Прямая интеграция из приложения подходит для сервисов, изначально спроектированных для клиентских SDK — карт, аналитики, push-уведомлений, где секретные ключи не требуются или уже защищены механизмом самого провайдера. Это быстрее в разработке и не создаёт дополнительной точки отказа в виде собственного сервера.
Но для платежей, работы с персональными данными или любых сервисов, где требуется секретный API-ключ, прямая интеграция из мобильного приложения — уязвимость: любой ключ, зашитый в код приложения, можно извлечь реверс-инжинирингом APK или IPA. В таких случаях обязателен собственный backend, который держит секретные ключи на сервере, принимает запросы от приложения по своему защищённому API и уже сам обращается к внешнему сервису.
- платежи, работа с персональными данными, любые операции с деньгами — только через собственный backend;
- карты, аналитика, push, авторизация через соцсети — обычно можно интегрировать напрямую через официальный SDK;
- вебхуки от внешних сервисов (уведомление об оплате, статус доставки) — всегда принимает backend, а не мобильное приложение, потому что приложение может быть закрыто или офлайн в момент события;
- любая интеграция, требующая rate limit или очередь повторных попыток, лучше живёт на сервере, где есть постоянное соединение и контроль состояния.
Обработка сбоев — не опциональная часть интеграции
Внешний сервис недоступен, отвечает с задержкой, возвращает неожиданный формат ответа — это не исключительная ситуация, а нормальный режим работы, который должен быть предусмотрен архитектурой с самого начала, а не добавлен «после того как пользователи начали жаловаться».
Для критичных операций, таких как оплата, стандартный паттерн — идемпотентные запросы с уникальным идентификатором операции: если сеть оборвалась после отправки запроса, но до получения ответа, повторная отправка того же запроса с тем же идентификатором не создаёт задвоенный платёж, а возвращает результат уже выполненной операции. Без этого механизма нестабильное мобильное соединение рано или поздно приведёт к списанию средств дважды за один заказ.
Для менее критичных интеграций — push-уведомлений, аналитики — приемлема более простая стратегия: локальная очередь событий на устройстве с отложенной отправкой при восстановлении сети, чтобы не терять данные, но и не блокировать интерфейс приложения ожиданием ответа от стороннего сервиса.
Как мы проектируем интеграции в мобильных приложениях
В Codeking на этапе проектирования мы отдельно классифицируем каждую внешнюю интеграцию по двум признакам: критичность для бизнеса (можно ли пользователю продолжить работу, если сервис недоступен) и чувствительность данных (требуется ли скрывать ключи и защищать передаваемую информацию). От этой классификации зависит, будет ли интеграция идти напрямую из приложения или через собственный backend-слой.
Отдельно стоит сказать про интеграции с корпоративными системами заказчика — CRM, учётными системами, внутренними API. Для этого класса задач мы обычно проектируем отдельный слой синхронизации, который может работать асинхронно и переживать временную недоступность внутренней системы заказчика без потери данных. Похожий подход мы применяем и для интеграции мобильных приложений с Битрикс24 — подробнее об этом можно почитать в статье «Мобильное приложение для Битрикс24: интеграция и кастомная разработка», где разбирается конкретный кейс работы с REST API одной платформы.
Главный практический вывод: чем раньше на проекте появляется чёткое разделение — что интегрируется напрямую, а что через собственный backend, и как система ведёт себя при сбое стороннего сервиса — тем меньше приложение зависит от стабильности каждого отдельного партнёра и тем проще потом заменить один сервис на другой без переписывания всей логики.
