API, совместимый с Coinbase Commerce

Открыть в ChatGPTОткрыть в Claude

Эндпоинты charge, заголовок X-CC-Api-Key, объект charge и вебхуки с подписью X-CC-Webhook-Signature соответствуют документации Coinbase Commerce, поэтому официальные SDK работают после замены одной строки. Coinbase Commerce перестал обслуживать продавцов за пределами США и Сингапура с 2026-03-31. Переходите откуда-то ещё? См. обзор перехода.

Внутри это обычный счёт blockwallets: адреса для приёма ваши, страница оплаты — наша размещённая страница, а платёж засчитывается только после подтверждения в блокчейне и сверки со вторым узлом. Далее: три шага, затем что поддерживает каждый API и чем он отличается от оригинала — параметры, которые мы не реализовали, возвращают ошибку, а не молча игнорируются.

Три шага

  1. Получите аккаунт продавца (запросите доступ на главной странице) и добавьте свои домены в разделе «Домены сайта» на странице «Разработчикам › Интеграция и ключи» в кабинете. URL уведомлений (ipn_callback_url) и URL перенаправления (success_url / cancel_url / redirect_url) должны находиться на этих доменах или на домене вашего URL уведомлений — утёкший ключ не сможет направить вебхуки в другое место.
  2. Создайте совместимые учётные данные в кабинете продавца в разделе «Разработчикам › Интеграция и ключи», один набор для live и один для test: для NOWPayments — API key + IPN secret, для Coinbase Commerce — API key + webhook shared secret. Они показываются один раз; мы храним только хеши / шифртекст.
  3. Направьте код на базовый URL ниже и используйте новые ключи. Сначала запустите его в тестовых сетях с тестовыми учётными данными, затем переключитесь на live.
ДоПослеЗаголовок авторизацииПодпись вебхука
https://api.commerce.coinbase.comhttps://blockwallets.io/coinbase/X-CC-Api-KeyX-CC-Webhook-Signature (HMAC-SHA256)

Coinbase Commerce

Все официальные SDK принимают базовый URL — измените одну строку (не забудьте про завершающий /):

SDK
// Node(coinbase-commerce-node)
const { Client } = require("coinbase-commerce-node");
- Client.init(process.env.COINBASE_COMMERCE_API_KEY);
+ Client.init(process.env.COINBASE_COMMERCE_API_KEY, "https://blockwallets.io/coinbase/");

# Python(coinbase-commerce)
- client = Client(api_key=API_KEY)
+ client = Client(api_key=API_KEY, base_api_uri="https://blockwallets.io/coinbase/")

// PHP(coinbase/coinbase-commerce)
- ApiClient::init($apiKey);
+ ApiClient::init($apiKey, 'https://blockwallets.io/coinbase/');
curl
curl -X POST https://blockwallets.io/coinbase/charges \
  -H "X-CC-Api-Key: $COINBASE_COMMERCE_API_KEY" -H "X-CC-Version: 2018-03-22" \
  -H "content-type: application/json" \
  -d '{"name":"Order #12345","description":"Pro plan","pricing_type":"fixed_price",
       "local_price":{"amount":"100.00","currency":"USD"},
       "redirect_url":"https://shop.example/success","cancel_url":"https://shop.example/cancel",
       "metadata":{"order_id":"12345"}}'
# → 201 {"data": {"id": "…", "code": "7C7V5ECK", "hosted_url": "https://blockwallets.io/pay/inv_…", "timeline": [{"status": "NEW", …}], …}}

Поддерживаемые эндпоинты

ЭндпоинтПримечания
POST /chargesСоздать charge; hosted_url — наша размещённая страница оплаты; действует 1 час
GET /charges/:code_or_idПоиск по 8-символьному коду или id
GET /chargesСписок: limit (≤100) / starting_after / ending_before / order, с тем же объектом pagination
POST /charges/:code_or_id/cancelОтменить charge, по которому ещё не виден ни один платёж

Недоступно: /charges/:code/resolve (400 — недоплаченные charge разбирайте в кабинете), /checkouts, /events, /invoices (404).

Вебхуки

Вебхуки Coinbase настраиваются на уровне аккаунта, и наши тоже: они приходят на URL уведомлений, заданный в кабинете (charge, созданные с тестовыми учётными данными, приходят на тестовый URL). Тело — формат Coinbase {id, scheduled_for, attempt_number, event: {id, type, api_version, created_at, data}} с полным charge в data; X-CC-Webhook-Signature = HMAC-SHA256(shared secret, исходное тело), так что Webhook.verifyEventBody из SDK работает без изменений. При повторах event.id остаётся прежним, а attempt_number растёт — убирайте дубликаты по event.id.

Node.js
import crypto from "node:crypto";

// Same as the SDK's Webhook.verifySigHeader: HMAC-SHA256(shared secret, raw body)
function verifyWebhook(rawBody, sig, sharedSecret) {
  const hmac = crypto.createHmac("sha256", sharedSecret).update(rawBody, "utf8").digest("hex");
  return crypto.timingSafeEqual(Buffer.from(hmac), Buffer.from(sig || ""));
}
// verifyWebhook(rawBody, req.headers["x-cc-webhook-signature"], process.env.COINBASE_WEBHOOK_SECRET)
// or with the official SDK:Webhook.verifyEventBody(rawBody, signature, sharedSecret)
СобытиеКогдаПоследняя запись в timeline
charge:confirmedОплачен (подтверждён в блокчейне и сверен; переплата засчитывается)COMPLETED
charge:failedИстёк без оплаты / отменён вами / истёк с недоплатойEXPIRED / CANCELED / UNRESOLVED (контекст UNDERPAID)

При запросе вы увидите также NEW (ожидает оплаты) и PENDING (платёж виден в блокчейне, идут подтверждения). Выполняйте заказ по charge:confirmed: события charge:created, charge:pending, charge:delayed и charge:resolved мы не отправляем.

Отличия от Coinbase Commerce

Тестовый режим

Charge и платежи, созданные с тестовыми учётными данными, работают в тестовой сети каждого блокчейна, а их вебхуки подписываются тестовым IPN secret / shared secret — полностью отдельно от live: тестовый ключ не видит live-платежи.

Всё остальное (страница оплаты, подтверждения, сети и минимумы, возвраты) работает так же, как в основной документации.