Реалізація конвертації криптовалюти в фіат у мобільному додатку мерчанта
Мерчант прийняв оплату в USDT, а на наступний день виявив, що курс просів на 4% та гроші так і лежать на кошельку. Автоматична конвертація в фіат одразу після підтвердження транзакції — не "nice to have", а вимога бізнесу. Реалізувати це в мобільному додатку складніше, ніж здається: потрібно синхронізувати события on-chain з конвертацією через CEX або процесинг без втрати транзакції при збоях.
Архітектура конвертації
Два основних підходи — через платіжний процесинг (Coinbase Commerce, NOWPayments, CryptoCloud) та через пряму інтеграцію з біржею (Binance API, Bybit API). У кожного своя логіка на мобільному клієнті.
Через платіжний процесинг
NOWPayments та аналоги приймають крипту та автоматично конвертують у фіат до моменту виводу. Мобільний клієнт робить POST /v1/payment з параметром payout_currency: "USD" — процесинг бере на себе ризик курсової різниці. Додатку залишається:
- Запросити адресу для оплати та суму
- Показати QR-код або Deep Link (
bitcoin:addr?amount=0.001) - Polling статусу через
GET /v1/payment/{id}кожні 15 секунд або WebSocket - Показати статус:
waiting → confirming → confirmed → finished
Проблема polling — коли мережа біткоїна перевантажена, confirming може висіти 40+ хвилин. Користувач закроє додаток. Потрібно push-сповіщення через FCM/APNs при зміні статусу — бекенд отримує webhook від процесингу та розсилає push.
Через Binance API
Пряма інтеграція: після отримання крипти на кастодіальний кошельок робимо POST /sapi/v1/convert/getQuote — отримуємо котировку, потім POST /sapi/v1/convert/acceptQuote. Квота дійсна 10 секунд. Якщо прострочена — повтор. На мобільному клієнті цей процес схований за бекендом; клієнт бачить тільки фінальний фіатний баланс.
// Приклад відображення статусу конвертації (SwiftUI)
struct ConversionStatusView: View {
@StateObject var viewModel: ConversionViewModel
var body: some View {
switch viewModel.status {
case .waitingPayment(let address, let amount):
QRCodeView(address: address, amount: amount)
case .confirming(let confirmations, let required):
ConfirmationProgressView(current: confirmations, required: required)
case .converting:
LoadingView(text: "Конвертуємо в USD...")
case .completed(let fiatAmount):
SuccessView(amount: fiatAmount)
case .failed(let error):
ErrorView(error: error)
}
}
}
Робота з курсом та проскальзуванням
Користувач бачить "отримаєте $99.50" — а по факту приходить $97.80 через проскальзування при конвертації. Потрібно явно показувати estimated_rate та locked_rate (якщо процесинг підтримує lock курса на 15–20 хвилин). CryptoCloud підтримує фіксацію курса; NOWPayments — ні.
Для відображення live-курса у додатку використовуємо WebSocket від Binance wss://stream.binance.com:9443/ws/btcusdt@ticker або CoinGecko REST з кешуванням на 30 секунд.
Безпека на мобільному клієнті
Приватні ключі кошельків — ніколи на мобільному пристрої. Мобільний клієнт спілкується тільки з власним бекендом. API-ключі до бірж — тільки на сервері, захищені через Vault або змінні середовища. На iOS використовуємо Keychain для зберігання сесійних токенів, на Android — EncryptedSharedPreferences з Jetpack Security.
Етапи та сроки
Аудит бізнес-вимог → вибір процесингу або CEX → реалізація серверного шару конвертації → мобільний клієнт з polling/WebSocket → push-сповіщення → тестування у Testnet/Sandbox.
3–5 днів для інтеграції через готовий процесинг. 2–3 тижні при прямій інтеграції з біржею з обробкою помилок та ретраями. Вартість розраховується індивідуально після аналізу вимог.







