# API blockwallets, совместимый с Cryptomus

> API blockwallets, совместимый с Cryptomus: счета и статические кошельки, подпись, вебхуки и их проверка, тестовый режим, сети, ошибки и переход с Cryptomus заменой домена.
>
> HTML: https://blockwallets.io/docs/cryptomus?lang=ru · English: https://blockwallets.io/docs/cryptomus.md?lang=en

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

blockwallets принимает USDT и USDC, а также BTC, LTC, DOGE, BCH и нативные монеты (зачисляются в долларах США по зафиксированному курсу): клиент платит, мы подтверждаем платёж в блокчейне и уведомляем вас. API, подписи и вебхуки такие же, как у **Cryptomus** — если вы уже интегрировали Cryptomus, смените домен, и всё. Сначала о том, как это работает, затем об API.

### Два способа приёма

Оба принимают **любую сумму**: заказы с фиксированной ценой и пополнения, где клиент вводит сумму сам. После оплаты вы отгружаете заказ или зачисляете сумму на баланс клиента. Разница только в том, **получает ли каждый платёж новый адрес**.

Рекомендуется · большинство интеграций**Счета**
Клиент выбирает товар или вводит сумму на вашей странице, вы создаёте счёт, и он отправляет сумму, указанную на странице оплаты. У каждого счёта новый адрес и обратный отсчёт; когда платёж приходит, мы уведомляем вас с фактически полученной суммой.

`POST /v1/payment` → вебхук `type: payment`

По желанию**Статические кошельки**
Сумма заранее не задаётся: каждый клиент получает постоянный адрес в каждой сети, сохраняет его в своём кошельке и отправляет на него в любое время. Каждый перевод вызывает отдельный вебхук.

`POST /v1/wallet` → вебхук `type: wallet`

