Розробка мобільного додатку для краудфандингу
Краудфандинг—це Kickstarter або Indiegogo у вашому смартфоні. Але якщо спростити до «користувачі платять за проект», отримаємо нежизнеспособний продукт. Реальна складність: умовне резервування коштів (escrow), логіка All-or-Nothing vs. Keep-it-All, система вознаграджень з різними рівнями та регуляторні вимоги до публічного збору коштів.
Моделі фінансування та їх реалізація
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 день. Кампанії довше 30 днів—не можемо утримувати авторизацію весь цей час. Рішення: списувати одразу (Keep-it-All модель) або виконувати повторну авторизацію незадовго до закінчення.
Keep-it-All (KiA)—кошти списуються одразу при бекінгу, незалежно від досягнення цілі. Технічно простіше, але менш привабливо для бекерів. Популярна для благодійних та творчих проектів.
Рівні вознаграджень (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 бекерів.
Модерація та anti-fraud
Публічний збір коштів привлекає шахрайські проекти. Базовий захист:
- Ручна модерація нових проектів перед публікацією
- Верифікація особистості автора через KYC (паспорт + селфі)—обов'язкова для виведення коштів
- Автоматичне обмеження на виведення до підтвердження KYC
Інтеграція з KYC-провайдерами: Sumsub, Veriff, Onfido. Мобільний додаток ініціює KYC через SDK провайдера—процес повністю в нативному UI.
// 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.
Ориентири по терміні
| Scope | Терміни |
|---|---|
| Базова версія: перегляд та підтримка проектів, оплата, історія | 6–8 тижнів |
| Кабінет автора: створення проектів, оновлення, аналітика | +3–4 тижні |
| All-or-Nothing з escrow та автоматичним capture/refund | +2 тижні |
| KYC та виведення через Stripe Connect | +2–3 тижні |
Вартість розраховується індивідуально після аналізу вимог.







