Інтеграція криптоплатіжного шлюзу в e-commerce — не просто підключення SDK. Часто стикаємося з ситуацією, коли після створення інвойсу webhook не приходить або статуси дублюються, і бухгалтерія не може звести кінці з кінцями. BitPay вирішує ці проблеми, але вимагає правильної обробки статусів та ідемпотентності.
Ми інтегруємо BitPay у ваш бізнес: налаштовуємо прийом BTC, ETH, USDC, USDT через Ethereum, Polygon, Arbitrum, Base. BitPay бере на себе юридичну документацію та конвертацію у фіат. Наша команда реалізувала 25+ криптовалютних інтеграцій. BitPay в 3 рази швидше в налаштуванні, ніж самописний шлюз. Оцінимо проект безкоштовно — зв'яжіться з нами.
Як влаштований платіжний потік?
API працює через рахунки-фактури (invoices): ваш backend створює інвойс на BitPay, отримує URL для редиректу користувача, BitPay приймає оплату та повідомляє ваш webhook. Повна документація доступна в BitPay API Reference.
Чому ECDSA-аутентифікація складніша, ніж ключ API?
BitPay використовує підпис запитів приватним ключем замість статичного токена. Це безпечніше, але вимагає генерації ECDSA keypair та реєстрації публічного ключа як токена.
Для більшості інтеграцій простіше використовувати офіційний BitPay SDK (Node.js, PHP, Python, Ruby, Java) — він інкапсулює підпис запитів.
const BitPaySDK = require('bitpay-sdk'); const fs = require('fs'); // Генерація ключів та отримання токена (один раз) async function setupBitPay() { const client = new BitPaySDK.Client( null, // конфіг файл BitPaySDK.Env.Prod, // або Env.Test для testnet fs.readFileSync('./private.key', 'utf8') // ECDSA приватний ключ ); // Токен з BitPay Dashboard → API Tokens await client.authorizeClient('your-pairing-code'); return client; } Створення інвойсу
const BitPaySDK = require('bitpay-sdk'); async function createInvoice(orderId, amount, currency = 'USD') { const invoice = new BitPaySDK.Models.Invoice(amount, currency); invoice.orderId = orderId; invoice.notificationUrl = `https://yourapp.com/webhooks/bitpay`; invoice.redirectUrl = `https://yourapp.com/orders/${orderId}/success`; invoice.closeUrl = `https://yourapp.com/orders/${orderId}/cancel`; // Метадані для reconciliation invoice.buyer = new BitPaySDK.Models.Buyer(); invoice.buyer.email = customerEmail; // Опціонально: приймати тільки конкретну монету // invoice.paymentCurrencies = ['BTC', 'USDC']; const created = await client.createInvoice(invoice); return { invoiceId: created.id, paymentUrl: created.url, // редирект користувача expirationTime: created.expirationTime }; } Інвойс дійсний 15 хвилин за замовчуванням — користувач має оплатити в цей період. Сума в USD фіксується за курсом BitPay на момент створення інвойсу.
Webhook обробка
BitPay надсилає IPN (Instant Payment Notification) на notificationUrl. Критично перевіряти статус інвойсу через API, а не просто довіряти webhook-даним.
const express = require('express'); const router = express.Router(); router.post('/webhooks/bitpay', async (req, res) => { const { id: invoiceId, status } = req.body.data || {}; if (!invoiceId) { return res.status(400).json({ error: 'Missing invoice ID' }); } // ВАЖЛИВО: верифікуємо через API, не довіряємо тілу webhook const invoice = await client.getInvoice(invoiceId); switch (invoice.status) { case 'paid': // Оплачено, але чекаємо підтверджень (зазвичай 1-6 блоків) await updateOrderStatus(invoice.orderId, 'paid_unconfirmed'); break; case 'confirmed': // Достатньо підтверджень (зазвичай 1 для більшості монет) await updateOrderStatus(invoice.orderId, 'confirmed'); break; case 'complete': // Всі підтвердження отримані, кошти зараховані await fulfillOrder(invoice.orderId); break; case 'expired': await updateOrderStatus(invoice.orderId, 'expired'); break; case 'invalid': // Underpayment або інша помилка await handleInvalidPayment(invoice.orderId, invoice); break; } res.json({ success: true }); }); | Статус | Опис | Дія |
|---|---|---|
new | Інвойс створено, очікує оплати | Чекати |
paid | Оплачено, але непідтверджено | Ставити в чергу |
confirmed | Мінімум підтверджень (зазвичай 1) | Зараховувати частково |
complete | Всі підтвердження, кошти зараховані | Виконувати замовлення |
expired | Користувач не оплатив за 15 хвилин | Скасовувати |
invalid | Недоплата або помилка | Повернення |
Для фулфілменту використовуйте confirmed або complete залежно від tolerance до ризику. complete — найбезпечніший, але затримка більша.
Повернення (Refunds)
BitPay вимагає адресу для повернення — її потрібно запитати у користувача в момент оплати або при ініціації повернення.
async function createRefund(invoiceId, amount, currency) { const refund = new BitPaySDK.Models.Refund(); refund.invoiceId = invoiceId; refund.amount = amount; refund.currency = currency; // валюта повернення const created = await client.createRefund(refund); // BitPay надішле email користувачу із запитом адреси return created; } Ризики, що покриваються BitPay
BitPay обробляє безпеку транзакцій, гарантує відсутність chargeback (нескасовувані платежі) та надає сертифіковані звіти для бухгалтерії. Згідно з офіційною документацією, платформа не вимагає додаткового узгодження з регуляторами.
Порівняння BitPay та самописного шлюзу
| Параметр | BitPay | Самописний шлюз |
|---|---|---|
| Час запуску | 2–3 дні | 2–4 тижні |
| Юридична підтримка | Готова документація | Потребує юриста |
| Конвертація у фіат | Автоматична | Потрібен обмінник |
| Безпека | ECDSA + PCI-сертифікат | Повна відповідальність |
Типові проблеми при інтеграції
Webhook не приходить. BitPay вимагає HTTPS з валідним сертифікатом на notificationUrl. Localhost недоступний — для розробки використовуйте ngrok або BitPay Testnet з публічним URL.
Дублюючі webhook-и. BitPay може надіслати кілька повідомлень про один статус (retry при таймауті). Використовуйте invoiceId як idempotency key: INSERT ... ON CONFLICT (invoice_id, status) DO NOTHING.
Partial payment. Якщо користувач оплатив менше — статус invalid. BitPay автоматично повертає underpayment за наявності email покупця.
Timezone в expirationTime. Поле повертається як Unix timestamp в мілісекундах. new Date(invoice.expirationTime) — не забудьте про мс, не секунди.
Тестування
BitPay надає Testnet середовище (BitPaySDK.Env.Test) з тестовим Bitcoin. Створюєте інвойс, платите з testnet гаманця — весь flow без реальних грошей. Парінг-код для тестового середовища створюється окремо в dashboard.
Що входить в роботу
- Інтеграція SDK BitPay (Node.js, PHP, Python, Ruby, Java)
- Налаштування webhook-ендпоінта з ідемпотентністю
- Обробка статусів та edge cases (прострочений інвойс, partial payment, retry)
- Тестування на Testnet та деплой
- Документація по вашій реалізації
- Підтримка 30 днів після запуску
Терміни орієнтовно
2–3 дні: 1 день на SDK, 1 день на webhook + статус-машину, 1 день на тестування. Конкретна вартість розраховується індивідуально залежно від складності інтеграції. Отримайте консультацію — зв'яжіться з нами для оцінки вашого проекту. Замовте інтеграцію BitPay, і ми налаштуємо прийом криптовалют за 48 годин.







