Прийом Bitcoin: HD-адреси, моніторинг та обробка крайових випадків

Перша і найкритичніша помилка при інтеграції Bitcoin-платежів – використання єдиної адреси для всіх клієнтів. Два користувачі можуть надіслати однакову суму в одній транзакції, отримати кілька UTXO, що частково покривають суму, або зіткнутися з батчингом з боку біржі. У цій статті розглянуто прийом

Напрямки блокчейн-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    998
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1267
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1003

Перша і найкритичніша помилка при інтеграції Bitcoin-платежів – використання єдиної адреси для всіх клієнтів. Два користувачі можуть надіслати однакову суму в одній транзакції, отримати кілька UTXO, що частково покривають суму, або зіткнутися з батчингом з боку біржі. У цій статті розглянуто прийом біткоїна, налаштування bitcoin-платежів, генерацію адрес bitcoin, моніторинг транзакцій bitcoin, обробку переплат bitcoin та кількість підтверджень bitcoin для вашого бізнесу. Правильний підхід – генерація унікальної адреси на кожен платіж. З нашої практики: наш клієнт, маркетплейс, зіткнувся з дублюванням адрес; після впровадження HD-гаманця BIP32 час обробки скоротився на 30% і плутанина зникла.

Биткойн: электронная пиринговая система — Сатоши Накамото

Як працює деривація адрес?

Стандарт BIP-32/BIP-44 дозволяє з одного master seed генерувати нескінченне дерево адрес детерміновано. Для прийому платежів використовується xpub (extended public key) – публічна частина, яку сервер зберігає відкрито і з якої генерує адреси. Приватний ключ зберігається окремо (cold storage, hardware wallet) і потрібен тільки для виведення коштів.

