Интеграция с BitPay

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1306 услуг
Интеграция с BitPay
Простой
~2-3 дня
Часто задаваемые вопросы

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

Этапы блокчейн-разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1307
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1219
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    920
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1148
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    611
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    885

Интеграция с BitPay

BitPay — один из старейших криптоплатёжных процессоров, запущен в 2011 году. Сегодня поддерживает BTC, ETH, USDC, USDT, несколько сетей (Ethereum, Polygon, Arbitrum, Base), автоматическую конвертацию в фиат. Для бизнеса который хочет принимать крипту без собственной инфраструктуры и с готовой юридической документацией — разумный выбор.

API работает через счёт-фактуры (invoices): ваш backend создаёт инвойс на BitPay, получает URL для перенаправления пользователя, BitPay принимает оплату и уведомляет ваш webhook.

API аутентификация

BitPay использует нестандартную схему аутентификации на основе ECDSA-подписей. Клиент генерирует ECDSA keypair, публичный ключ регистрируется как «токен» на BitPay. Каждый запрос подписывается приватным ключом.

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;
}

Для большинства интеграций проще использовать официальный BitPay SDK (Node.js, PHP, Python, Ruby, Java) — он инкапсулирует подпись запросов.

Создание инвойса

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':
            // Оплачен, но ждём подтверждений
            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 });
});

Цепочка статусов: newpaidconfirmedcomplete. Для фулфилмента используйте 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;
}

Типичные проблемы при интеграции

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.

Процесс интеграции

Регистрация → создание API токена → интеграция SDK в backend → webhook endpoint → тестирование на Testnet → production паринг.

Срок 2-3 дня: 1 день на SDK интеграцию и создание инвойсов, 1 день на webhook + статус-машину, 1 день на тестирование и edge cases (истёкший инвойс, partial payment, webhook retry).