Разработка мобильного приложения для сбора пожертвований
Пользователь не доверяет, если не видит, на что идут деньги. Особенно когда донаты рекуррентные, а суммы произвольные. Мы сталкивались с проектами, где из-за плохой реализации прозрачности и UX падал LTV донаторов. Например, один благотворительный фонд терял до 40% пользователей на экране оплаты из-за отсутствия Apple Pay и непонятного прогресса сбора. Прозрачность сборов — это не просто прогресс-бар, а целая система: лента транзакций, анимированные индикаторы, автоматические отчёты. В этой статье — как избежать типовых ошибок и сделать приложение, которому верят.
Как разработать мобильное приложение для сбора пожертвований?
Базовый функционал включает три типа платежей: разовый донат, рекуррентный донат и оплата через кошелёчные системы. Каждый требует своей реализации.
Разовый донат
Стандартный платёж через провайдера. Пользователь вводит сумму, нажимает кнопку, видит результат. Главное — минимизировать количество полей. Идеально — одна кнопка «Пожертвовать» с предустановленными суммами и полем «своя сумма».
Рекуррентный донат
Пользователь подписывается на ежемесячное списание. Реализуется через 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 = "RU" request.currencyCode = "RUB" request.supportedNetworks = [.visa, .masterCard] request.merchantCapabilities = [.capability3DS] request.paymentSummaryItems = [ PKPaymentSummaryItem( label: "Помощь животным", amount: NSDecimalNumber(string: donationAmount) ) ] Apple Pay лучше разовых карточных платежей в 2-3 раза по конверсии — подтверждено A/B-тестами наших клиентов.
Сравнение подходов к платежам
| Критерий | Разовый донат | Рекуррентный донат | 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.
Почему recurrency стоит внедрять с первой версии?
Рекуррентные донаты дают на 30-50% больше среднего чека по сравнению с разовыми платежами. Технически мы реализуем recurring через токенизацию карт: после первого успешного списания храним paymentMethodID на сервере и инициируем новые списания через Stripe API. Обязательно настраиваем напоминания о списании (push + email) за 3 дня до даты — это снижает chargeback в 4 раза.
Стек технологий для сборки
| Компонент | 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, настройка metrica, закрытие доступа к тестовым данным
- Пост-релиз: мониторинг crash-free rate, обновление библиотек, поддержка в течение 3 месяцев
Ориентиры по срокам
Базовая версия (разовые донаты, карта + Apple/Google Pay, история): 3–5 недель. Рекуррентные подписки — ещё 1–2 недели. Прогресс-бары по целевым сборам — ещё 1 неделя. Стоимость рассчитывается индивидуально. Получите консультацию по вашему проекту — более 5 лет опыта в разработке финтех-приложений. Свяжитесь с нами, чтобы обсудить детали.







