Впровадження прийому крипто-платежів через мобільний додаток (мерчант)
Мерчанту потрібно прийняти крипто-платіж у точці продажу або в інтернет-магазині. Мобільний додаток — це касовий термінал: ввів суму, показав QR покупателю, дождався підтвердження, зафіксував продаж. Все це має працювати швидко та без складної настройки.
Генерація платіжної адреси та QR
Генеруйте нову адресу за транзакцію — спрощує зіставлення «який платіж за який замовлення». HD-гаманець (BIP-32/BIP-44) дозволяє деривацію адрес: m/44'/60'/0'/0/N.
// iOS — деривація наступної адреси з HD гаманця (secp256k1)
import HDWalletKit
func nextReceivingAddress(masterKey: HDPrivateKey, accountIndex: UInt32) -> String {
let derived = masterKey
.derived(at: 44, hardened: true)
.derived(at: 60, hardened: true) // ETH
.derived(at: 0, hardened: true) // account
.derived(at: 0) // external chain
.derived(at: accountIndex)
return derived.publicKey.ethereumAddress
}
Зберігайте accountIndex локально, інкрементуйте за платіж. Серверна частина має мониторити всі використовувані адреси.
QR-код з таймером курсу
Крипто курси змінюються. Щоб покупатель заплатив рівно потрібну суму:
- Мерчант вводить суму у фіаті (1000 RUB)
- Додаток запитує поточний курс (CoinGecko
/simple/price?ids=tether&vs_currencies=rub) - Розраховує суму у крипто з буфером:
amount_usdt = fiat_amount / rate * 1.005(0.5% слиппаж) - Фіксує курс на 15 хвилин, показує таймер
- Генерує QR з URI:
ethereum:0xUsdtAddress@1/transfer?address=0xMerchant&uint256=<raw_amount>
// Android — розрахунок суми у крипто з буфером
fun calculateCryptoAmount(
fiatAmount: BigDecimal,
ratePerUnit: BigDecimal,
slippagePercent: BigDecimal = BigDecimal("0.5"),
decimals: Int = 6 // USDT: 6
): BigInteger {
val slippageFactor = BigDecimal.ONE + slippagePercent / BigDecimal(100)
val cryptoAmount = fiatAmount.divide(ratePerUnit, 10, RoundingMode.HALF_UP) * slippageFactor
return cryptoAmount.movePointRight(decimals).toBigInteger()
}
При закінченні таймера — оновіть QR з новим курсом. Попередження: «Час дії QR істік, оновлюємо ціну».
Очікування та підтвердження транзакції
Після показу QR — додаток слухає вхідні транзакції на платіжну адресу. Два варіанти:
Polling через API: Запитуйте Etherscan API / Blockscout щоперепини 5–10 секунд:
GET https://api.etherscan.io/api?module=account&action=tokentx&address={paymentAddress}&startblock={latest}
WebSocket від сервера: Backend мониторить блокчейн та відправляє подію через WebSocket або push при отриманні транзакції.
Перший варіант простіший, але дорогий при масштабуванні. Другий — правильний для продакшену.
Статуси платежу
// iOS — конечний автомат статусів платежу
enum PaymentStatus {
case awaitingPayment(expiresAt: Date)
case detected(txHash: String, confirmations: Int)
case confirmed(txHash: String, amountReceived: BigDecimal)
case underpaid(expected: BigDecimal, received: BigDecimal)
case expired
case failed(reason: String)
}
На detected — зелений екран «Платіж виявлено, чекаємо підтверджень (1/3)». На confirmed — звук касси, повний екран успіху з сумою.
Часткова оплата та таймаут
Якщо покупатель заплатив менше — underpaid. Три варіанти стратегії:
- Чекати додаткову оплату до витягу розширеного таймера (1–24 години)
- Прийняти частково з записом задолженості
- Автовозврат (складно — потребує зберігання ключів для повернення)
Виберіть стратегію в налаштуваннях додатка мерчанта.
Історія транзакцій та звіти
Список прийнятих платежів: дата, сума у крипто та фіаті за курсом на момент оплати, статус, TxHash (посилання на Explorer). Фільтри по даті та статусу. CSV експорт — для бухгалтерії.
Часова шкала: 5 робочих днів: HD-адреса per order, генерація QR з URI-форматом та таймером курсу, polling/WS вхідних транзакцій, екран підтвердження зі звуком, історія з фільтрами.







