Реализация подключения к POS-терминалу из мобильного приложения
Подключение мобильного приложения к POS-терминалу — это не просто «отправить сумму на терминал». Это интеграция с закрытыми протоколами оборудования, которые у каждого производителя свои, плюс обработка всех возможных сбоев связи в момент финансовой операции.
Протоколы и производители
Большинство POS-терминалов в торговом ритейле общаются по одному из стандартных интерфейсных протоколов:
ECR-протокол (Electronic Cash Register) — набор команд для передачи суммы с кассового приложения на терминал. У каждого банка-эквайера или производителя — своя реализация. Сбербанк (СБОЛ), ВТБ, Ingenico, Verifone — у всех отличается синтаксис команд и поля ответа.
OPI (Open Payment Initiative) / OPOS (OLE for POS) — более стандартизированные протоколы, популярны в Европе.
Proprietary SDK: PAX A-серия, Sunmi V2, Newland — имеют собственные Android SDK (терминал сам работает на Android, вызываем AIDL-интерфейс или Intent).
Перед началом разработки — уточняем у клиента: какой конкретный терминал, какой банк-эквайер, какой протокол поддерживается. Это не технический выбор разработчика — это факты об установленном оборудовании.
Интерфейсы подключения
Bluetooth (BLE + Classic). Терминал выступает GATT-сервером (BLE) или classic Bluetooth serial device. На iOS: CoreBluetooth для BLE, classic Bluetooth — только через ExternalAccessory framework с MFi-сертификацией. Это важное ограничение: большинство POS-терминалов используют classic Bluetooth SPP-профиль, а iOS без MFi-сертификата производителя терминала не сможет подключиться через classic BT. На Android ограничений нет — BluetoothSocket + RFCOMM.
USB. Android: UsbManager, UsbDeviceConnection. iOS: Lightning/USB-C аксессуар — снова нужен MFi. На практике USB-подключение встречается реже, чем Bluetooth.
TCP/IP (Wi-Fi / LAN). Терминал на локальной сети, приложение подключается по IP:Port и отправляет команды в текстовом или бинарном формате. URLSession / OkHttp для HTTP-команд или CFStream / Java Socket для raw TCP. Самый предсказуемый интерфейс с точки зрения iOS.
Флоу платёжной операции
- Приложение формирует команду «продажа» с суммой и дополнительными параметрами.
- Отправляет на терминал.
- Терминал показывает пользователю экран оплаты, принимает карту.
- Возвращает ответ: статус (
approved/declined/error), код авторизации, RRN, маскированный PAN. - Приложение обрабатывает ответ и продолжает бизнес-флоу (закрывает чек, обновляет заказ).
Шаги 2–4 могут занять до 60–90 секунд при медленном эквайринге. На этот период показываем spinner с сообщением «Ожидание ответа терминала» и кнопку «Отмена» (которая отправляет команду отмены на терминал, не просто закрывает экран).
Обработка сбоев
Самый неприятный кейс: транзакция ушла на терминал, связь прервалась — приложение не знает, прошёл платёж или нет. Терминал авторизовал карту, но ответ не дошёл.
Правильная схема: при потере связи — пробуем получить статус последней транзакции (команда «запрос последней операции»). Если терминал отвечает — берём статус оттуда. Если нет — показываем оператору «Статус неизвестен, проверьте терминал» и сохраняем транзакцию в PENDING статусе. Автоматическое списание при неизвестном статусе — недопустимо.
Reconnect logic: при обрыве Bluetooth — автоматическое переподключение с 3–5 попытками, exponential backoff. Состояние соединения — всегда видно в UI (иконка статуса).
Возврат и отмена
Отмена транзакции (reversal) — до закрытия финансового дня. Возврат (refund) — после. Оба требуют отдельных команд на терминал с RRN исходной транзакции. Реализуем оба сценария — оператор должен иметь возможность исправить ошибку.
Android vs iOS
| Аспект | Android | iOS |
|---|---|---|
| Classic BT (SPP) | Нативно, BluetoothSocket |
Только MFi-устройства |
| BLE | BluetoothGatt |
CoreBluetooth |
| USB | UsbManager |
Только MFi |
| TCP/IP | Socket / OkHttp |
CFStream / URLSession |
Если заказчик требует iOS и терминал работает только по classic Bluetooth без MFi — единственный путь: TCP/IP через промежуточный адаптер или переход на терминал с BLE/TCP поддержкой.
Процесс
Выяснение модели терминала и протокола → изучение документации эквайера → реализация транспортного слоя (BT/USB/TCP) → протокол команд (продажа, отмена, возврат, запрос статуса) → обработка edge-cases (обрыв связи, таймаут) → тестирование на реальном терминале в тестовом режиме эквайера → боевое тестирование → эксплуатация.
Ориентиры по срокам
Базовая интеграция (продажа + ответ) по конкретному протоколу с одним интерфейсом: 3–5 дней. Полный набор операций (продажа, отмена, возврат, запрос статуса) + retry/reconnect logic + несколько интерфейсов: 2–3 недели.







