Розробка мобільного застосунку для збору пожертвувань
Користувач не довіряє, якщо не бачить, на що йдуть гроші. Особливо коли донати рекурентні, а суми довільні. Ми стикалися з проєктами, де через погану реалізацію прозорості та UX падав LTV донаторів. Наприклад, один благодійний фонд втрачав до 40% користувачів на екрані оплати через відсутність Apple Pay та незрозумілий прогрес збору. Прозорість зборів — це не просто прогрес-бар, а ціла система: стрічка транзакцій, анімовані індикатори, автоматичні звіти. У цій статті — як уникнути типових помилок і зробити застосунок, якому вірять.
За даними Wikipedia, мобільні пожертви зростають на 25% щороку.
Ключові етапи розробки мобільного застосунку для збору пожертвувань
Базовий функціонал включає три типи платежів: разовий донат, рекурентний донат та оплата через гаманцеві системи. Кожен вимагає своєї реалізації.
Разовий донат
Стандартний платіж через провайдера. Користувач вводить суму, натискає кнопку, бачить результат. Головне — мінімізувати кількість полів. Ідеально — одна кнопка «Пожертвувати» з попередньо встановленими сумами та полем «своя сума».
Рекурентний донат
Користувач підписується на щомісячне списання. Реалізується через recurring payments: при першому платежі провайдер повертає токен картки, далі сервер самостійно ініціює списання в потрібний день. Це основа прогнозованого cash flow для НКО.
// iOS: Stripe recurring donation setup import StripePayments let params = STPConfirmSetupIntentParams( paymentMethodParams: cardParams, clientSecret: setupIntentClientSecret ) STPPaymentHandler.shared().confirmSetupIntent( params, with: self ) { [weak self] status, setupIntent, error in switch status { case .succeeded: // setupIntent.paymentMethodID — сохраняем на сервере self?.saveRecurringMethod(setupIntent?.paymentMethodID) case .failed: self?.showError(error?.localizedDescription) case .canceled: break @unknown default: break } } Apple Pay / Google Pay для разових донатів
Максимально низке тертя — користувач не вводить дані картки вручну. Налаштування merchant ID та provisioning profile входить в обсяг робіт. Приклад на iOS:
let request = PKPaymentRequest() request.merchantIdentifier = "merchant.com.yourcharity.app" request.countryCode = "UA" request.currencyCode = "UAH" request.supportedNetworks = [.visa, .masterCard] request.merchantCapabilities = [.capability3DS] request.paymentSummaryItems = [ PKPaymentSummaryItem( label: "Допомога тваринам", amount: NSDecimalNumber(string: donationAmount) ) ] Apple Pay кращий за разові карткові платежі в 2-3 рази за конверсією — підтверджено A/B-тестами наших клієнтів. Крім того, Apple Pay зменшує час платежу в 10 разів у порівнянні з ручним введенням даних.
Порівняння підходів до платежів
| Критерій | Разовий донат | Рекурентний донат | Apple/Google Pay |
|---|---|---|---|
| Час на платіж | ~30 секунд | ~15 секунд (перший) | 2-3 секунди |
| Довіра користувача | Середня | Висока | Висока |
| Частота помилок | 3-5% | 1-2% | <1% |
| Підтримка податкових вирахувань | За запитом | Автоматично | За запитом |
Як реалізувати довільну суму без помилок?
Поле «своя сума» — часте джерело помилок. Проблеми:
- Користувач вводить «1000.5» або «1 000» з пробілом — потрібна нормалізація до
Decimal - Мінімальний ліміт провайдера (у більшості — 10 грн)
- Максимальний ліміт без 3DS (зазвичай 150 000 грн)
// Android: нормализация произвольной суммы fun parseAmount(input: String): Result<Long> { val cleaned = input .replace(",", ".") .replace(Regex("\\s"), "") .trim() return try { val decimal = cleaned.toBigDecimal() if (decimal < BigDecimal("10")) { Result.failure(Exception("Минимальная сумма — 10 ₽")) } else if (decimal > BigDecimal("150000")) { Result.failure(Exception("Для сумм выше 150 000 ₽ требуется верификация")) } else { Result.success((decimal * BigDecimal("100")).toLong()) // в копейках } } catch (e: NumberFormatException) { Result.failure(Exception("Введите корректную сумму")) } } Як забезпечити прозорість збору?
Користувачі жертвують охочіше, коли бачать конкретну мету та прогрес. Це "прогрес-бар збору" — цільовий показник vs поточний. Для анімації використовуємо animateFloatAsState у Flutter або Compose. Сервер надсилає нові дані через WebSocket, і шкала оновлюється плавно, створюючи залучаючий ефект.
// Android: Jetpack Compose progress indicator для сбора @Composable fun FundraisingProgress( current: Long, target: Long, modifier: Modifier = Modifier ) { val progress = (current.toFloat() / target.toFloat()).coerceIn(0f, 1f) val animatedProgress by animateFloatAsState( targetValue = progress, animationSpec = tween(durationMillis = 800) ) Column(modifier) { LinearProgressIndicator( progress = animatedProgress, modifier = Modifier.fillMaxWidth().height(8.dp), trackColor = MaterialTheme.colorScheme.surfaceVariant, color = MaterialTheme.colorScheme.primary ) Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Text("${formatAmount(current)} ₴ зібрано") Text("із ${formatAmount(target)} ₴") } } } Крім прогрес-бару, додаємо стрічку транзакцій — кожен користувач бачить, що його донат зафіксовано. Це підвищує довіру та знижує chargeback.
Переваги рекурентних платежів з першої версії
Рекурентні донати дають на 30-50% більший середній чек порівняно з разовими платежами. Наприклад, при середньому чеку $50, рекурентна підписка приносить $600 на рік з одного донатора. Технічно ми реалізуємо recurring через токенізацію карток: після першого успішного списання зберігаємо paymentMethodID на сервері та ініціюємо нові списання через Stripe API. Обов'язково налаштовуємо нагадування про списання (push + email) за 3 дні до дати — це знижує chargeback у 4 рази.
Технічні деталі токенізації карток
Токенізація відбувається за допомогою Stripe: під час першого платежу Stripe повертає paymentMethodID, який шифрується та зберігається на сервері. Подальші списання ініціюються через API Stripe без повторного введення даних. Це забезпечує відповідність стандарту PCI DSS.Стек технологій для збірки
| Компонент | iOS | Android | Flutter |
|---|---|---|---|
| Платіжний SDK | Stripe Payments iOS | Stripe Android SDK | Stripe Flutter |
| Push-сповіщення | APNs | FCM (Firebase) | FCM (Firebase) |
| Deep linking | Universal Links | App Links | app_links plugin |
Податкові вирахування та документи
Для благодійних фондів часто потрібне формування довідки для податкового вирахування. Це серверна логіка: агрегація платежів користувача за рік, формування PDF. Застосунок лише показує кнопку «Завантажити довідку».
Що входить у розробку під ключ?
- Аналітика: інтерв'ю з фондом, аудит поточних процесів, вибір провайдера (Stripe / YooKassa / Cloud Payments)
- Проєктування: UX-прототипи з фокусом на екран платежу та історію, архітектура (iOS / Android / Flutter)
- Реалізація: верстка екранів, інтеграція платежів, налаштування push-сповіщень (APNs + FCM), deep linking (Universal Links)
- Тестування: unit-тести логіки, UI-тести критичних шляхів, тестова оплата в sandbox, перевірка App Store Review Guidelines (Section 4.2/5.1)
- Деплой: публікація в App Store та Google Play, налаштування метрики, закриття доступу до тестових даних
- Пост-реліз: моніторинг crash-free rate, оновлення бібліотек, підтримка протягом 3 місяців
Орієнтири за термінами
Базова версія (разові донати, картка + Apple/Google Pay, історія): 3–5 тижнів. Рекурентні підписки — ще 1–2 тижні. Прогрес-бари за цільовими зборами — ще 1 тиждень. Вартість розраховується індивідуально. Ми маємо сертифікованих розробників Stripe та 5-річний досвід у фінтех. Гарантуємо відповідність стандартам PCI DSS. Отримайте консультацію щодо вашого проєкту — більше 5 років досвіду в розробці фінтех-застосунків. Зв'яжіться з нами, щоб обговорити деталі.







