Інтеграція з BTCPay Server
BTCPay Server — self-hosted процесор біткоін-платежів. Без третьої сторони, без KYC для продавця, без комісії крім on-chain. Для бізнесу, який хочу приймати BTC/LTC/Monero без залежності від Coinbase Commerce або BitPay — це стандартний вибір. Інтеграція займає від кількох годин до кількох днів залежно від глибини кастомізації.
Що таке BTCPay Server всередині
BTCPay — це .NET додаток, який запускає власні або підключається до зовнішніх повних вузлів (Bitcoin Core, LND для Lightning, Electrum server). Схема:
Ваш сайт → BTCPay API → Bitcoin Full Node
→ Lightning Network (LND / CLN)
→ Electrum Server (для Altcoins)
Для production розгортання потрібен VPS з мінімум 2 CPU / 4 GB RAM / 500 GB SSD (Bitcoin blockchain ~600 GB). BTCPay Docker Compose розгортає все автоматично.
Розгортання BTCPay Server
# На Ubuntu 22.04
git clone https://github.com/btcpayserver/btcpayserver-docker
cd btcpayserver-docker
export BTCPAY_HOST="pay.yourdomain.com"
export NBITCOIN_NETWORK="mainnet"
export BTCPAYGEN_CRYPTO1="btc"
export BTCPAYGEN_LIGHTNING="lnd"
export BTCPAYGEN_REVERSEPROXY="nginx"
export BTCPAYGEN_ADDITIONAL_FRAGMENTS="opt-save-storage"
. ./btcpay-setup.sh -i
opt-save-storage включає Bitcoin pruned mode (зберігає тільки останні ~1 GB блоків). Для Electrum-індексування потрібен full node, але для базового приймання платежів pruned достатньо.
API: створення інвойсів
BTCPay Greenfield API v1 — RESTful, документація на /docs:
const BTCPAY_BASE = 'https://pay.yourdomain.com';
const STORE_ID = process.env.BTCPAY_STORE_ID!;
const API_KEY = process.env.BTCPAY_API_KEY!; // Generated in BTCPay → Account → API Keys
async function createInvoice(params: {
amount: number;
currency: string;
orderId: string;
buyerEmail?: string;
}): Promise<BTCPayInvoice> {
const response = await fetch(
`${BTCPAY_BASE}/api/v1/stores/${STORE_ID}/invoices`,
{
method: 'POST',
headers: {
'Authorization': `token ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: params.amount.toString(),
currency: params.currency, // 'USD', 'EUR' — BTCPay сам конвертує в BTC
metadata: {
orderId: params.orderId,
buyerEmail: params.buyerEmail,
},
checkout: {
speedPolicy: 'MediumSpeed', // 2 підтвердження
expirationMinutes: 30,
redirectURL: `https://yourshop.com/orders/${params.orderId}`,
defaultPaymentMethod: 'BTC',
},
}),
}
);
return response.json();
}
speedPolicy:
-
HighSpeed— 0 підтвердження (mempool), тільки для довірених покупців або Lightning -
MediumSpeed— 1 підтвердження (~10 хв) -
LowMediumSpeed— 2 підтвердження -
LowSpeed— 6 підтвердження (~1 година)
Webhook: обробка подій оплати
У BTCPay Store Settings → Webhooks додайте URL та секрет:
import { createHmac } from 'crypto';
app.post('/webhooks/btcpay', express.raw({ type: 'application/json' }), async (req, res) => {
// Верифікація підпису
const signature = req.headers['btcpay-sig1'] as string;
const expectedSig = 'sha256=' + createHmac('sha256', process.env.BTCPAY_WEBHOOK_SECRET!)
.update(req.body)
.digest('hex');
if (signature !== expectedSig) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body.toString());
switch (event.type) {
case 'InvoiceSettled':
// Оплачено та підтверджено згідно speedPolicy
await fulfillOrder(event.metadata.orderId);
break;
case 'InvoiceExpired':
await cancelOrder(event.metadata.orderId);
break;
case 'InvoicePaymentSettled':
// Конкретний платіж підтверджений (актуально при partial payments)
break;
}
res.sendStatus(200);
});
Важливо: завжди верифікуйте HMAC підпис. BTCPay повторює доставку webhook при неуспішній відповіді.
Lightning Network: платежі за секунди
Якщо включили LND при розгортанні — Lightning працює з коробки:
// Інвойс спеціально для Lightning
const lightningInvoice = await fetch(
`${BTCPAY_BASE}/api/v1/stores/${STORE_ID}/lightning/BTC/invoices`,
{
method: 'POST',
headers: { 'Authorization': `token ${API_KEY}` },
body: JSON.stringify({
amount: '1000', // в millisatoshis
description: `Order ${orderId}`,
expiry: 900, // 15 хвилин
}),
}
).then(r => r.json());
// Повертає BOLT11 payment request для QR-коду
console.log(lightningInvoice.BOLT11);
Для Lightning: канали потрібно відкрити та підтримувати вхідну ліквідність. Для невеликих магазинів — 1–2 каналів з крупними hub-нодами (ACINQ, WalletOfSatoshi) достатньо.
Кастомний checkout
BTCPay дозволяє кастомізувати checkout сторінку через Templates або використовувати Payment Request UI. Для повного контролю над UX — embedded checkout через iframe:
<iframe
src="https://pay.yourdomain.com/i/{invoiceId}"
style="width: 100%; height: 600px; border: none;"
allow="payment"
title="Embedded content from pay.yourdomain.com">
</iframe>
Або слухайте подій через postMessage:
window.addEventListener('message', (event) => {
if (event.origin !== 'https://pay.yourdomain.com') return;
if (event.data === 'invoiceSettled') {
// Платіж пройшов, оновіть UI
redirectToThankYouPage();
}
});
Мультивалютність
BTCPay підтримує LTC, XMR, ETH (через NBXplorer) та інші. При розгортанні додайте:
export BTCPAYGEN_CRYPTO2="ltc"
export BTCPAYGEN_CRYPTO3="xmr"
Для ETH та ERC-20 — окремий плагін BTCPayServer.Plugins.Ethereum у настройках.
Резервне копіювання
Критичні дані для бекапу:
- Seed фраза LND wallet (
~/.lnd/data/chain/bitcoin/mainnet/wallet.db) - BTCPay база даних (PostgreSQL:
btcpayserver) - Настройки store та API ключи (експорт з UI)
Втрата LND wallet seed = втрата коштів у відкритих каналах. Бекап обов'язковий до відкриття будь-яких каналів.







