Реалізація QR-коду для приймання крипто-платежів у мобільному додатку
QR-код для приймання платежу — це не просто адреса в квадратиках. Правильний URI-формат дозволяє платнику автоматично заповнити суму та валюту у своєму гаманці. Неправильний розмір або відсутність error correction — і QR не читається половиною сканерів.
URI-формати для різних блокчейнів
Стандартні формати, які розпізнають більшість гаманців:
-
Bitcoin (BIP-21):
bitcoin:1A2B3C4D5E6F?amount=0.001&label=Order+123 -
Ethereum (EIP-681):
ethereum:0xAbCd1234@1?value=500000000000000000(value у wei) -
ERC-20 transfer (EIP-681):
ethereum:0xTokenAddress@1/transfer?address=0xRecipient&uint256=1000000(USDC, 6 decimалів) -
Solana (SPL):
solana:RecipientPubkey?amount=0.5&spl-token=TokenMintAddress&label=Payment
EIP-681 для ERC-20 — нотація неочевидна: спочатку адреса контракту токена, потім метод transfer з одержувачем та сумою. Багато гаманців підтримують спрощений формат: ethereum:0xRecipient?value=X&contractAddress=0xToken.
Генерація QR з правильними параметрами
// iOS — генерація QR через CoreImage з потрібним рівнем коррекції
import CoreImage.CIFilterBuiltins
func generateQRCode(from string: String, size: CGFloat = 300) -> UIImage {
let filter = CIFilter.qrCodeGenerator()
filter.message = Data(string.utf8)
filter.correctionLevel = "Q" // 25% error correction — для логотипу поверх QR
let transform = CGAffineTransform(scaleX: size / filter.outputImage!.extent.width,
y: size / filter.outputImage!.extent.height)
let scaledImage = filter.outputImage!.transformed(by: transform)
// Інтерполяція nearest neighbor для чіткості
let context = CIContext()
let cgImage = context.createCGImage(scaledImage, from: scaledImage.extent)!
return UIImage(cgImage: cgImage)
}
// Android — ZXing з кастомним розміром
import com.google.zxing.BarcodeFormat
import com.google.zxing.EncodeHintType
import com.google.zxing.qrcode.QRCodeWriter
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
val hints = mapOf(
EncodeHintType.ERROR_CORRECTION to ErrorCorrectionLevel.Q,
EncodeHintType.MARGIN to 1,
EncodeHintType.CHARACTER_SET to "UTF-8"
)
val bitMatrix = QRCodeWriter().encode(uri, BarcodeFormat.QR_CODE, 512, 512, hints)
Рівень коррекції Q (25%) — оптимально, якщо плануєте логотип поверх QR. Без логотипу достатньо M (15%).
Динамічна сума та вибір токена
Якщо у додатку є поле введення суми перед генерацією QR — URI оновлюється при кожній зміні суми. Для ERC-20 важливо врахувати decimals при формуванні value:
// Android — розрахунок value для USDC (6 decimалів)
val humanAmount = BigDecimal("100.50") // введено користувачем
val decimals = 6
val rawAmount = humanAmount.movePointRight(decimals).toBigInteger() // 100500000
val uri = "ethereum:${usdcContractAddress}@1/transfer?address=${recipientAddress}&uint256=$rawAmount"
Брендинг поверх QR
Логотип додатку в центрі QR — стандартна практика. Центральна зона до 30% площі — безпечна при рівні коррекції Q. Логотип повинен бути білим квадратом з іконкою, щоб не порушувати контрастність модулів QR.
Часовий графік: 1 день: генерація QR за коректним URI-форматом, поле введення суми, кнопки «Копіювати» та «Поділитися», опціональний логотип в центрі.







