Інтеграція з 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);
    }
  }
}

Що потрібно реалізувати

  • Endpoint створення Charge і редирект на hosted_url
  • Webhook handler з верифікацією HMAC
  • Збереження charge.code в базі для reconciliation
  • Fallback polling для pending charges
  • UI-сторінка очікування з polling статусу (GET /charges/:code кожні 10 сек)