Разработка мобильного приложения для ресторана (оплата по QR)
QR-оплата в ресторане на первый взгляд выглядит просто: отсканировал — заплатил. На деле интеграция ломается на стыке нескольких слоёв — генерация QR на стороне кассовой системы, синхронизация статуса оплаты между официантским планшетом и приложением гостя, и обработка таймаутов, когда эквайер отвечает позже, чем закрывается счёт.
Где чаще всего ломается интеграция
Самая частая проблема — гонка состояний при QR-оплате через СБП (Систему быстрых платежей). Гость сканирует динамический QR, сформированный через API ЮKassa или CloudPayments, делает перевод. Банк отправляет webhook на ваш сервер. Но приложение уже показывает «Ожидайте подтверждения» и через 30 секунд — «Время ожидания истекло». Причина — webhook пришёл через 35 секунд из-за сетевых задержек на стороне банка, а polling на мобильном клиенте остановился раньше.
Решение: WebSocket-канал между сервером и мобильным клиентом вместо polling. Сервер при получении webhook немедленно пушит статус на устройство. Таймаут на клиенте увеличиваем до 3 минут, но визуально показываем прогресс — анимация ожидания не должна зависнуть «навсегда» с точки зрения UX.
Вторая проблема — сканирование QR на iOS через AVFoundation. Стандартный AVCaptureMetadataOutput с типом .qr иногда не читает распечатанный QR при плохом освещении ресторана. Добавляем torchMode = .auto и выставляем videoZoomFactor программно при низком brightness из AVCaptureDevice.exposureTargetBias.
Как выглядит стек и архитектура
На iOS — SwiftUI + Combine для состояния экрана оплаты, AVFoundation для сканирования, URLSession с async/await для запросов к своему бэкенду. На Android — Jetpack Compose, CameraX с QRCodeAnalyzer поверх ML Kit Barcode Scanning, Retrofit + OkHttp.
Серверная часть: генерация динамического QR через API эквайера (у ЮKassa это POST /v3/payments с confirmation.type = qr), получение confirmation_url, WebSocket-нотификации клиенту, обработка webhook с верификацией подписи sha256.
Для меню и каталога блюд — обычный REST, данные кэшируем локально через Core Data (iOS) или Room (Android), чтобы меню открывалось без интернета.
Схема взаимодействия
[Мобильное приложение гостя]
|
| Запрос счёта (tableId)
v
[Бэкенд ресторана]
|
| POST /v3/payments → ЮKassa API
v
[ЮKassa] → возвращает confirmation_url (QR)
|
| WebSocket push при получении webhook
v
[Мобильное приложение] → статус "Оплачено"
Этапы работы
Начинаем с аудита кассовой системы ресторана — нужно понять, через какой протокол она общается (iiko, r_keeper, Poster, или самописная). Интеграция с iiko через iiko.transport API добавляет около 2 дней к сроку. Затем:
- Дизайн экранов: меню, корзина, экран оплаты с QR
- Реализация сканирования и генерации QR
- Интеграция с платёжным провайдером
- Тестирование webhook'ов в Sandbox
- Сборка и публикация в App Store / Google Play
Сроки
MVP с QR-оплатой и меню — 2–3 недели. С полноценной интеграцией кассовой системы и версиями для iOS и Android — до 5 недель. Стоимость рассчитывается индивидуально после анализа требований.







