Разработка мобильного приложения для краудфандинга
Несколько лет назад одна из наших платформ для краудфандинга столкнулась с проблемой: в последний час кампании число одновременных запросов на оформление бэкингов выросло в 10 раз, и база данных не справилась с транзакциями — часть платежей повисла в статусе pending, бэкеры получили двойные списания. После аудита мы переписали механизм авторизации и добавили шардирование по project_id. Эта ошибка стоила клиенту значительных репутационных потерь — и помогла нам отточить архитектуру, которую теперь используем во всех проектах. В статье разберём ключевые компоненты, которые превращают MVP в production-grade платформу: от escrow-моделей до быстрых выплат. Опираемся на опыт 50+ финтех- и маркетплейс-решений.
Как реализовать надёжное условное списание средств?
All-or-Nothing (AoN) — средства списываются только при достижении цели. Если кампания не собрала нужную сумму — все платежи возвращаются. Реализация: при бэкинге делаем authorization hold на карте (средства заморожены, но не списаны). При успехе кампании — capture, при провале — void.
# Stripe: создание PaymentIntent с capture_method=manual import stripe def back_project(user_id: str, project_id: str, amount: int, reward_tier_id: str) -> dict: payment_intent = stripe.PaymentIntent.create( amount=amount, currency="usd", capture_method="manual", # не списывать сразу metadata={ "user_id": user_id, "project_id": project_id, "reward_tier_id": reward_tier_id }, confirm=False # подтвердим на клиенте ) return {"client_secret": payment_intent.client_secret} def capture_all_backers(project_id: str): """Вызывается при успешном завершении кампании""" backers = db.get_backers(project_id, status="authorized") for backer in backers: stripe.PaymentIntent.capture(backer.payment_intent_id) db.update_backer_status(backer.id, "captured") def refund_all_backers(project_id: str): """Вызывается при провале кампании""" backers = db.get_backers(project_id, status="authorized") for backer in backers: stripe.PaymentIntent.cancel(backer.payment_intent_id) db.update_backer_status(backer.id, "cancelled") Проблема: авторизация на карте действует ограниченный срок — у Stripe это 7 дней для большинства карт, максимум 31 деньStripe Documentation: "Authorization holds". Кампании длиннее 30 дней — нельзя удерживать авторизацию всё это время. Решение: списывать сразу (Keep-it-All модель) или выполнять повторную авторизацию незадолго до истечения.
Keep-it-All (KiA) — средства списываются сразу при бэкинге, независимо от достижения цели. Технически проще, но менее привлекательна для бэкеров. Популярна для благотворительных и творческих проектов. По данным Statista, AoN-кампании собирают в среднем на 40% больше средств, чем KiA, поэтому для коммерческих проектов мы рекомендуем именно первую модель.
| Параметр | All-or-Nothing | Keep-it-All |
|---|---|---|
| Момент списания | При успехе кампании | Сразу при бэкинге |
| Доверие бэкеров | Высокое | Среднее |
| Сложность реализации | Высокая (авторизация, таймауты) | Низкая |
| Подходит для | Коммерческие проекты | Благотворительность, творчество |
Почему AoN предпочтительнее для больших проектов?
По данным Stripe, около 70% успешных краудфандинговых кампаний используют AoN. Бэкеры чувствуют себя увереннее, зная что их деньги не пропадут, если цель не будет достигнута.Уровни вознаграждений (Reward Tiers)
Каждый проект предлагает несколько уровней: «Поддержать» за $10, «Ранний доступ» за $50, «Эксклюзивный набор» за $200. У каждого уровня — количество доступных слотов и текущая заполненность.
// iOS: экран выбора уровня вознаграждения struct RewardTierView: View { let tier: RewardTier let onSelect: () -> Void var body: some View { VStack(alignment: .leading, spacing: 8) { HStack { Text("$\(tier.amount)") .font(.title2.bold()) Spacer() if let limit = tier.backerLimit { Text("\(tier.backerCount)/\(limit) поддержали") .font(.caption) .foregroundColor(tier.isSoldOut ? .red : .secondary) } } Text(tier.title).font(.headline) Text(tier.description).font(.body).foregroundColor(.secondary) if let estimatedDelivery = tier.estimatedDelivery { Label("Доставка: \(estimatedDelivery)", systemImage: "shippingbox") .font(.caption) } Button(tier.isSoldOut ? "Разобрано" : "Выбрать уровень") { if !tier.isSoldOut { onSelect() } } .disabled(tier.isSoldOut) } .padding() .background(.regularMaterial) .clipShape(RoundedRectangle(cornerRadius: 12)) } } Ограниченные слоты требуют pessimistic locking на сервере: при оформлении бэкинга блокируем строку reward_tier для проверки и декремента счётчика в одной транзакции.
Прогресс кампании и социальная механика
Страница проекта — центральный контент. Прогресс-бар собранных средств, обратный отсчёт до конца кампании, лента обновлений от автора, комментарии бэкеров.
Технически самый нагруженный момент: последний день кампании. Все бэкеры проверяют прогресс одновременно. WebSocket для реального времени или aggressive polling (каждые 10 секунд в последние часы) — с кешированием на CDN.
// Android: WebSocket для живого обновления прогресса class CampaignProgressViewModel( private val campaignId: String, private val wsClient: WebSocketClient ) : ViewModel() { val progress = MutableStateFlow<CampaignProgress?>(null) init { wsClient.connect("wss://api.yourplatform.com/campaigns/$campaignId/live") viewModelScope.launch { wsClient.messages.collect { message -> val update = json.decodeFromString<CampaignProgressUpdate>(message) progress.value = update.progress } } } override fun onCleared() { wsClient.disconnect() } } Обновления проекта и коммуникация с бэкерами
Автор публикует обновления о ходе работ. Бэкеры получают push-уведомления о каждом новом обновлении. Сегментация: уведомление только тем, кто поддержал именно этот проект.
FCM topic-based messaging для этого не подходит — нужна таргетированная рассылка через серверный список получателей. Для каждого проекта хранится список device_tokens бэкеров.
Как проходит верификация авторов (KYC) и почему это критически важно?
Публичный сбор средств привлекает мошеннические проекты. Базовая защита:
- Ручная модерация новых проектов перед публикацией
- Верификация личности автора через KYC (паспорт + селфи) — обязательна для вывода средств
- Автоматическое ограничение на вывод до подтверждения KYC
Процесс верификации пошагово:
- Автор заполняет профиль в приложении.
- Нажимает "Пройти верификацию" — система генерирует accessToken для KYC-провайдера.
- Открывается нативный SDK (Sumsub, Veriff или Onfido), где автор делает фото паспорта и селфи.
- SDK передаёт данные провайдеру, который проверяет документы и возвращает статус.
- Если статус
approved, автор может запросить вывод средств. Еслиrejected— отправляется на повторную проверку с комментарием.
Интеграция с KYC-провайдерами: Sumsub, Veriff, Onfido. Мобильное приложение инициирует KYC через SDK провайдера — процесс полностью в нативном UI. Гарантируем безопасность данных — все SDK сертифицированы.
// iOS: Sumsub KYC flow import IdensicMobileSDK let sdk = SNSMobileSDK.build( accessToken: kycAccessToken ) .withHandlers( onStatusDidChange: { [weak self] sdk, prevStatus in if sdk.mainState == .approved { self?.onKYCApproved() } }, onEvent: { sdk, event in } ) .assemble() sdk.present(from: self) Вывод средств для авторов
После успешного завершения кампании автор хочет получить деньги. Схема вывода:
- KYC пройден → можно запросить вывод
- Платформа удерживает комиссию (обычно 5–10%)
- Остаток выводится через Stripe Connect (payout на банковский счёт) или международным переводом
Stripe Connect — стандарт для маркетплейсов с выплатами. Каждый автор — отдельный Connected Account.
Что входит в нашу работу
- Аналитика требований и проектирование архитектуры
- Разработка под iOS (Swift 5.9+, SwiftUI) и Android (Kotlin, Jetpack Compose)
- Интеграция платежей (Stripe, Braintree) и KYC-провайдеров
- Настройка push-уведомлений (FCM/APNs), deep linking, App Tracking Transparency
- Модерация контента и anti-fraud алгоритмы
- Деплой в App Store и Google Play, тесты и поддержка
Ориентиры по срокам
| Scope | Срок |
|---|---|
| Базовая версия: просмотр и поддержка проектов, оплата, история | 6–8 недель |
| Кабинет автора: создание проектов, обновления, аналитика | +3–4 недели |
| All-or-Nothing с escrow и автоматическим capture/refund | +2 недели |
| KYC и вывод через Stripe Connect | +2–3 недели |
Стоимость рассчитывается индивидуально после анализа требований. Чтобы обсудить детали вашего проекта, оставьте заявку — мы свяжемся в течение дня. Получите консультацию по архитектуре — наши инженеры помогут выбрать оптимальное решение.