Если сомневаетесь, используйте счета. Без кода подойдут [платёжные ссылки](https://blockwallets.io/docs/cryptomus?lang=ru#links) в кабинете — это счета, которые создаются за вас. Ещё не продавец? Запросите доступ на [главной странице](https://blockwallets.io/?lang=ru#join); после одобрения войдите в [кабинет продавца](https://blockwallets.io/dashboard) и начните с пункта «Пробный платёж» на главной странице кабинета, заплатив небольшую сумму (деньги поступят на ваш собственный баланс).

### Как проходит счёт

В платеже участвуют четыре стороны: клиент, ваш сайт, blockwallets и блокчейн. Схема идёт сверху вниз по времени; правый столбец — статус счёта на каждом шаге.

Коротко, пять шагов:

- Вы создаёте счёт (платёжная ссылка делает это за вас, либо ваш сервер вызывает `/v1/payment`), получаете `url` страницы оплаты и перенаправляете туда клиента.

- На странице оплаты клиент выбирает монету и сеть, получает отдельный адрес и сумму и платит из кошелька или с биржи.

- Мы видим перевод в блокчейне, ждём достаточного числа подтверждений, затем сверяем его со вторым поставщиком узлов (чтобы один узел не мог подделать платёж).

- Счёт получает статус `paid`, и мы сразу отправляем POST с подписанным вебхуком на ваш `url_callback`; через несколько секунд страница оплаты возвращает клиента на ваш `url_success`.

- Деньги зачисляются на ваш баланс; выводите их на свой кошелёк из кабинета продавца.

#### Статус счёта

| status | Значение | Что делаете вы |
| --- | --- | --- |
| `check` | Ожидает оплаты | — |
| `confirm_check` | Перевод виден, ждём подтверждений | — |
| `wrong_amount_waiting` | Получено меньше нужного; клиент может доплатить на тот же адрес (если `is_payment_multiple` равен true; уведомление приходит один раз) | — (после доплаты придёт `paid`) |
| `paid` | Оплачен | Отгрузите или зачислите по `payment_amount_usd` |
| `paid_over` | Оплачен с переплатой | То же (`payment_amount_usd` — полученная сумма) |
| `wrong_amount` | Истёк, полная сумма не получена (при `is_payment_multiple` false — первый же недоплаченный перевод) | Сервисы с пополнением могут зачислить полученную сумму `payment_amount_usd`; магазины просят клиента доплатить остаток |
| `cancel` | Истёк, ничего не получено | — (деньги, пришедшие позже, всё равно зачисляются и приходят в уведомлении) |

Если `is_final` равен `true`, статус больше не изменится (кроме поздних платежей).

### Платёжные ссылки (без кода)

Кабинет продавца → «Платежи › Платёжные ссылки» → введите описание и сумму (зафиксируйте сеть или дайте клиенту выбрать) → создайте. У каждой ссылки есть URL и QR-код.

- Каждое открытие ссылки создаёт новый счёт, поэтому одну ссылку можно использовать многократно (например, «Членство $99»).

- Каждый платёж виден в разделе «Платежи › Транзакции»; выводите деньги на свой кошелёк в разделе «Средства › Баланс и вывод».

- Если вы создали учётные данные и URL вебхука в разделе «Разработчикам › Интеграция и ключи», платежи по ссылкам тоже приходят уведомлениями в формате, описанном ниже.

- Чтобы прекратить приём, нажмите «Отключить» — ссылка перестанет работать сразу.

### Интеграция по API

#### 1. Учётные данные и подпись

Кабинет продавца → «Разработчикам › Интеграция и ключи» → создайте **merchant** (UUID) и **API key**. Есть один набор для Live и один для Test: Live принимает настоящие деньги, Test работает в тестовых сетях. Добавьте также **домены сайта**: `url_callback`, `url_return` и `url_success` должны находиться на них. API key показывается только один раз — храните его надёжно и только на сервере.

Базовый URL: `https://blockwallets.io`. Каждый эндпоинт — `POST` + JSON со следующими заголовками:

- `merchant`: UUID вашего продавца (он определяет Live или Test)

- `sign`: `md5(base64(тело запроса) + API key)`, где тело — в точности та JSON-строка, которую вы отправляете

Успешный ответ: `{"state": 0, "result": {…}}`; ошибка: `{"state": 1, "message": "…"}` (см. [Ошибки](https://blockwallets.io/docs/cryptomus?lang=ru#errors)).

У основных эндпоинтов ниже есть панель «Попробовать»: введите Test merchant и API key, и страница подпишет запрос в вашем браузере, вызовет эндпоинт и покажет полный запрос и ответ (учётные данные остаются в памяти страницы). Если подпись не совпадает, сравните её по шагам в [проверке подписи](https://blockwallets.io/docs/sign?lang=ru).

```nodejs
import crypto from "node:crypto";

async function call(path, data) {
  const body = JSON.stringify(data);
  const sign = crypto.createHash("md5").update(Buffer.from(body).toString("base64") + process.env.BW_API_KEY).digest("hex");
  const res = await fetch("https://blockwallets.io" + path, {
    method: "POST",
    headers: { merchant: process.env.BW_MERCHANT, sign, "Content-Type": "application/json" },
    body,
  });
  return res.json();
}
```

```php
function bw_call(string $path, array $data): array {
    $body = json_encode($data, JSON_UNESCAPED_UNICODE);
    $sign = md5(base64_encode($body) . getenv('BW_API_KEY'));
    $ch = curl_init('https://blockwallets.io' . $path);
    curl_setopt_array($ch, [
        CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ['merchant: ' . getenv('BW_MERCHANT'), 'sign: ' . $sign, 'Content-Type: application/json'],
    ]);
    return json_decode(curl_exec($ch), true);
}
```

```python
import base64, hashlib, json, os, requests

def bw_call(path: str, data: dict) -> dict:
    body = json.dumps(data, separators=(",", ":"), ensure_ascii=False)
    sign = hashlib.md5((base64.b64encode(body.encode()).decode() + os.environ["BW_API_KEY"]).encode()).hexdigest()
    headers = {"merchant": os.environ["BW_MERCHANT"], "sign": sign, "Content-Type": "application/json"}
    return requests.post("https://blockwallets.io" + path, data=body.encode(), headers=headers).json()
```

#### 2. Создание счёта POST /v1/payment

Когда клиент оформляет заказ или вводит сумму на странице пополнения, вызовите `https://blockwallets.io/v1/payment` и перенаправьте его на возвращённый `result.url`.

```json
{
  "amount": "42.00",
  "currency": "USD",
  "order_id": "order_1042",
  "url_callback": "https://shop.example/webhooks/crypto",
  "url_return": "https://shop.example/cart",
  "url_success": "https://shop.example/thanks?order=1042"
}
```

| Параметр | Обязательный | Описание |
| --- | --- | --- |
| `amount` | Да | Сумма строкой, не более двух знаков после запятой: `"42.00"`. Ваша цена или число, введённое клиентом; не меньше минимума выбранной сети (см. [сети](https://blockwallets.io/docs/cryptomus?lang=ru#networks)) |
| `currency` | Да | `USD`, `USDT` или `USDC`, все 1:1 |
| `order_id` | Да | Номер вашего заказа: буквы, цифры, `-`, `_`, до 100 символов. Повторный вызов с тем же order_id возвращает существующий счёт (дубликатов заказов не будет) |
| `url_callback` | Нет | URL вебхука. Если не указать, вебхук не отправляется |
| `url_return` | Нет | Куда ведёт «Назад» до оплаты |
| `url_success` | Нет | Куда попадает клиент после оплаты |
| `network` | Нет | Заранее выбрать сеть: `tron` / `bsc` / `eth` / `base` / `polygon` / `arbitrum` / `optimism` / `avalanche` / `xlayer` / `btc` / `ltc` / `doge` / `bch` / `sol` / `ton`; если не указать, клиент выберет на странице оплаты |
| `to_currency` | Нет | Монета в этой сети: `USDT` / `USDC`; для `btc` / `ltc` / `doge` / `bch` это `BTC` / `LTC` / `DOGE` / `BCH` (необязательно) |
| `lifetime` | Нет | Срок жизни счёта в секундах, 300 – 43200, по умолчанию 3600; всё, что меньше 600, считается как 600 |
| `accuracy_payment_percent` | Нет | Какая недоплата ещё считается оплатой, 0 – 5, по умолчанию 0. `100` = принять любую пришедшую сумму: `paid` сразу после подтверждения (`paid_over`, если больше), зачисляйте по `payment_amount_usd` из вебхука — удобно для пополнений. Если не указать, действует «Правило суммы» в разделе «Настройки › Правила приёма платежей и ставки» кабинета: «зачислять, сколько пришло» означает 100 |
| `subtract` | Нет | Доля комиссии платформы, которую платит клиент, 0 – 100, добавляется к `payer_amount` (комиссия платформы 1%, при больших оборотах ниже; при 1% и значении 100 счёт на $100 обойдётся клиенту в $101.00; см. [цены](https://blockwallets.io/pricing?lang=ru)). Если не указать, действует настройка «Комиссия и недоплата» в разделе «Настройки › Правила приёма платежей и ставки» кабинета (по умолчанию 0) |
| `is_payment_multiple` | Нет | Можно ли доплатить недостающую сумму, по умолчанию true: статус `wrong_amount_waiting`, доплата на тот же адрес переводит счёт в `paid` (если при первой недоплате до конца оставалось менее 30 минут, срок переносится на 30 минут вперёд). false: первый же недоплаченный перевод переводит счёт в `wrong_amount`. Если не указать, действует настройка в кабинете |
| `additional_data` | Нет | Любая строка (до 255), возвращается как есть в запросах и вебхуках |

```json
{
  "state": 0,
  "result": {
    "uuid": "6f1c2a7e-…",
    "order_id": "order_1042",
    "amount": "42.00",
    "currency": "USD",
    "network": null,
    "address": null,
    "payer_amount": null,
    "payment_amount": null,
    "url": "https://blockwallets.io/pay/inv_01J8…",
    "expired_at": 1760965200,
    "status": "check",
    "is_final": false
  }
}
```

`network`, `address` и `payer_amount` заполняются, когда клиент выбирает сеть.

#### 3. Запрос счетов

- `POST /v1/payment/info` `{"order_id": "…"}` или `{"uuid": "…"}`: получить один счёт, попутно проверив блокчейн (не чаще раза в 10 секунд).

- `POST /v1/payment/list`: список, по 15 на страницу, необязательные `date_from` / `date_to`; следующая страница через возвращённый `paginate.nextCursor` (`?cursor=…`).

- `POST /v1/payment/services`: доступные сети и минимальная сумма для каждой.

- `POST /v1/payment/resend` `{"order_id": "…"}`: повторно отправить вебхук оплаченного или недоплаченного счёта.

Основной канал — вебхуки, запросы служат запасным вариантом (например, если ваш сервер не работал и пропустил вебхук).

#### 4. Статические кошельки POST /v1/wallet

Открывает постоянный адрес для одного клиента в одной сети. Один и тот же `order_id` (обычно id вашего пользователя) + сеть всегда дают один и тот же адрес; все сети EVM (BNB Chain, Ethereum, Base, Polygon, Arbitrum, Optimism, Avalanche, X Layer) используют один адрес, а TRON, BTC, LTC, DOGE, BCH, Solana и TON — каждая свой. Всё, что отправит клиент, зачисляется, на каждый перевод приходит вебхук; переводы BTC / LTC / DOGE / BCH / TRX / BNB / ETH / POL / AVAX / OKB / SOL / TON пересчитываются в доллары США по курсу на момент, когда каждый перевод был замечен (`payment_amount_usd`).

```json
{
  "order_id": "user_42",
  "currency": "USDT",
  "network": "tron",
  "url_callback": "https://shop.example/webhooks/crypto"
}
```

```json
{
  "state": 0,
  "result": {
    "wallet_uuid": "0b9d…",
    "uuid": "5e2f…",
    "order_id": "user_42",
    "currency": "USDT",
    "network": "tron",
    "address": "TXy4…8kQ2",
    "url": "https://blockwallets.io/deposit/dac_01J8…"
  }
}
```

`result.url` — размещённая у нас страница пополнения (адрес + QR-код + последние поступления), которую можно дать клиенту. Переводы ниже минимума сети (обычно $1, BTC $5) автоматически не зачисляются; чтобы их зачислили, свяжитесь с нами. Блокировка адресов (`/v1/wallet/block-address`) пока не поддерживается.

### Вебхуки

Когда меняется статус счёта (`paid`, `paid_over`, `wrong_amount_waiting`, `wrong_amount`, `cancel`) и при каждом переводе на статический кошелёк, мы отправляем POST с JSON на `url_callback`. Ответ 2xx считается доставкой; иначе повторяем через 1 минуту, 5 минут, 30 минут, 2 часа, 12 часов, 24 часа и ещё 24 часа. Можно также отправить повторно из кабинета или через `/v1/payment/resend`.

```json
{
  "type": "payment",
  "uuid": "6f1c2a7e-…",
  "order_id": "order_1042",
  "amount": "42.00",
  "payment_amount": "42",
  "payment_amount_usd": "42.00",
  "merchant_amount": "41.58",
  "commission": "0.42",
  "is_final": true,
  "status": "paid",
  "from": "TQ8m…",
  "wallet_address_uuid": null,
  "network": "tron",
  "currency": "USD",
  "payer_currency": "USDT",
  "payer_amount": "42",
  "payer_amount_exchange_rate": "1",
  "additional_data": null,
  "txid": "9c1e…",
  "sign": "5f0c9b…"
}
```

| type | Когда | Зачисление |
| --- | --- | --- |
| `payment` | Изменился статус счёта — см. `status` | Зачисляйте `payment_amount_usd` при `paid` / `paid_over`; убирайте дубликаты по `uuid` |
| `wallet` | На статический кошелёк пришёл перевод (`status` всегда `paid`; `order_id` — тот, с которым вы открыли кошелёк) | Зачисляйте `payment_amount_usd`; у каждого перевода свой `uuid` — убирайте дубликаты по нему |

#### Проверка подписи (обязательна)

Подпись — это поле `sign` тела вебхука: удалите `sign`, закодируйте остальное так же, как PHP `json_encode` (компактно, `/` экранируется как `\/`, не-ASCII символы не экранируются), и `md5(base64(закодированное) + API key)` должно совпасть с `sign`. Используйте API key того же режима. Один и тот же вебхук может прийти более одного раза — убирайте дубликаты по `uuid` + `status`.

Если проверка не проходит, вставьте исходное тело вебхука в [проверку подписи](https://blockwallets.io/docs/sign?lang=ru): она показывает результат каждого шага и отмечает, где ваш результат отличается (всё выполняется в вашем браузере; API key никуда не отправляется). Любой вебхук из раздела «Разработчикам › Журнал вебхуков» в кабинете открывается в проверке одним щелчком.

```nodejs
import crypto from "node:crypto";

function verify(rawBody, apiKey) {
  const { sign, ...data } = JSON.parse(rawBody);
  const json = JSON.stringify(data).replaceAll("/", "\\/");
  const expected = crypto.createHash("md5").update(Buffer.from(json).toString("base64") + apiKey).digest("hex");
  return typeof sign === "string" && sign.length === expected.length && crypto.timingSafeEqual(Buffer.from(sign), Buffer.from(expected));
}
```

```php
$data = json_decode(file_get_contents('php://input'), true);
$sign = $data['sign'] ?? '';
unset($data['sign']);
$expected = md5(base64_encode(json_encode($data, JSON_UNESCAPED_UNICODE)) . $apiKey);
if (!hash_equals($expected, $sign)) {
    http_response_code(401); exit;
}
```

```python
import base64, hashlib, hmac, json

def verify(raw_body: bytes, api_key: str) -> bool:
    data = json.loads(raw_body)
    sign = data.pop("sign", "")
    encoded = json.dumps(data, separators=(",", ":"), ensure_ascii=False).replace("/", "\\/")
    expected = hashlib.md5((base64.b64encode(encoded.encode()).decode() + api_key).encode()).hexdigest()
    return hmac.compare_digest(expected, sign)
```

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

Счета, созданные с Test merchant и API key, работают в тестовых сетях без настоящих денег. На странице оплаты есть кнопка «Симулировать оплату» (полная / половина / переплата), так что вы увидите смену статусов и вебхуки, не добывая тестовые монеты.

- `POST /v1/test-webhook/payment`, `/v1/test-webhook/wallet`: отправляют подписанный пример вебхука на `url_callback` (передайте обязательный `url_callback` на одном из ваших зарегистрированных доменов, а также `currency`, `network`, при желании `status`, `order_id`), чтобы отладить код проверки.

- Кабинет «Разработчикам › Интеграция и ключи» → «Отправить тестовое уведомление»: отправляет пример на ваш URL вебхука.

- Кабинет «Разработчикам › Журнал вебхуков»: каждая попытка доставки с временем, целевым URL, HTTP-статусом, длительностью, телом запроса и ответом вашего сервера (первые 4 КБ); фильтр по заказу или статусу и повторная отправка одним щелчком. Хранится 30 дней.

### Переход с Cryptomus

- Кабинет «Разработчикам › Интеграция и ключи» → создайте merchant и API key.

- Замените в коде `https://api.cryptomus.com` на `https://blockwallets.io` и используйте новые merchant и API key.

- Добавьте свои домены в разделе «Домены сайта» (`url_callback` / `url_return` / `url_success` принимают только их).

Поддерживаются: `/v1/payment`, `/v1/payment/info`, `/v1/payment/list`, `/v1/payment/services`, `/v1/payment/resend`, `/v1/wallet`, `/v1/test-webhook/payment`, `/v1/test-webhook/wallet`. Отличия: счета выставляются только в USD / USDT / USDC (все 1:1, без курсового спреда); `commission` — наша комиссия платформы (полученная сумма × ставка продавца на момент создания счёта — стандартная 1%, по обороту вплоть до 0.5%; с доли, которую покрывает клиент, ничего не берётся дважды), а `merchant_amount` = получено − `commission`; когда клиент платит в BTC / LTC / DOGE / BCH / TRX / BNB / ETH / POL / AVAX / OKB / SOL / TON, мы берём медиану нескольких бирж, зафиксированную на 30 минут — `payer_amount` это количество монет к отправке, `payer_amount_exchange_rate` — стоимость одной монеты в долларах США, а платёж пересчитывается в `payment_amount_usd` по зафиксированному курсу (монеты остаются у нас, ничего не обменивается); сети `tron` / `bsc` / `eth` / `base` / `polygon` / `arbitrum` / `optimism` / `avalanche` / `xlayer` / `btc` / `ltc` / `doge` / `bch` / `sol` / `ton`; минимальный срок жизни счёта 10 минут; нет `is_refresh` и блокировки статических кошельков; по умолчанию вебхуки приходят с меняющихся IP; если вы используете список разрешённых IP, включите в кабинете «Вебхуки с фиксированного IP» в разделе «Разработчикам › Интеграция и ключи», и вебхуки будут приходить только с `18.163.145.41` — список разрешённых адресов лишь дополнительный слой, продолжайте проверять `sign`.

Переходите с **NOWPayments** или **Coinbase Commerce**? У нас есть совместимые API для обоих — смените базовый URL и ключи; см. [руководство по переходу](https://blockwallets.io/docs/migrate?lang=ru).

### Сети и суммы

| Монета | Сеть | Параметр network | Минимум | Поступление |
| --- | --- | --- | --- | --- |
| USDT | TRON | `tron` | $1 | ~1 мин |
| USDT | BNB Chain | `bsc` | $1 | ~1 мин |
| USDC | BNB Chain | `bsc` | $1 | ~1 мин |
| USDT | Ethereum | `eth` | $5 | ~1 мин |
| USDC | Ethereum | `eth` | $5 | ~1 мин |
| USDC | Base | `base` | $1 | ~1 мин |
| USDT | Polygon | `polygon` | $1 | ~1 мин |
| USDC | Polygon | `polygon` | $1 | ~1 мин |
| USDT | Arbitrum | `arbitrum` | $1 | ~1 мин |
| USDC | Arbitrum | `arbitrum` | $1 | ~1 мин |
| USDT | Optimism | `optimism` | $1 | ~1 мин |
| USDC | Optimism | `optimism` | $1 | ~1 мин |
| USDT | Avalanche | `avalanche` | $1 | ~1 мин |
| USDC | Avalanche | `avalanche` | $1 | ~1 мин |
| USDT | X Layer | `xlayer` | $1 | ~1 мин |
| USDC | X Layer | `xlayer` | $1 | ~1 мин |
| USD1 | BNB Chain | `bsc` | $1 | ~1 мин |
| FDUSD | BNB Chain | `bsc` | $1 | ~1 мин |
| DAI | Ethereum | `eth` | $5 | ~1 мин |
| DAI | Arbitrum | `arbitrum` | $1 | ~1 мин |
| DAI | Base | `base` | $1 | ~1 мин |
| BTC | Bitcoin | `btc` | $5 | ~10 мин |
| LTC | Litecoin | `ltc` | $1 | ~3 мин |
| DOGE | Dogecoin | `doge` | $1 | ~1 мин |
| BCH | Bitcoin Cash | `bch` | $1 | ~10 мин |
| TRX | TRON | `tron` | $1 | ~1 мин |
| BNB | BNB Chain | `bsc` | $1 | ~1 мин |
| ETH | Ethereum | `eth` | $5 | ~1 мин |
| ETH | Base | `base` | $1 | ~1 мин |
| ETH | Arbitrum | `arbitrum` | $1 | ~1 мин |
| ETH | Optimism | `optimism` | $1 | ~1 мин |
| POL | Polygon | `polygon` | $1 | ~1 мин |
| AVAX | Avalanche | `avalanche` | $1 | ~1 мин |
| OKB | X Layer | `xlayer` | $1 | ~1 мин |
| USDT | Solana | `sol` | $1 | ~1 мин |
| USDC | Solana | `sol` | $1 | ~1 мин |
| SOL | Solana | `sol` | $1 | ~1 мин |
| USDT | TON | `ton` | $1 | ~1 мин |
| TON | TON | `ton` | $1 | ~1 мин |

Комиссии ERC-20 высоки, поэтому минимум $5; комиссии Bitcoin тоже немалые, минимум $5; во всех остальных сетях $1. Клиенты должны отправлять в той сети, которая указана на странице оплаты — деньги, отправленные в другой сети, автоматически не зачисляются. BTC / LTC / DOGE / BCH отображаются как «обнаружен» сразу, как попадают в мемпул, и засчитываются, когда наберут достаточно подтверждений; заменённые (RBF) или отброшенные транзакции не засчитываются. Нативные монеты (TRX, BNB, ETH, POL, AVAX, OKB, SOL, TON) котируются по зафиксированному курсу и зачисляются в долларах США, как BTC / LTC / DOGE / BCH; указывайте и сеть, и монету: для счетов `network: "bsc", to_currency: "BNB"`, для статических кошельков `network: "bsc", currency: "BNB"`. Одна сеть без монеты по умолчанию означает USDT в этой сети (USDC в Base). Переводы, сделанные контрактами (мультиподпись, пакетные выплаты), тоже принимаются; в некоторых сетях хеш их транзакции недоступен, и `txid` в вебхуке равен `null`.

### Ошибки

```json
{ "state": 1, "message": "amount must be a number like 10.28" }
```

| HTTP | Частые причины |
| --- | --- |
| 422 | Отсутствуют или некорректны параметры; сумма ниже минимума сети; URL вебхука или перенаправления не входит в зарегистрированные домены; неподдерживаемая монета или сеть в `/v1/payment` |
| 401 | Неверный merchant, неверный `sign` (`Invalid Sign.`) или API key был заменён |
| 404 | Счёта не существует или он не ваш (`Payment not found`); в `/v1/wallet` — неподдерживаемое сочетание монеты и сети (`The service was not found`) |
| 503 | Сеть временно недоступна — выберите другую или не задавайте сеть заранее |

Если подпись неверна (`Invalid Sign.`), в ответе есть объект `debug`: `body_base64` — base64 тела запроса, которое мы получили (ваше собственное содержимое, но никогда не API key), а `body_bytes` — его длина. Сравните с base64, которое вы подписывали: если они различаются, отправленное вами тело не совпадает с подписанной строкой (ваш фреймворк сериализовал его заново, прокси изменил кодировку, добавился завершающий перевод строки); если совпадают, неверен API key. Вставьте его в [проверку подписи](https://blockwallets.io/docs/sign?lang=ru), чтобы увидеть первое отличие.

```json
{
  "state": 1,
  "message": "Invalid Sign.",
  "debug": {
    "body_base64": "eyJhbW91bnQiOiI0Mi4wMCIsImN1cnJlbmN5IjoiVVNEIiwi…",
    "body_bytes": 158,
    "sign_formula": "md5(body_base64 + API key)"
  }
}
```

### Вопросы

#### Клиенты пополняют на любую сумму — какой способ выбрать?

Счета. Пусть клиент вводит сумму на вашей странице пополнения, создайте на неё счёт и зачислите `payment_amount_usd`, когда платёж придёт. Статические кошельки нужны, только если клиенты должны сохранить один адрес и многократно отправлять на него.

#### Что, если клиент заплатил меньше?

До истечения срока клиент может отправить разницу на странице оплаты (она показывает, сколько ещё нужно; статус `wrong_amount_waiting`, а если при первой недоплате до конца оставалось менее 30 минут, срок переносится на 30 минут вперёд). Если к истечению всё ещё не хватает, счёт получает статус `wrong_amount`, а `payment_amount_usd` в вебхуке — полученная сумма; сервисы с пополнением могут просто зачислить её.

#### Что, если клиент заплатил поздно или дважды?

Деньги, пришедшие после истечения срока, всё равно зачисляются и приходят уведомлением; деньги, пришедшие после полной оплаты счёта, тоже фиксируются и видны в кабинете.

#### Что, если клиент отправил в неверной сети?

Например, счёт в TRON, а он отправил из BNB Chain: платёж автоматически не зачисляется — напишите нам, и мы разберём его вручную.

#### Сколько это стоит?

1% с каждого полученного платежа, ставка автоматически снижается по обороту прошлого месяца (0.9% от $50,000, 0.8% от $100,000, 0.7% от $250,000, 0.6% от $500,000 и 0.5% от $1,000,000), без абонентской платы и платы за подключение. Комиссию сети клиент платит при отправке; чтобы переложить её на клиента, задайте `subtract` при создании счёта или значение по умолчанию в кабинете. За вывод дополнительная комиссия не взимается. См. [цены](https://blockwallets.io/pricing?lang=ru).

#### Когда деньги попадут ко мне?

Они зачисляются на ваш баланс сразу после подтверждения платежа. Запросите вывод на свой кошелёк в разделе «Средства › Баланс и вывод»; после нашего одобрения мы выплачиваем, и транзакция в блокчейне появляется в истории выводов.

Можно также включить автовывод: когда доступный баланс достигает заданной вами суммы или раз в сутки в 00:00 UTC выводится весь доступный баланс. Автоматические выводы проверяются так же, и каждое изменение настроек отправляет уведомление на вашу почту.
