Разработка мобильного приложения для ставок на спорт
Букмекерские приложения обрабатывают тысячи обновлений котировок в секунду. Задержка в 3–5 секунд превращается в финансовые потери: клиенты ставят по устаревшим данным, а арбитражники выводят деньги. Центральная задача — актуальность данных. Наш стек и архитектура решают её на уровне протокола и UI. В одном из проектов с 5000+ одновременных подключений мы добились задержки обновления коэффициентов менее 100 мс. Это позволило оператору сократить потери от арбитражных ставок на 30% и снизить нагрузку на сервер в 10 раз по сравнению с традиционным polling.
Почему WebSocket, а не REST?
REST polling каждые 3 секунды при 500 активных матчах создаёт нагрузку, несовместимую с real-time. Мы используем WebSocket: одно соединение, подписки на события (SUBSCRIBE {market_ids: [123, 456]}), сервер присылает дифф ({market_id: 123, outcomes: [{id: 1, odds: 2.45}]}). Клиент применяет изменения к локальному state без перезагрузки.
- iOS:
URLSessionWebSocketTask+Combinepublisher дистрибьютит обновления по ViewModel'ам. - Android:
OkHttp WebSocket+StateFlow/SharedFlowчерезBettingRepository. - При разрыве — автоматический reconnect с экспоненциальным backoff и повторной подпиской.
- Визуально — микроанимация при изменении коэффициента (зелёный/красный flash через
animate()в Compose илиUIView.animateв UIKit).
Suspended markets. Перед крупным событием матч уходит в suspend — ставки блокируются. Приложение получает {market_id: 123, status: "suspended"} и немедленно деактивирует кнопку «Поставить». Если купон уже открыт — показываем inline предупреждение.
Как работает idempotency_key в размещении ставок?
idempotency_key (UUID клиента) обязателен — предотвращает дублирование ставок при сетевых сбоях. Он передаётся в POST /bets. Сервер проверяет уникальность ключа за определённый промежуток времени, что исключает повторное списание средств.
Купон ставки (betslip) — архитектура и подводные камни
Betslip — технически сложный UI-компонент. Пользователь добавляет исходы, приложение считает accumulator odds: total_odds = outcome_1_odds × outcome_2_odds × ... × outcome_n_odds. При изменении любого коэффициента во время открытого betslip — обновление с анимацией и предложением принять новые условия.
Flow размещения ставки:
- Нажатие «Поставить» → локальная валидация (баланс, мин/макс ставка).
- POST
/betsс{selections, stake, idempotency_key}→ сервер резервирует сумму. - Ответ:
{bet_id, status: "accepted"/"pending"/"rejected", actual_odds}. - Если
actual_oddsизменились — диалог «Коэффициент изменился. Принять?».
Как мы обеспечиваем геолокационный контроль?
Лицензионные требования запрещают ставки за пределами разрешённой территории. Запрашиваем CLLocationManager (iOS) или FusedLocationProviderClient (Android) при старте. Координаты уходят на сервер, сервер сверяет с GeoIP + device location. VPN detection: сравниваем IP-геолокацию с GPS — существенное расхождение только флаг для проверки, а не бан.
Платежи и вывод: безопасность прежде всего
Пополнение и вывод через Stripe, Adyen, PayOp или локальные PSP. Карточные данные не проходят через наш сервер — используем Stripe iOS SDK (STPPaymentCardTextField) / Stripe Android SDK. Для вывода — обязательная верификация (KYC) через Sumsub. Apple Pay / Google Pay для быстрого депозита: интеграция занимает 1–2 дня при готовом бэкенде.
Сравнение подходов и SDK
| Критерий | WebSocket | Long polling |
|---|---|---|
| Задержка обновления | 50–100 мс | 3–5 сек |
| Нагрузка на сервер | Низкая | Высокая |
| Сложность реализации | Средняя | Низкая |
| Поддержка suspend events | Нативная | Требует костылей |
| Масштабируемость (1000+ подключений) | Отличная | Плохая |
| Платформа | Библиотека | Поддержка Combine/Flow |
|---|---|---|
| iOS | URLSessionWebSocketTask | Да (Combine) |
| Android | OkHttp | Да (Flow через callback) |
| iOS/Android (альтернатива) | Starscream (iOS) / okhttp3 (Android) | Зависит от реализации |
WebSocket лучше подходит для live-котировок: снижает нагрузку в 10 раз по сравнению с polling и обеспечивает актуальность данных. При нагрузочном тестировании мы эмулировали 2000+ одновременных подключений и достигли 99.99% успешных обновлений.
Какой стек и архитектура используются?
- iOS: Swift 5.9+, SwiftUI, Combine, async/await
- Android: Kotlin, Jetpack Compose, Hilt DI, Room, Coroutines + Flow
- Cross-platform: Flutter 3.x (Dart) или React Native (TypeScript) — но для live-котировок предпочтительна нативная разработка
- Backend: GraphQL (Apollo) + REST + Codable, Firebase / Supabase
- Хранилище: локальная БД (Room / Core Data) с миграциями для истории ставок
Архитектура: Clean Architecture — BettingRepository (WebSocket + REST), BetSlipViewModel (accumulator, validation), PaymentRepository, GeoLocationService.
Процесс работы: от аудита до публикации
- Аудит лицензионных требований и выбор юрисдикции
- Проектирование API и WebSocket-контракта
- Разработка real-time котировок и betslip
- Интеграция платежей + KYC
- Геолокационный контроль
- Нагрузочное тестирование (1000+ одновременных обновлений)
- Публикация в магазинах (App Store: gambling entitlement + лицензия; Google Play: Gambling policy)
Что входит в результат
- Исходный код приложения для iOS и/или Android
- WebSocket-контракт и документация API
- Настроенные CI/CD (TestFlight, Firebase App Distribution)
- Инструкция по публикации и сопровождению
- Поддержка в течение 30 дней после сдачи
Опыт и сроки
Мы занимаемся мобильной разработкой 8+ лет. В портфолио более 20 проектов, включая high-load букмекерские платформы. Среднее время вывода MVP — 10 недель. Стоимость разработки варьируется в зависимости от функционала и требований к real-time.
- MVP (live и prematch котировки, одиночные и экспресс-ставки, базовые платежи): 8–12 недель.
- Полноценная платформа (live streaming, cash out, многовалютность, обе платформы): 3–5 месяцев.
Чтобы обсудить детали, свяжитесь с нами — пришлём коммерческое предложение с примерной оценкой в течение двух дней. Получите консультацию по вашему проекту прямо сейчас.







