<!-- Source: https://docs.infraio.xyz/ru/api-reference -->
<!-- Last updated: 2026-10-04 -->

# Справочник API

Каждый endpoint ниже говорит на JSON, живёт под `https://api.infraio.xyz`
(prod) или `https://api-dev.infraio.xyz` (test) и аутентифицируется через
HMAC-SHA256 — см. [Аутентификация](https://docs.infraio.xyz/ru/api-reference/authentication)
для подписания запросов и [Ошибки](https://docs.infraio.xyz/ru/api-reference/errors) для формы
конверта ошибки.

Эта страница перечисляет endpoint'ы для интеграций мерчантов. Если у
endpoint'а нет собственной страницы, он описан на связанной странице
концепции.

> **Note:**
>
> Endpoint'ы под **`/b2b/v1/*`** подписываются HMAC вашим **secret**-ключом
> (`sk_…`). Это уровень, который вызывает ваш backend. Панель мерчанта и
> размещённый checkout используют собственные endpoint'ы, которые не входят
> в интеграционный API.

## Checkout

| Метод | Путь | Назначение | Заметки |
| --- | --- | --- | --- |
| `POST` | `/b2b/v1/checkout-sessions/quick` | Создание сессии одним вызовом — заказ + checkout-session создаются вместе. | См. [Быстрый старт](https://docs.infraio.xyz/ru/get-started/quickstart#2-create-a-checkout-session-server) для тела запроса и примера. |
| `POST` | `/b2b/v1/checkout-sessions` | Создание сессии под *существующий* заказ. Используйте, когда у вашей платформы уже своя модель заказа и вы хотите одну сессию на попытку. | Двухшаговый поток. |
| `GET` | `/b2b/v1/checkout-sessions/by-order/{order_id}` | Список всех сессий, когда-либо созданных для заказа. | Полезно, когда покупатель забросил сессию и вы хотите показать предыдущие попытки в своей панели. |

## Заказы

Заказы — это вневременная биллинговая сущность. Один заказ может стоять
за несколькими сессиями checkout (например, покупатель забросил и
повторил попытку).

| Метод | Путь | Назначение | Заметки |
| --- | --- | --- | --- |
| `POST` | `/b2b/v1/orders` | Создание заказа без сессии. | Используйте, когда хотите потом отправить покупателю платёжную ссылку, а не редиректить его сразу. |
| `GET` | `/b2b/v1/orders/{id}` | Чтение одного заказа с позициями и статусом. | Статус: `PENDING` → `PAID` \| `PARTIAL_PAID` \| `CANCELED`. После возврата: `PARTIALLY_REFUNDED` \| `REFUNDED`. |
| `GET` | `/b2b/v1/orders/by-merchant/{merchant_id}` | Список ваших заказов, курсорная пагинация. | См. [Курсорная пагинация](#cursor-pagination) для протокола курсора. |
| `PATCH` | `/b2b/v1/orders/{id}/cancel` | Отметить неоплаченный заказ отменённым. Отправляет `order.canceled`. | Не сработает, если заказ уже оплачен. |
| `PATCH` | `/b2b/v1/orders/{id}/reopen` | Откатить авто-отмену (`canceled_reason=payment_timeout`). | Полезно, если покупатель вернулся после истечения TTL. |

## Возвраты

См. [Страницу концепции «Возвраты»](https://docs.infraio.xyz/ru/concepts/refunds) для потока
saga и жизненного цикла токена.

### Инициированные мерчантом

| Метод | Путь | Назначение | Заметки |
| --- | --- | --- | --- |
| `POST` | `/b2b/v1/merchants/{merchant_id}/refunds` | Возврат, инициированный мерчантом. Автоматически одобряется (пропускает `PENDING`). | Отправляет `payment.refund.approved` сразу. |

### Инициированные клиентом — refund-request токены

Покупатель заполняет форму возврата на нашей размещённой странице; вы
только генерируете токен и доставляете URL. Токены можно выпускать из
вашего backend'а (ниже) или из панели мерчанта. Обновления и отмены
обрабатываются в панели.

| Метод | Путь | Аутентификация | Назначение |
| --- | --- | --- | --- |
| `POST` | `/b2b/v1/merchants/{merchant_id}/refund-requests` | HMAC (`sk_…`) | Выпуск токена из вашего backend'а. Тело: `{ref_type, ref_value, amount, ttl_seconds?, metadata?, hide_summary?, hide_header?}`. `ref_type` — одно из `order_id` / `order_number` / `session_id` / `session_key`; `ref_value` — соответствующий идентификатор. `amount` **обязателен** и фиксирует максимум, который покупатель может ввести. По умолчанию TTL **30 мин**. Отправляет `refund_request.created` (`source: b2b`). |

### Жизненный цикл возврата (после создания)

Применимо к обоим потокам. Endpoint'ы ниже работают с самим возвратом
(id начинается с `rfn_…`), а не с request-токеном.

| Метод | Путь | Назначение | Заметки |
| --- | --- | --- | --- |
| `GET` | `/b2b/v1/refunds/{id}` | Чтение одного возврата. | Статус: `PENDING` → `APPROVED` → `EXECUTED` \| `REJECTED`. |
| `GET` | `/b2b/v1/refunds/by-merchant/{merchant_id}` | Список ваших возвратов, курсорная пагинация. | — |
| `POST` | `/b2b/v1/refunds/{id}/approve` | Одобрить `PENDING` возврат (только для инициированных клиентом — инициированные мерчантом уже в `APPROVED`). | Крипто: переходит в `APPROVED`, далее вызывайте `/submit-tx`. |
| `POST` | `/b2b/v1/refunds/{id}/reject` | Отклонить `PENDING` возврат. | Отправляет `payment.refund.rejected`. |
| `POST` | `/b2b/v1/refunds/{id}/submit-tx` | Только крипто — отметить on-chain tx hash, который вы транслировали. | Тело: `{tx_hash, network, token_address}` — все три обязательны. |

## Каталог (только чтение)

| Метод | Путь | Назначение |
| --- | --- | --- |
| `GET` | `/v1/supported/networks` | Все сети, на которых InfraIO Pay может проводить расчёт (mainnet + testnet, фильтр по окружению). |
| `GET` | `/v1/supported/tokens` | Все стейблкоины на этих сетях. |
| `GET` | `/v1/supported/currencies` | Валюты, принимаемые для `order.currency`. |

## Health

| Метод | Путь | Аутентификация | Назначение |
| --- | --- | --- | --- |
| `GET` | `/health` | Нет (публичный) | Проверка доступности. Возвращает `{"status":"ok"}`. Направьте ваши uptime-мониторы сюда. |

## Курсорная пагинация

Каждый list-endpoint принимает одинаковые query-параметры и возвращает
одинаковый конверт. Курсоры непрозрачны и используются вместо offset'ов,
чтобы страница не смещалась, когда при постраничном чтении появляется
новая строка.

| Query-параметр | Тип | По умолчанию | Заметки |
| --- | --- | --- | --- |
| `cursor` | `string` | — | Непрозрачный — скопируйте `next_cursor` из предыдущего ответа дословно. |
| `limit` | `int` | `20` | `1..100`. |
| `sort_dir` | `'asc' \| 'desc'` | `desc` | Сортировка по `(created_at, id)`. |
| `from` / `to` | `RFC3339` | — | Опциональный фильтр по временному окну. |
| `search` | `string` | — | Свободный текстовый фильтр там, где поддерживается. |

Конверт ответа:

```json
{
  "orders": [ /* строки страницы */ ],
  "next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0wNS0...",
  "has_next": true
}
```

`has_next` присутствует всегда. `next_cursor` опускается, когда
`has_next` равен `false`. Относитесь к курсору как к непрозрачной строке.

## Чего нет на этой странице

Эта страница охватывает endpoint'ы, предназначенные для интеграций
мерчантов. Если вам нужен endpoint, которого здесь нет, или спецификация
OpenAPI, обратитесь в поддержку.
