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

> Перейдите с Coinbase Commerce на blockwallets, сменив базовый URL SDK и ключи: поддерживаемые эндпоинты charge, вебхуки и подписи, отличия.
>
> HTML: https://blockwallets.io/docs/coinbase-commerce?lang=ru · English: https://blockwallets.io/docs/coinbase-commerce.md?lang=en

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

Эндпоинты charge, заголовок `X-CC-Api-Key`, объект charge и вебхуки с подписью `X-CC-Webhook-Signature` соответствуют документации Coinbase Commerce, поэтому официальные SDK работают после замены одной строки. Coinbase Commerce перестал обслуживать продавцов за пределами США и Сингапура с 2026-03-31. Переходите откуда-то ещё? См. [обзор перехода](https://blockwallets.io/docs/migrate?lang=ru).

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

### Три шага

- Получите аккаунт продавца ([запросите доступ на главной странице](https://blockwallets.io/?lang=ru#join)) и добавьте свои домены в разделе «Домены сайта» на странице «Разработчикам › Интеграция и ключи» в кабинете. URL уведомлений (`ipn_callback_url`) и URL перенаправления (`success_url` / `cancel_url` / `redirect_url`) должны находиться на этих доменах или на домене вашего URL уведомлений — утёкший ключ не сможет направить вебхуки в другое место.

- Создайте совместимые учётные данные в кабинете продавца в разделе «Разработчикам › Интеграция и ключи», один набор для live и один для test: для NOWPayments — **API key + IPN secret**, для Coinbase Commerce — **API key + webhook shared secret**. Они показываются один раз; мы храним только хеши / шифртекст.

- Направьте код на базовый URL ниже и используйте новые ключи. Сначала запустите его в тестовых сетях с тестовыми учётными данными, затем переключитесь на live.

| До | После | Заголовок авторизации | Подпись вебхука |
| --- | --- | --- | --- |
| `https://api.commerce.coinbase.com` | `https://blockwallets.io/coinbase/` | `X-CC-Api-Key` | `X-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`.

```nodejs
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

- `pricing_type` должен быть `fixed_price`; `local_price.currency` должна быть USD (USDC / USDT 1:1). `no_price` и другие фиатные валюты возвращают 400.

- Адрес появляется, когда клиент выбирает монету и сеть на странице оплаты: в `addresses` только эта сеть, в `pricing` после выбора только `local` и `settlement`; полей `exchange_rates`, `checkout` и брендинга нет.

- `metadata` сохраняется и возвращается как есть (до 4 КБ).

- Возвраты в timeline не отображаются; смотрите их в кабинете.

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

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

Всё остальное (страница оплаты, подтверждения, сети и минимумы, возвраты) работает так же, как в [основной документации](https://blockwallets.io/docs/cryptomus?lang=ru).