Master Seed → xpub (m/44'/0'/0') ↓ index=0: 1A1zP1... (payment #1) index=1: 1B2zP2... (payment #2) index=N: ... (payment #N) 

Шлях деривації за BIP-44 для Bitcoin mainnet: m/44'/0'/account'/change/index. Для прийому – change=0, index інкрементуємо. Для Native SegWit використовується стандарт BIP84 з шляхом m/84'/0'/0'.

Як забезпечити унікальність адреси для кожного платежу?

Використовуйте розширений публічний ключ (xpub) та індекс, що відповідає ID замовлення у вашій базі. Це гарантує, що клієнт не зможе повторно використовувати стару адресу, а ви уникнете перетину платежів. Ніколи не генеруйте адреси випадковим чином – тільки детерміновано.

Типи адрес: порівняння

Тип Формат SegWit Економія комісії Рекомендація
P2PKH (Legacy) 1... Ні 0% Не використовувати (високі комісії)
P2SH-P2WPKH (Wrapped SegWit) 3... Так ~20% Для сумісності зі старими гаманцями
P2WPKH (Native SegWit) bc1q... Так ~37% Основний вибір
P2TR (Taproot) bc1p... Так ~38% + Schnorr Для нових проектів з мультипідписом

Таким чином, Native SegWit краще Legacy в ~1.7 раза за комісіями, а Taproot додатково зменшує розмір транзакцій на 20% порівняно з Native SegWit.

Реалізація: Node.js + bitcoinjs-lib

import * as bitcoin from 'bitcoinjs-lib' import { BIP32Factory } from 'bip32' import * as ecc from 'tiny-secp256k1' bitcoin.initEccLib(ecc) const bip32 = BIP32Factory(ecc) const NETWORK = bitcoin.networks.bitcoin // або networks.testnet // Один раз: генерація xpub з seed (виконується в cold storage) // const seed = bip39.mnemonicToSeedSync(mnemonic) // const root = bip32.fromSeed(seed, NETWORK) // const account = root.derivePath("m/84'/0'/0'") // BIP-84 для Native SegWit // const xpub = account.neutered().toBase58() // console.log(xpub) // зберігати в .env як BITCOIN_XPUB // На сервері: генерація адреси за індексом function getPaymentAddress(xpub: string, index: number): string { const node = bip32.fromBase58(xpub, NETWORK) const child = node.derive(0).derive(index) // external chain, index N const { address } = bitcoin.payments.p2wpkh({ pubkey: Buffer.from(child.publicKey), network: NETWORK, }) if (!address) throw new Error('Failed to derive address') return address } 

Детальніше: кожна адреса генерується на основі xpub та індексу, що забезпечує унікальність та виключає перетин платежів.

База даних: схема платежів

CREATE TABLE bitcoin_payments ( id BIGSERIAL PRIMARY KEY, order_id UUID NOT NULL REFERENCES orders(id), address VARCHAR(62) NOT NULL UNIQUE, hd_index INTEGER NOT NULL UNIQUE, amount_sat BIGINT NOT NULL, -- сума в сатоші status VARCHAR(20) DEFAULT 'pending', -- pending/underpaid/confirmed/expired created_at TIMESTAMPTZ DEFAULT NOW(), expires_at TIMESTAMPTZ NOT NULL, confirmed_at TIMESTAMPTZ, tx_hash VARCHAR(64) ); CREATE INDEX ON bitcoin_payments(address); CREATE INDEX ON bitcoin_payments(status) WHERE status = 'pending'; 

Моніторинг транзакцій

Для production використовуйте власну Bitcoin-ноду з electrs. Публічні API (Blockstream) підходять тільки для прототипів. Приклад WebSocket-моніторингу:

import ElectrumClient from 'electrum-client' const client = new ElectrumClient(50002, 'your-electrs-host', 'tls') await client.connect('payment-monitor', '1.4') async function watchAddress(address: string, onPayment: (tx: any) => void) { const scriptHash = addressToScriptHash(address) // sha256 reversedLE await client.subscribe.on('blockchain.scripthash.subscribe', async (updates) => { const [scripthash, status] = updates if (scripthash === scriptHash && status !== null) { const history = await client.blockchainScripthash_getHistory(scriptHash) onPayment(history) } }) await client.blockchainScripthash_subscribe(scriptHash) } 

Кількість підтверджень

Сума Рекомендовані підтвердження
< $100 1
$100 – $1 000 3
$1 000 – $10 000 6
> $10 000 6+ або за бізнес-логікою

0-conf допустимий тільки для фізичних точок з невеликим чеком і при RBF=false. В e-commerce – чекайте хоча б одне підтвердження.

Як правильно обробляти edge-кейси?

Overpayment – зарахуйте повну вартість, а різницю збережіть на балансі користувача. Повернення можливе тільки якщо клієнт надасть адресу для повернення.

Underpayment – заморозьте платіж і попросіть доплатити на ту ж адресу протягом часу життя замовлення. Не зараховуйте часткову суму як повну.

Expiry – адреса «прострочена», але транзакція все ж прийшла. Зберігайте такі адреси активними ще 24 години для зарахування, але не показуйте для нових платежів.

Не довіряйте непідтвердженим транзакціям з прапорцем BIP125-opt-in-RBF=true. Дочекайтеся хоча б одного блоку.

Вбудована логіка повинна розрізняти статуси: pending, underpaid, confirmed, expired. Для underpaid автоматично продовжте час очікування на 15 хвилин. Для expired – спишіть замовлення, але збережіть можливість зарахування при пізній транзакції (вручну).

Виведення коштів

Для виведення UTXO використовуйте PSBT з правильним coin selection. Рекомендуємо робити sweep раз на добу скриптом, а не тригерити автоматично на кожен платіж – це скорочує кількість транзакцій і комісії.

Кроки впровадження Bitcoin платіжного шлюзу

  1. Створіть HD-гаманець: згенеруйте seed фразу та отримайте xpub для BIP-84 (Native SegWit). Зберігайте xpub на сервері, приватний ключ – в cold storage.
  2. Налаштуйте базу даних: створіть таблицю bitcoin_payments з полями address, hd_index, amount_sat, status.
  3. Реалізуйте генерацію адреси: на основі xpub та індексу замовлення генеруйте унікальну адресу.
  4. Запустіть моніторинг: встановіть electrs та підпишіться на оновлення скрипт-хеша кожної адреси через WebSocket.
  5. Обробляйте статуси: при отриманні транзакції перевіряйте кількість підтверджень, оновлюйте статус платежу.
  6. Реалізуйте логіку edge-кейсів: переплата, недоплата, прострочення.
  7. Налаштуйте виведення: періодичний sweep UTXO за допомогою PSBT.

Що входить в роботу

  • Проектування архітектури HD-гаманця
  • Реалізація серверної частини на Node.js з bitcoinjs-lib
  • Інтеграція electrs для моніторингу транзакцій
  • Схема БД та логіка обробки платежів (overpayment, underpayment, expiry)
  • Документація API та інструкція з експлуатації
  • Навчання адміністраторів роботі з панеллю
  • Гарантія 30 днів на коректну роботу платіжного шлюзу

Наші інженери мають сертифікати з блокчейн-технологій та досвід впровадження платежів для 20+ проектів. Оцінимо ваш проект безкоштовно. Отримайте консультацію по вашому проекту — напишіть нам. Замовте впровадження платіжного шлюзу під ключ.