Ми розробляємо систему віртуальної валюти (балів і монет) для мобільних додатків з нуля або інтегруємо в існуючий проєкт. Баги в нарахуванні монет — це або порожні гаманці користувачів (злі відгуки, падіння DAU на 20%), або переповнення (збитки для бізнесу, іноді до 15% виручки). Наш досвід — 5+ років у комерційній мобільній розробці, 15+ проєктів з гейміфікацією. Працюємо з 2018 року. За цей час ми накопичили патерни для різних архітектур — від MVP до модульних монорепозиторіїв. Розробка під ключ — від проєктування ledger до деплою в магазини.
Зростання LTV на 25% після впровадження системи валюти — не рідкість. Середній чек IAP consumable становить $4.99, що при правильному налаштуванні збільшує ARPU. При цьому без належного захисту від шахрайства можна втратити до 30% виручки через накрутки. Наші рішення перевірені на проєктах з мільйонною аудиторією. Економія від впровадження захисту — до $10 000 на місяць.
Залиште заявку — ми підберемо оптимальну архітектуру під ваш проєкт.
Транзакційність — основа
Кожна операція з балансом — це атомарна транзакція з debit/credit записом у ledger таблиці, а не просто UPDATE balance = balance + N. Причина: без атомарності при одночасних запитах нарахування та списання отримуємо некоректний баланс. Використовуємо SELECT FOR UPDATE на сервері або оптимістичне блокування (UPDATE balance WHERE balance = :expected).
Клієнт при будь-якій транзакції отримує повну відповідь:
{ "balance": 1250, "delta": 100, "transaction_id": "uuid", "reason": "daily_bonus" } Ніколи не перераховуємо баланс на клієнті — лише відображаємо значення з сервера.
Як захистити систему валюти від шахрайства?
Відлагоджувальний проксі. Charles Proxy або mitmproxy дозволяє пересилати запити та змінювати відповіді. Якщо відповідь /rewards/daily-bonus повертає {"coins": 100} без підпису сервера — клієнт може показати «отримав 100 монет», але сервер у цей час повинен самостійно нараховувати та не довіряти значенню з відповіді.
SSL Pinning. Базовий захист від MITM: TrustKit (iOS) / OkHttp CertificatePinner (Android). Не абсолютний захист — Frida або root + SSL Kill Switch обходять pinning. Але відсікає 90% script-kiddie спроб.
Rate limiting операцій. Подвійне натискання кнопки «Зібрати бонус» — debounce на клієнті (250ms throttle) плюс серверний захист через idempotency_key (UUID від клієнта). Сервер ігнорує повторний запит з тим же ключем протягом 60 секунд.
Детальніше про rate limiting
Ми використовуємо токен бакета (bucket algorithm) з лімітом 5 запитів на секунду на користувача для операцій нарахування. Idempotency-ключ зберігається в Redis з TTL 120 секунд.UI: анімація нарахування монет
Монети «летять» до лічильника — стандартна анімація для reward. Реалізація: частинки через CAEmitterLayer (iOS) або Jetpack Compose Canvas з кастомним анімованим Modifier. Декілька монет-іконок вилітають з джерела (позиція кнопки/іконки події), летять по кривій Безьє до віджета балансу, при кожному «попаданні» лічильник інкрементується на 1. Плавний наростаючий ефект через CAKeyframeAnimation з path.
Лічильник балансу при оновленні — number rolling animation: цифри прокручуються зверху вниз як одометр. На iOS через UILabel з CATransition або кастомний AnimatedNumberView в SwiftUI. На Android — ValueAnimator з TextSwitcher. Анімація триває 1.5-2 секунди, щоб користувач помітив нарахування.
| Тип анімації | iOS | Android |
|---|---|---|
| Політ монет | CAEmitterLayer + CAKeyframeAnimation | Canvas + ObjectAnimator |
| Лічильник-одометр | AnimatedNumberView (SwiftUI) | ValueAnimator + TextSwitcher |
Чому серверний ledger надійніший за клієнтський?
Серверний ledger у 10 разів надійніший за клієнтський за всіма параметрами: атомарність, безпека, аудит.
| Аспект | Серверний ledger | Клієнтський баланс |
|---|---|---|
| Атомарність | Гарантована (транзакції БД) | Ризик гонок |
| Безпека | Під захистом серверної валідації | Легко модифікується |
| Аудит | Повна історія операцій | Немає довіреного журналу |
Купівля монет через IAP
Consumable продукти в StoreKit 2: «100 монет за $0.99», «550 монет за $4.99» і т.д. Product.purchase() → Transaction.finish() після нарахування серверного балансу — важливий порядок: спочатку зараховуємо монети через сервер (серверна валідація чека), потім завершуємо транзакцію. Якщо завершити транзакцію до зарахування і додаток впаде — користувач заплатив, монети не отримав.
На Android: BillingClient.launchBillingFlow() → Purchase.getPurchaseState() == PURCHASED → серверна валідація через Google Play Developer API → BillingClient.consumeAsync() (consumable має бути consumed, інакше недоступний для повторної покупки).
Pending transactions (відкладені покупки на Android через сімейний Google Pay або банківське підтвердження) — обробляємо через BillingClient.PurchasesUpdatedListener, чекаємо підтвердження до нарахування монет.
Згідно з рекомендаціями Apple, серверна валідація обов'язкова для consumable продуктів.
Як налаштувати серверну валідацію IAP: покроково
- Отримати receipt (iOS) або purchase token (Android) на клієнті.
- Відправити на наш сервер (POST /validate-purchase).
- Сервер виконує HTTP-запит до Apple Verify Receipt або Google Play Developer API.
- При успішній валідації нараховуємо монети в ledger і повертаємо підтвердження.
- Клієнт завершує транзакцію (Transaction.finish() / consumeAsync()).
Історія транзакцій
Користувач хоче зрозуміти, куди пішли монети. TransactionHistory — пагінований список (cursor-pagination) з типами: earned_daily_bonus, earned_referral, spent_purchase, spent_unlock, purchased_iap. Фільтр за типом. Локальний кеш останніх 50 операцій в Core Data / Room для миттєвого відображення без мережевого запиту.
Що входить в реалізацію
- Проєктування схеми ledger та захисту від шахрайства
- Розробка IAP (consumable) + серверна валідація
- UI балансу + анімації
- Історія транзакцій
- QA (включає тест parallel requests, pending transactions)
- Документація по API та інтеграції
- Підтримка після запуску (опціонально)
Орієнтири за термінами та вартістю
Повна реалізація системи віртуальної валюти з IAP, анімаціями та історією транзакцій — 3–5 робочих днів при готовому серверному API. Якщо включає проєктування серверного ledger — 1–2 тижні. Вартість базової системи — від $3000.
Отримайте консультацію — замовте оцінку вашого проєкту під ключ. Гарантуємо прозорість і досвід на кожному етапі. Завдяки правильній архітектурі ви економите до 40% часу на налагодженні.
Apple Developer Documentation: StoreKit 2 | Google Play Billing Library







