Интеграция с Coinbase Commerce

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1306 услуг
Интеграция с Coinbase Commerce
Простой
~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
    886

Интеграция с Coinbase Commerce

Coinbase Commerce — non-custodial платёжный процессинг: средства поступают напрямую на ваш кошелёк, минуя Coinbase. Поддерживает BTC, ETH, USDC, DAI, LTC, BCH и ряд других активов. Ключевое отличие от custodial-процессингов: Coinbase не держит ваши деньги, нет KYC для получателя, нет риска заморозки средств со стороны процессора.

Что интегрируем

Два основных объекта API:

  • Charge — одноразовый платёжный запрос с фиксированной суммой, привязанный к конкретному заказу
  • Checkout — переиспользуемая платёжная страница (подходит для донатов, где сумма произвольная)

Для e-commerce используем Charges.

Создание Charge через API

const axios = require("axios");

async function createCharge(orderId, amountUSD, description) {
  const response = await axios.post(
    "https://api.commerce.coinbase.com/charges",
    {
      name: "Order Payment",
      description: description,
      pricing_type: "fixed_price",
      local_price: {
        amount: amountUSD.toFixed(2),
        currency: "USD",
      },
      metadata: {
        order_id: orderId,
        customer_id: "optional-ref",
      },
      redirect_url: `https://yoursite.com/orders/${orderId}/success`,
      cancel_url: `https://yoursite.com/orders/${orderId}/cancel`,
    },
    {
      headers: {
        "X-CC-Api-Key": process.env.COINBASE_COMMERCE_API_KEY,
        "X-CC-Version": "2018-03-22",
      },
    }
  );

  return response.data.data; // содержит hosted_url, code, addresses
}

hosted_url — готовая страница Coinbase Commerce, куда редиректим пользователя. Coinbase показывает адреса в разных сетях на выбор пользователя, QR, countdown таймер (15 минут по умолчанию для крипто-курса).

Обработка webhook

Самая важная часть. Coinbase Commerce шлёт события при каждом изменении статуса:

const crypto = require("crypto");

app.post("/webhooks/coinbase", express.raw({ type: "application/json" }), (req, res) => {
  const signature = req.headers["x-cc-webhook-signature"];
  const webhookSecret = process.env.COINBASE_COMMERCE_WEBHOOK_SECRET;

  // Верификация подписи — HMAC-SHA256 от raw body
  const expectedSig = crypto
    .createHmac("sha256", webhookSecret)
    .update(req.body)
    .digest("hex");

  if (signature !== expectedSig) {
    return res.status(401).json({ error: "Invalid signature" });
  }

  const event = JSON.parse(req.body);

  switch (event.type) {
    case "charge:confirmed":
      // Достаточно для товаров с низким риском
      await orderService.markConfirmed(event.data.metadata.order_id);
      break;

    case "charge:failed":
    case "charge:expired":
      await orderService.markFailed(event.data.metadata.order_id);
      break;

    case "charge:resolved":
      // Финальный успешный статус после underpayment-resolve или delayed payment
      await orderService.markResolved(event.data.metadata.order_id);
      break;
  }

  res.json({ received: true });
});

Важно: req.body должен быть raw Buffer при верификации подписи — не парсить через express.json() до верификации, иначе подпись не сойдётся.

Статусная машина Charge

NEW → PENDING (получена первая транзакция) → CONFIRMED → RESOLVED
                                           → EXPIRED (истёк таймер)
                                           → FAILED (underpayment, timeout)
                                           → UNRESOLVED (требует ручного разбора)

CONFIRMED наступает после достаточного количества confirmations (зависит от сети: Bitcoin — 3, Ethereum — 12). Для большинства товаров достаточно CONFIRMED. RESOLVED — финальный статус, означает полную обработку включая overpayment-возвраты.

Polling как fallback

Webhook может не дойти — настройте периодическую сверку. Coinbase Commerce API позволяет получить статус Charge по его коду:

// Запускать раз в 5 минут для pending charges
async function syncPendingCharges() {
  const pending = await db.getPendingCharges();

  for (const charge of pending) {
    const { data } = await coinbaseClient.get(`/charges/${charge.code}`);
    const timeline = data.data.timeline;
    const latestStatus = timeline[timeline.length - 1].status;

    if (["CONFIRMED", "RESOLVED"].includes(latestStatus)) {
      await orderService.markPaid(charge.orderId);
    }
  }
}

Что нужно реализовать

  • Эндпоинт создания Charge и редирект на hosted_url
  • Webhook handler с верификацией HMAC
  • Сохранение charge.code в базе для reconciliation
  • Fallback polling для pending charges
  • UI-страница ожидания с polling статуса (GET /charges/:code каждые 10 сек)