# Приём платежей без догадок

Единое руководство по Merchant API: от первого инвойса до сверки выплат. Начните с готовой страницы оплаты, затем подключите уведомления и автоматизацию на своём сервере.

## Первый платёж

1. Создайте проект в [кабинете](/cabinet). Если проект ожидает активации, завершите её до интеграции.
2. В разделе «Интеграции» получите `project_id`, ключ API и секрет API. Храните секреты на сервере.
3. Создайте инвойс запросом ниже. Сохраните `invoice_id` и связь с вашим `order_id`.
4. Перенаправьте покупателя на `invoice_url` из ответа. Страница Bitcofy предложит доступные сети и активы.
5. Примите подписанное уведомление или проверьте инвойс через API. Выдавайте товар по подтверждённому результату, а не по возврату покупателя на ваш сайт.

```bash
curl --request POST 'https://pay.bitcofy.pro/api/v1/invoices' \
  --header "X-API-Key: $BITCOFY_API_KEY" \
  --header "X-API-Secret: $BITCOFY_API_SECRET" \
  --header 'Content-Type: application/json' \
  --data '{
    "project_id": "YOUR_PROJECT_ID",
    "order_id": "order-1001",
    "amount": "49.90",
    "currency": "USD",
    "buy_type": "package",
    "success_url": "https://merchant.example/order/success",
    "cancel_url": "https://merchant.example/order/cancel"
  }'
```

`amount` — стоимость в `USD` или `RUB`, а не количество USDT. Покупатель отправляет криптовалюту в сумме выбранной платёжной опции. Не рассчитывайте её самостоятельно из рекламного курса: используйте `amount_crypto`, комиссию и срок фиксации из API.

Повтор создания с тем же `project_id` и `order_id` возвращает существующий инвойс. Новые поля такого повтора не обновляют старый инвойс. Для нового заказа нужен новый `order_id`.

## Доступ и секреты

Базовый адрес: `https://pay.bitcofy.pro`. Пути справочника уже содержат `/api/v1`: не добавляйте его второй раз.

| Операция | Что передать | Назначение |
| --- | --- | --- |
| Публичная информация | Без ключа | Сети, курсы и возможности интеграции |
| Чтение данных проекта | `X-API-Key` или `Authorization: Bearer <project_api_key>` | Доступ только к своему проекту |
| Изменение данных проекта | Ключ API и `X-API-Secret` | Создание инвойсов, настройки, выплаты |
| Подписанная выплата или решение по заявке | Доступ на запись и `signature`, `nonce`, `timestamp` | Дополнительная подпись Ed25519 |
| Вход в кабинет | Сессия пользователя | Не является ключом Merchant API |

Ключ API имеет префикс `bpk_`, секрет API — `bps_`, секрет подписи webhook — `bwhsec_live_`. Это разные значения. Приватный ключ Ed25519 остаётся у вас; в API регистрируется публичный ключ в Base64.

Заголовки HTTP не зависят от регистра. Названия полей JSON, сетей и активов используйте в точности как в ответах API. `X-API-Secret` не заменяет ключ API. Для POST/PUT с JSON передавайте `Content-Type: application/json`.

## Жизненный цикл инвойса

Состояние инвойса, подтверждения перевода и доступный для вывода баланс — разные сущности. Отслеживайте их отдельно.

| Статус | Что означает | Как поступить |
| --- | --- | --- |
| `created` | Инвойс создан, платёжное окно ещё не запущено | Показать ссылку на оплату |
| `waiting_payment` | Выбрана платёжная опция и запущено окно оплаты | Ожидать перевод до срока сессии |
| `pending` | Обнаружен перевод, обработка не завершена | Дождаться подтверждений и окончательного решения |
| `paid` | Оплата принята | Обработать заказ один раз |
| `paid_over` | Принята оплата с переплатой | Учесть фактически зачисленную сумму |
| `partially_paid`, `wrong_amount`, `additional_payment` | Требуется обработка неполной или отличающейся суммы | Сверить платежи и разрешение инвойса; не считать полной оплатой автоматически |
| `late_payment` | Зафиксирована поздняя оплата | Проверить платежи и результат зачисления по своей политике заказа |
| `expired`, `cancel` | Окно истекло или инвойс отменён | Не выдавать заказ только на основании перехода по ссылке |

Ориентируйтесь на `required_confirmations` в выбранной опции и `confirmations`/`credited` в платежах. Число подтверждений зависит от сети и конфигурации; не фиксируйте одно значение для всех сетей. Сам факт появления транзакции или её хеша не означает зачисление.

Состояние `created` не следует трактовать как запущенный таймер оплаты: срок платёжной сессии начинается после выбора сети и актива. При активной сессии маршрут и курс фиксируются на её срок. Проверяйте поля сессии и текущий ответ API.

## Готовая страница оплаты и доступные активы

Рекомендуемый путь — открыть `invoice_url`. Публичные методы `by-hash` обслуживают готовую страницу оплаты; это отдельный сценарий, а не замена защищённому Merchant API.

Для `POST …/payment-session` сначала откройте готовую страницу инвойса в том же браузере: сервер проверяет cookie доступа и ограничивает частоту запросов. Одного `invoice_hash` для запуска сессии недостаточно. Ответ `403` с просьбой открыть страницу означает отсутствие действующего доступа.

Список сетей `/api/v1/public/networks` описывает возможности платформы. Для конкретного инвойса используйте его `payment_options`: доступность зависит от настроек проекта и администратора и может измениться. Не предлагайте покупателю отключённую опцию из закешированного списка.

Адрес и сумма берутся из одной выбранной пары `network` + `asset`. Совпадающий символ токена в разных сетях не означает взаимозаменяемость. `success_url` и `cancel_url` управляют переходом браузера, а не подтверждают оплату.

## Уведомления об операциях

Настройте HTTPS-адрес в кабинете или через `POST /api/v1/projects/{project_id}/webhook/config`. Отправьте тест через `POST …/webhook/test`. Состояние доставок доступно в `GET …/webhook/events`.

Сервер присылает JSON и заголовки `X-Bitcofy-Event-Id`, `X-Bitcofy-Event-Type`, `X-Bitcofy-Timestamp`, `X-Bitcofy-Signature`, `X-Bitcofy-Retry-Count`. Подпись — HMAC-SHA256 в hex, ключ — секрет webhook, сообщение — точная строка timestamp, точка и исходные байты тела. Не разбирайте и не сериализуйте JSON заново до проверки.

```javascript
import { createHmac, timingSafeEqual } from 'node:crypto';

// rawBody: Buffer с исходным телом HTTP-запроса, до JSON.parse.
export function verifyWebhook(rawBody, timestamp, signature, secret) {
  if (!Buffer.isBuffer(rawBody) || typeof timestamp !== 'string' ||
      typeof signature !== 'string' || !/^[a-f0-9]{64}$/i.test(signature)) return false;
  const expected = createHmac('sha256', secret)
    .update(timestamp + '.', 'utf8').update(rawBody).digest();
  return timingSafeEqual(expected, Buffer.from(signature, 'hex'));
}
```

1. Проверьте подпись, допустимую давность timestamp и принадлежность события вашему проекту. Окно давности задайте в своей интеграции с учётом часов серверов.
2. Сохраните событие и дедуплицируйте по `event_id` атомарно с изменением заказа. Повторная доставка не должна повторно зачислять деньги или выдавать товар.
3. Ответьте любым `2xx` после надёжного сохранения. Длительную обработку выполняйте в очереди.
4. Если события пришли не по порядку или состояние неоднозначно, запросите актуальный инвойс либо выплату через API.

На попытку доставки отводится 5 секунд. При ошибке выполняется до 10 попыток всего: интервалы 15, 30, 60, 120, 240 секунд, далее не более 300 секунд между попытками; фактический запуск зависит от очереди. После исчерпания попыток событие помечается недоставленным окончательно. Не полагайтесь на уведомления как на единственный способ сверки.

Основные события: `invoice.created`, `invoice.status_changed`, `payout.created`, `payout.processing`, `payout.status_changed`, `payout.rejected`, `webhook.test`. Для выплат возможны дополнительные события переходов; используйте `event_type` и текущий объект, а не порядок доставки.

## Выплаты и заявки

Выберите подходящий сценарий: прямая подписанная выплата через `POST /api/v1/payouts` или заявка `POST /api/v1/projects/{project_id}/payout-requests` с отдельным подтверждением/отклонением.

До отправки проверьте `/balances`, сеть, актив и адрес. Общий учётный баланс и `available_for_withdrawal` могут различаться: часть средств ещё ожидает сбора. Значения комиссии и доступности берите из ответов API, а не задавайте константами.

Для прямой выплаты `amount` включает комиссию: сумма получателю определяется после её вычета. Сверяйте `gross_amount`, `fee_amount` и `net_amount` в результате. Нельзя считать HTTP `200` доказательством завершённой отправки в сеть: выплата обрабатывается асинхронно.

| Состояние | Значение |
| --- | --- |
| `requested` | Заявка ожидает решения |
| `approved`, `rejected` | Решение по заявке; подтверждение ещё не означает завершение выплаты |
| `pending` / `provider_status=processing` | Выплата обрабатывается |
| `success` / `provider_status=completed` | Успешное завершение |
| `send_error` / `provider_status=failed` | Ошибка отправки; сверить актуальный результат и возврат резерва |

Сохраняйте `request_id`, `payout_id`, `idempotency_key`, `tx_hash` и итоговые флаги ответа. Для единой сверки используйте `GET …/payouts/reconcile`, передав ровно один из `request_id`, `payout_id` или `idempotency_key`.

## Подпись Ed25519

Создайте пару ключей на своём сервере и зарегистрируйте публичный ключ через `POST …/security/payout-key`. Подпись кодируется в Base64. Ключ и секрет API всё равно обязательны.

Сообщение прямой выплаты — UTF-8, поля соединяются `\n`, без перевода строки в конце:

```text
bitcofy-payout-v1
{project_id}
{network}
{asset}
{amount}
{destination_address}
{idempotency_key}
{nonce}
{timestamp_utc}
```

Для подтверждения или отклонения заявки используется другое сообщение. В строке `action` передайте `approve` или `reject`. При подтверждении строка причины остаётся пустой:

```text
bitcofy-payout-approval-v1
{project_id}
{request_id}
{action}
{rejection_reason_or_empty}
{nonce}
{timestamp_utc}
```

`timestamp` должен отличаться от текущего времени сервера не более чем на 5 минут. Сервер нормализует его в UTC через Python `isoformat()`: например, `2026-09-29T12:00:00+00:00`. Чтобы избежать различий `Z`/`+00:00` и дробных секунд, отправляйте и подписывайте UTC-время без долей секунды с суффиксом `+00:00`. Для каждого нового подписанного действия генерируйте уникальный `nonce`.

Передавайте денежное `amount` строкой десятичного числа без экспоненты и подписывайте ту же строку. Не используйте числа с плавающей точкой. Пример сообщения, возвращённый сервером, показывает формат, но не заменяет сообщение вашей конкретной операции.

Примеры ниже подписывают уже собранное каноническое сообщение. `private_key` генератора API — 32-байтовый seed в Base64. Это не 64-байтовый расширенный ключ TweetNaCl/Go: преобразуйте seed, как показано ниже.

### Node.js

```javascript
import { createPrivateKey, sign } from 'node:crypto';

// message: canonical UTF-8 message shown above, no trailing newline.
export function signMessage(seedBase64, message) {
  const seed = Buffer.from(seedBase64, 'base64');
  if (seed.length !== 32) throw new Error('Expected a 32-byte Ed25519 seed');
  const pkcs8 = Buffer.concat([
    Buffer.from('302e020100300506032b657004220420', 'hex'), seed
  ]);
  const key = createPrivateKey({ key: pkcs8, format: 'der', type: 'pkcs8' });
  return sign(null, Buffer.from(message, 'utf8'), key).toString('base64');
}
```

### Python

```python
# Dependency: cryptography
import base64
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey

def sign_message(seed_base64: str, message: str) -> str:
    seed = base64.b64decode(seed_base64, validate=True)
    key = Ed25519PrivateKey.from_private_bytes(seed)  # 32-byte seed
    return base64.b64encode(key.sign(message.encode('utf-8'))).decode('ascii')
```

### Go

```go
package payouts

import (
    "crypto/ed25519"
    "encoding/base64"
    "fmt"
)

func SignMessage(seedBase64 string, message string) (string, error) {
    seed, err := base64.StdEncoding.DecodeString(seedBase64)
    if err != nil || len(seed) != ed25519.SeedSize {
        return "", fmt.Errorf("expected a Base64 32-byte Ed25519 seed")
    }
    key := ed25519.NewKeyFromSeed(seed)
    signature := ed25519.Sign(key, []byte(message))
    return base64.StdEncoding.EncodeToString(signature), nil
}
```

## Повторы, таймауты и сверка

| Ситуация | Правильное действие |
| --- | --- |
| Таймаут создания инвойса | Найти по `order_id` или повторить создание с тем же `order_id` |
| Таймаут выплаты | Сначала запросить результат по тому же `idempotency_key` либо через reconcile |
| Выплата найдена | Продолжать наблюдать её состояние; не создавать новую |
| Новая подписанная попытка после сверки | Сохранить ключ логической операции, обновить timestamp и nonce, заново подписать |
| `400`, `401`, `403`, `422` | Исправить параметры, доступ или подпись; слепой повтор не поможет |
| `409` при выплате | Разобрать структурированную причину, доступный баланс и резерв |
| `429` или временная недоступность | Увеличивать задержку с разбросом; учитывать `Retry-After`, если он присутствует |

Не меняйте `idempotency_key` только потому, что ответ потерялся: это может создать вторую выплату. Для проверки состояния используйте чтение и webhook, а не частые повторные POST. При сетевой ошибке результат записи может быть неизвестен.

## Перед запуском

1. Проверьте привязку ключа к проекту, активацию проекта и доступные активы.
2. Пройдите успешную оплату, неполную сумму, истечение срока и позднюю оплату.
3. Проверьте подпись webhook на исходном теле, повтор события и неупорядоченную доставку.
4. Убедитесь, что возврат браузера не выдаёт заказ без подтверждения API.
5. Проверьте потерянный ответ создания, восстановление по идентификатору и защиту от повторной выплаты.
6. Для выплат проверьте комиссию, доступный баланс, Ed25519, timestamp и nonce.
7. Логируйте идентификаторы и ответы об ошибках, но не ключи API, секреты и приватные ключи.

## Документация для агентов

Достаточно передать агенту [эту страницу](https://pay.bitcofy.pro/docs): руководство и справочник уже присутствуют в HTML и не требуют JavaScript или входа.

- [Markdown на русском](/docs.md) — руководство, параметры, ответы и ошибки всех публичных методов.
- [English Markdown](/docs/en.md) — тот же контракт на английском.
- [llms.txt](/llms.txt) — короткий индекс материалов.
- [llms-full.txt](/llms-full.txt) — полная английская документация одним текстовым файлом.
- [OpenAPI JSON](/openapi.json) — актуальная публичная схема приложения.

Начните с сценария интеграции, затем уточните поля и ответы конкретного метода. Примеры с `YOUR_PROJECT_ID` и демонстрационными значениями нужно заменить; они не являются рабочими реквизитами. Сети, комиссии и требуемые подтверждения получайте из API.

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

## GET /api/v1/health

Доступность сервиса

Доступ: Без ключа API



### Параметры



Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/health'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `app` | `string` | Обязательно | App |

```json
{
  "status": "ok",
  "app": "string"
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |




## GET /api/v1/public/rates

Курсы валют

Доступ: Без ключа API



### Параметры



Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/public/rates'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `rates` | `array<object>` | Обязательно | Rates |
| `rates[].base_currency` | `string` | Обязательно | Base Currency |
| `rates[].quote_currency` | `string` | Обязательно | Quote Currency |
| `rates[].rate` | `string` | Обязательно | Rate шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rates[].source` | `string` | Обязательно | Source |
| `rates[].captured_at` | `string` | Обязательно | Captured At формат: date-time |

```json
{
  "rates": [
    {
      "base_currency": "USD",
      "quote_currency": "USD",
      "rate": "string",
      "source": "api",
      "captured_at": "2026-07-13T12:00:00Z"
    }
  ]
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |




## GET /api/v1/public/networks

Сети и активы

Доступ: Без ключа API

Это реестр сетей. Доступность оплаты конкретного инвойса определяйте по его payment_options.

### Параметры



Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/public/networks'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

```json
[
  {
    "example_key": "string"
  }
]
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |




## GET /api/v1/public/integrations

Готовые интеграции

Доступ: Без ключа API



### Параметры



Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/public/integrations'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `[].slug` | `string` | Обязательно | Slug |
| `[].display_name` | `string` | Обязательно | Display Name |
| `[].category` | `string` | Обязательно | Category |
| `[].description` | `string` | Обязательно | Description |
| `[].supports_webhooks` | `boolean` | Обязательно | Supports Webhooks |
| `[].supports_embedded_checkout` | `boolean` | Обязательно | Supports Embedded Checkout |
| `[].docs_markdown` | `string` | Обязательно | Docs Markdown |

```json
[
  {
    "slug": "string",
    "display_name": "string",
    "category": "string",
    "description": "string",
    "supports_webhooks": false,
    "supports_embedded_checkout": false,
    "docs_markdown": "string"
  }
]
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |




## Инвойсы и оплата

## POST /api/v1/invoices

Создать инвойс

Доступ: X-API-Key + X-API-Secret

USD или RUB; buy_type: package или balance. Повтор project_id + order_id возвращает существующий инвойс без обновления.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |
| `X-API-Secret` | header | Обязательно | Секрет API этого ключа; требуется для записи. |

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `order_id` | `string` | Обязательно | Ваш идентификатор заказа. Повтор в том же проекте возвращает прежний инвойс. |
| `amount` | `number / string` | Обязательно | Сумма > 0: для инвойса в currency; для выплаты в единицах asset, включая комиссию. Передавайте десятичной строкой. >: 0; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `currency` | `string` | Обязательно | USD или RUB; валюта стоимости заказа, не криптоактив. |
| `buy_type` | `string` | Необязательно | package — оплата заказа; balance — пополнение с учётом фактической подтверждённой суммы после комиссии. по умолчанию: "package"; мин. длина: 1; макс. длина: 32 |
| `callback_url` | `string / null` | Необязательно | Поле совместимости инвойса; не настраивает webhook проекта. Используйте /webhook/config. |
| `success_url` | `string / null` | Необязательно | Абсолютный HTTP(S) URL возврата после оплаты. Возврат не подтверждает зачисление. |
| `cancel_url` | `string / null` | Необязательно | Абсолютный HTTP(S) URL возврата при отмене. |
| `customer_id` | `string / null` | Необязательно | Необязательный идентификатор покупателя в вашей системе. |
| `customer_email` | `string / null` | Необязательно | Необязательный корректный email покупателя. формат: email |
| `metadata` | `object` | Необязательно | Произвольный JSON-объект вашего заказа. Системные поля billing_invoice_kind зарезервированы. |

```bash
curl --request POST 'https://pay.bitcofy.pro/api/v1/invoices' \
  --header "X-API-Key: $BITCOFY_API_KEY" \
  --header "X-API-Secret: $BITCOFY_API_SECRET" \
  --header 'Content-Type: application/json' \
  --data '{
  "project_id": "project_demo_001",
  "order_id": "order_1001",
  "amount": "100.00",
  "currency": "USD",
  "buy_type": "package",
  "callback_url": "https://merchant.example/api/bitcofy/webhook",
  "success_url": "https://merchant.example/payment/success",
  "cancel_url": "https://merchant.example/payment/cancel",
  "customer_id": "customer_42",
  "customer_email": "buyer@example.com",
  "metadata": {
    "order_ref": "SO-1001",
    "source": "landing",
    "plan": "pro"
  }
}'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `invoice_id` | `string` | Обязательно | Идентификатор инвойса из ответа создания. |
| `invoice_hash` | `string` | Обязательно | Публичный идентификатор из ссылки оплаты. Не публикуйте ссылки чужих заказов. |
| `invoice_url` | `string` | Обязательно | Готовая ссылка страницы оплаты для покупателя. |
| `requested_usd_amount` | `string` | Обязательно | Requested Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `service_fee_usd_amount` | `string / null` | Необязательно | Service Fee Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `total_payable_usd_amount` | `string / null` | Необязательно | Total Payable Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `expires_at` | `string` | Обязательно | Expires At формат: date-time |
| `status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `buy_type` | `string` | Обязательно | package — оплата заказа; balance — пополнение с учётом фактической подтверждённой суммы после комиссии. |
| `invoice_language` | `string` | Обязательно | Invoice Language |
| `resolved_language` | `string` | Обязательно | Resolved Language |
| `success_url` | `string / null` | Необязательно | Абсолютный HTTP(S) URL возврата после оплаты. Возврат не подтверждает зачисление. |
| `cancel_url` | `string / null` | Необязательно | Абсолютный HTTP(S) URL возврата при отмене. |
| `payment_session_started_at` | `string / null` | Необязательно | Payment Session Started At формат: date-time |
| `payment_session_expires_at` | `string / null` | Необязательно | Payment Session Expires At формат: date-time |
| `payment_session_active` | `boolean` | Необязательно | Payment Session Active по умолчанию: false |
| `selected_network` | `string / null` | Необязательно | Selected Network |
| `selected_asset` | `string / null` | Необязательно | Selected Asset |
| `payment_options` | `array<object>` | Обязательно | Payment Options |
| `payment_options[].network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `payment_options[].asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `payment_options[].option_key` | `string` | Обязательно | Option Key |
| `payment_options[].fee_percent` | `string` | Необязательно | Fee Percent по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].fee_usd_amount` | `string` | Необязательно | Fee Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].total_payable_usd_amount` | `string` | Необязательно | Total Payable Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].amount_crypto` | `string` | Обязательно | Количество криптоактива для выбранного маршрута оплаты. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].rate_value` | `string` | Обязательно | Rate Value шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].rate_locked_until` | `string` | Обязательно | Rate Locked Until формат: date-time |
| `payment_options[].required_confirmations` | `integer` | Обязательно | Порог подтверждений для этой сети; не фиксируйте число в интеграции. |
| `payment_options[].network_logo_url` | `string / null` | Необязательно | Network Logo Url |
| `payment_options[].asset_logo_url` | `string / null` | Необязательно | Asset Logo Url |
| `tracked_payment_option` | `object / null` | Необязательно | tracked payment option |
| `tracked_payment_option.network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `tracked_payment_option.asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `tracked_payment_option.option_key` | `string` | Обязательно | Option Key |
| `tracked_payment_option.fee_percent` | `string` | Необязательно | Fee Percent по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.fee_usd_amount` | `string` | Необязательно | Fee Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.total_payable_usd_amount` | `string` | Необязательно | Total Payable Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.amount_crypto` | `string` | Обязательно | Количество криптоактива для выбранного маршрута оплаты. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.rate_value` | `string` | Обязательно | Rate Value шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.rate_locked_until` | `string` | Обязательно | Rate Locked Until формат: date-time |
| `tracked_payment_option.required_confirmations` | `integer` | Обязательно | Порог подтверждений для этой сети; не фиксируйте число в интеграции. |
| `tracked_payment_option.network_logo_url` | `string / null` | Необязательно | Network Logo Url |
| `tracked_payment_option.asset_logo_url` | `string / null` | Необязательно | Asset Logo Url |

```json
{
  "invoice_id": "inv_demo_001",
  "invoice_hash": "dd8659b3058a",
  "invoice_url": "string",
  "requested_usd_amount": "string",
  "service_fee_usd_amount": "string",
  "total_payable_usd_amount": "string",
  "expires_at": "2026-07-13T12:00:00Z",
  "status": "ok",
  "buy_type": "package",
  "invoice_language": "auto",
  "resolved_language": "auto",
  "success_url": "https://merchant.example/payment/success",
  "cancel_url": "https://merchant.example/payment/cancel",
  "payment_session_started_at": "2026-07-13T12:00:00Z",
  "payment_session_expires_at": "2026-07-13T12:00:00Z",
  "payment_session_active": false,
  "selected_network": "Tron",
  "selected_asset": "USDT",
  "payment_options": [
    {
      "network": "Tron",
      "asset": "USDT",
      "option_key": "string",
      "fee_percent": "0",
      "fee_usd_amount": "0",
      "total_payable_usd_amount": "0",
      "amount_crypto": "string",
      "rate_value": "string",
      "rate_locked_until": "2026-07-13T12:00:00Z",
      "required_confirmations": 1,
      "network_logo_url": "Tron",
      "asset_logo_url": "USDT"
    }
  ],
  "tracked_payment_option": {
    "network": "Tron",
    "asset": "USDT",
    "option_key": "string",
    "fee_percent": "0",
    "fee_usd_amount": "0",
    "total_payable_usd_amount": "0",
    "amount_crypto": "string",
    "rate_value": "string",
    "rate_locked_until": "2026-07-13T12:00:00Z",
    "required_confirmations": 1,
    "network_logo_url": "Tron",
    "asset_logo_url": "USDT"
  }
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `400` | Некорректный запрос или состояние | Проверьте detail, параметры, подпись и текущее состояние. Не повторяйте неизменённый запрос. |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Invoice not found after creation`

## GET /api/v1/invoices/{invoice_id}

Получить инвойс

Доступ: X-API-Key

Обнаруженная транзакция ещё не равна зачислению. Проверяйте статус, confirmations, required_confirmations и credited там, где они присутствуют в ответе.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `invoice_id` | path · `string` | Обязательно | Идентификатор инвойса из ответа создания.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/invoices/YOUR_INVOICE_ID' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `invoice_id` | `string` | Обязательно | Идентификатор инвойса из ответа создания. |
| `invoice_hash` | `string` | Обязательно | Публичный идентификатор из ссылки оплаты. Не публикуйте ссылки чужих заказов. |
| `invoice_url` | `string` | Обязательно | Готовая ссылка страницы оплаты для покупателя. |
| `requested_usd_amount` | `string` | Обязательно | Requested Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `service_fee_usd_amount` | `string / null` | Необязательно | Service Fee Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `total_payable_usd_amount` | `string / null` | Необязательно | Total Payable Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `expires_at` | `string` | Обязательно | Expires At формат: date-time |
| `status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `buy_type` | `string` | Обязательно | package — оплата заказа; balance — пополнение с учётом фактической подтверждённой суммы после комиссии. |
| `invoice_language` | `string` | Обязательно | Invoice Language |
| `resolved_language` | `string` | Обязательно | Resolved Language |
| `success_url` | `string / null` | Необязательно | Абсолютный HTTP(S) URL возврата после оплаты. Возврат не подтверждает зачисление. |
| `cancel_url` | `string / null` | Необязательно | Абсолютный HTTP(S) URL возврата при отмене. |
| `payment_session_started_at` | `string / null` | Необязательно | Payment Session Started At формат: date-time |
| `payment_session_expires_at` | `string / null` | Необязательно | Payment Session Expires At формат: date-time |
| `payment_session_active` | `boolean` | Необязательно | Payment Session Active по умолчанию: false |
| `selected_network` | `string / null` | Необязательно | Selected Network |
| `selected_asset` | `string / null` | Необязательно | Selected Asset |
| `payment_options` | `array<object>` | Обязательно | Payment Options |
| `payment_options[].network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `payment_options[].asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `payment_options[].option_key` | `string` | Обязательно | Option Key |
| `payment_options[].fee_percent` | `string` | Необязательно | Fee Percent по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].fee_usd_amount` | `string` | Необязательно | Fee Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].total_payable_usd_amount` | `string` | Необязательно | Total Payable Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].amount_crypto` | `string` | Обязательно | Количество криптоактива для выбранного маршрута оплаты. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].rate_value` | `string` | Обязательно | Rate Value шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].rate_locked_until` | `string` | Обязательно | Rate Locked Until формат: date-time |
| `payment_options[].required_confirmations` | `integer` | Обязательно | Порог подтверждений для этой сети; не фиксируйте число в интеграции. |
| `payment_options[].network_logo_url` | `string / null` | Необязательно | Network Logo Url |
| `payment_options[].asset_logo_url` | `string / null` | Необязательно | Asset Logo Url |
| `tracked_payment_option` | `object / null` | Необязательно | tracked payment option |
| `tracked_payment_option.network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `tracked_payment_option.asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `tracked_payment_option.option_key` | `string` | Обязательно | Option Key |
| `tracked_payment_option.fee_percent` | `string` | Необязательно | Fee Percent по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.fee_usd_amount` | `string` | Необязательно | Fee Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.total_payable_usd_amount` | `string` | Необязательно | Total Payable Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.amount_crypto` | `string` | Обязательно | Количество криптоактива для выбранного маршрута оплаты. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.rate_value` | `string` | Обязательно | Rate Value шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.rate_locked_until` | `string` | Обязательно | Rate Locked Until формат: date-time |
| `tracked_payment_option.required_confirmations` | `integer` | Обязательно | Порог подтверждений для этой сети; не фиксируйте число в интеграции. |
| `tracked_payment_option.network_logo_url` | `string / null` | Необязательно | Network Logo Url |
| `tracked_payment_option.asset_logo_url` | `string / null` | Необязательно | Asset Logo Url |
| `order_id` | `string` | Обязательно | Ваш идентификатор заказа. Повтор в том же проекте возвращает прежний инвойс. |
| `fiat_currency` | `string` | Обязательно | Fiat Currency |
| `amount_fiat` | `string` | Обязательно | Amount Fiat шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `deposit_addresses` | `array<object>` | Обязательно | Deposit Addresses |
| `deposit_addresses[].network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `deposit_addresses[].address` | `string` | Обязательно | Address |
| `deposit_addresses[].derivation_path` | `string` | Обязательно | Derivation Path |
| `deposit_addresses[].wallet_status` | `string` | Обязательно | Wallet Status |

```json
{
  "invoice_id": "inv_demo_001",
  "invoice_hash": "dd8659b3058a",
  "invoice_url": "string",
  "requested_usd_amount": "string",
  "service_fee_usd_amount": "string",
  "total_payable_usd_amount": "string",
  "expires_at": "2026-07-13T12:00:00Z",
  "status": "ok",
  "buy_type": "package",
  "invoice_language": "auto",
  "resolved_language": "auto",
  "success_url": "https://merchant.example/payment/success",
  "cancel_url": "https://merchant.example/payment/cancel",
  "payment_session_started_at": "2026-07-13T12:00:00Z",
  "payment_session_expires_at": "2026-07-13T12:00:00Z",
  "payment_session_active": false,
  "selected_network": "Tron",
  "selected_asset": "USDT",
  "payment_options": [
    {
      "network": "Tron",
      "asset": "USDT",
      "option_key": "string",
      "fee_percent": "0",
      "fee_usd_amount": "0",
      "total_payable_usd_amount": "0",
      "amount_crypto": "string",
      "rate_value": "string",
      "rate_locked_until": "2026-07-13T12:00:00Z",
      "required_confirmations": 1,
      "network_logo_url": "Tron",
      "asset_logo_url": "USDT"
    }
  ],
  "tracked_payment_option": {
    "network": "Tron",
    "asset": "USDT",
    "option_key": "string",
    "fee_percent": "0",
    "fee_usd_amount": "0",
    "total_payable_usd_amount": "0",
    "amount_crypto": "string",
    "rate_value": "string",
    "rate_locked_until": "2026-07-13T12:00:00Z",
    "required_confirmations": 1,
    "network_logo_url": "Tron",
    "asset_logo_url": "USDT"
  },
  "order_id": "order_1001",
  "fiat_currency": "USD",
  "amount_fiat": "string",
  "deposit_addresses": [
    {
      "network": "Tron",
      "address": "TQ9ExampleDestinationAddress123456789",
      "derivation_path": "string",
      "wallet_status": "string"
    }
  ]
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Invoice not found`
- `Project API key is required`

## GET /api/v1/invoices/{invoice_id}/payments

Платежи инвойса

Доступ: X-API-Key

Обнаруженная транзакция ещё не равна зачислению. Проверяйте статус, confirmations, required_confirmations и credited там, где они присутствуют в ответе.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `invoice_id` | path · `string` | Обязательно | Идентификатор инвойса из ответа создания.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/invoices/YOUR_INVOICE_ID/payments' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `invoice_id` | `string` | Обязательно | Идентификатор инвойса из ответа создания. |
| `invoice_status` | `string` | Обязательно | Invoice Status |
| `buy_type` | `string` | Обязательно | package — оплата заказа; balance — пополнение с учётом фактической подтверждённой суммы после комиссии. |
| `credited_total_amount` | `string` | Необязательно | Credited Total Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `credited_fee_total` | `string` | Необязательно | Credited Fee Total по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `items` | `array<object>` | Обязательно | Items |
| `items[].transaction_id` | `string` | Обязательно | Transaction Id |
| `items[].invoice_id` | `string` | Обязательно | Идентификатор инвойса из ответа создания. |
| `items[].network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `items[].asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `items[].tx_hash` | `string` | Обязательно | Tx Hash |
| `items[].logical_index` | `string` | Обязательно | Logical Index |
| `items[].address` | `string` | Обязательно | Address |
| `items[].amount` | `string` | Обязательно | Сумма > 0: для инвойса в currency; для выплаты в единицах asset, включая комиссию. Передавайте десятичной строкой. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `items[].confirmations` | `integer` | Обязательно | Текущее количество подтверждений обнаруженной транзакции. |
| `items[].block_number` | `integer / null` | Необязательно | Block Number |
| `items[].status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `items[].buy_type` | `string` | Обязательно | package — оплата заказа; balance — пополнение с учётом фактической подтверждённой суммы после комиссии. |
| `items[].crediting_status` | `string` | Обязательно | Crediting Status |
| `items[].net_amount_after_fee` | `string` | Необязательно | Net Amount After Fee по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `items[].fee_amount` | `string` | Необязательно | Fee Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `items[].detected_at` | `string` | Обязательно | Detected At формат: date-time |
| `items[].confirmed_at` | `string / null` | Необязательно | Confirmed At формат: date-time |

```json
{
  "invoice_id": "inv_demo_001",
  "invoice_status": "string",
  "buy_type": "package",
  "credited_total_amount": "0",
  "credited_fee_total": "0",
  "items": [
    {
      "transaction_id": "string",
      "invoice_id": "inv_demo_001",
      "network": "Tron",
      "asset": "USDT",
      "tx_hash": "0xabc123def456",
      "logical_index": "string",
      "address": "TQ9ExampleDestinationAddress123456789",
      "amount": "string",
      "confirmations": 1,
      "block_number": 1,
      "status": "ok",
      "buy_type": "package",
      "crediting_status": "string",
      "net_amount_after_fee": "0",
      "fee_amount": "0",
      "detected_at": "2026-07-13T12:00:00Z",
      "confirmed_at": "2026-07-13T12:00:00Z"
    }
  ]
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Invoice not found`
- `Project API key is required`

## GET /api/v1/public/invoices/by-hash/{invoice_hash}

Открыть инвойс по публичному идентификатору

Доступ: Без ключа API

Обнаруженная транзакция ещё не равна зачислению. Проверяйте статус, confirmations, required_confirmations и credited там, где они присутствуют в ответе.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `invoice_hash` | path · `string` | Обязательно | Публичный идентификатор из ссылки оплаты. Не публикуйте ссылки чужих заказов.  |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/public/invoices/by-hash/YOUR_INVOICE_HASH'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `invoice_id` | `string` | Обязательно | Идентификатор инвойса из ответа создания. |
| `invoice_hash` | `string` | Обязательно | Публичный идентификатор из ссылки оплаты. Не публикуйте ссылки чужих заказов. |
| `invoice_url` | `string` | Обязательно | Готовая ссылка страницы оплаты для покупателя. |
| `requested_usd_amount` | `string` | Обязательно | Requested Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `service_fee_usd_amount` | `string / null` | Необязательно | Service Fee Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `total_payable_usd_amount` | `string / null` | Необязательно | Total Payable Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `expires_at` | `string` | Обязательно | Expires At формат: date-time |
| `status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `buy_type` | `string` | Обязательно | package — оплата заказа; balance — пополнение с учётом фактической подтверждённой суммы после комиссии. |
| `invoice_language` | `string` | Обязательно | Invoice Language |
| `resolved_language` | `string` | Обязательно | Resolved Language |
| `success_url` | `string / null` | Необязательно | Абсолютный HTTP(S) URL возврата после оплаты. Возврат не подтверждает зачисление. |
| `cancel_url` | `string / null` | Необязательно | Абсолютный HTTP(S) URL возврата при отмене. |
| `payment_session_started_at` | `string / null` | Необязательно | Payment Session Started At формат: date-time |
| `payment_session_expires_at` | `string / null` | Необязательно | Payment Session Expires At формат: date-time |
| `payment_session_active` | `boolean` | Необязательно | Payment Session Active по умолчанию: false |
| `selected_network` | `string / null` | Необязательно | Selected Network |
| `selected_asset` | `string / null` | Необязательно | Selected Asset |
| `payment_options` | `array<object>` | Обязательно | Payment Options |
| `payment_options[].network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `payment_options[].asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `payment_options[].option_key` | `string` | Обязательно | Option Key |
| `payment_options[].fee_percent` | `string` | Необязательно | Fee Percent по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].fee_usd_amount` | `string` | Необязательно | Fee Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].total_payable_usd_amount` | `string` | Необязательно | Total Payable Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].amount_crypto` | `string` | Обязательно | Количество криптоактива для выбранного маршрута оплаты. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].rate_value` | `string` | Обязательно | Rate Value шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].rate_locked_until` | `string` | Обязательно | Rate Locked Until формат: date-time |
| `payment_options[].required_confirmations` | `integer` | Обязательно | Порог подтверждений для этой сети; не фиксируйте число в интеграции. |
| `payment_options[].network_logo_url` | `string / null` | Необязательно | Network Logo Url |
| `payment_options[].asset_logo_url` | `string / null` | Необязательно | Asset Logo Url |
| `tracked_payment_option` | `object / null` | Необязательно | tracked payment option |
| `tracked_payment_option.network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `tracked_payment_option.asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `tracked_payment_option.option_key` | `string` | Обязательно | Option Key |
| `tracked_payment_option.fee_percent` | `string` | Необязательно | Fee Percent по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.fee_usd_amount` | `string` | Необязательно | Fee Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.total_payable_usd_amount` | `string` | Необязательно | Total Payable Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.amount_crypto` | `string` | Обязательно | Количество криптоактива для выбранного маршрута оплаты. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.rate_value` | `string` | Обязательно | Rate Value шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.rate_locked_until` | `string` | Обязательно | Rate Locked Until формат: date-time |
| `tracked_payment_option.required_confirmations` | `integer` | Обязательно | Порог подтверждений для этой сети; не фиксируйте число в интеграции. |
| `tracked_payment_option.network_logo_url` | `string / null` | Необязательно | Network Logo Url |
| `tracked_payment_option.asset_logo_url` | `string / null` | Необязательно | Asset Logo Url |
| `deposit_addresses` | `array<object>` | Обязательно | Deposit Addresses |
| `deposit_addresses[].network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `deposit_addresses[].address` | `string` | Обязательно | Address |

```json
{
  "invoice_id": "inv_demo_001",
  "invoice_hash": "dd8659b3058a",
  "invoice_url": "string",
  "requested_usd_amount": "string",
  "service_fee_usd_amount": "string",
  "total_payable_usd_amount": "string",
  "expires_at": "2026-07-13T12:00:00Z",
  "status": "ok",
  "buy_type": "package",
  "invoice_language": "auto",
  "resolved_language": "auto",
  "success_url": "https://merchant.example/payment/success",
  "cancel_url": "https://merchant.example/payment/cancel",
  "payment_session_started_at": "2026-07-13T12:00:00Z",
  "payment_session_expires_at": "2026-07-13T12:00:00Z",
  "payment_session_active": false,
  "selected_network": "Tron",
  "selected_asset": "USDT",
  "payment_options": [
    {
      "network": "Tron",
      "asset": "USDT",
      "option_key": "string",
      "fee_percent": "0",
      "fee_usd_amount": "0",
      "total_payable_usd_amount": "0",
      "amount_crypto": "string",
      "rate_value": "string",
      "rate_locked_until": "2026-07-13T12:00:00Z",
      "required_confirmations": 1,
      "network_logo_url": "Tron",
      "asset_logo_url": "USDT"
    }
  ],
  "tracked_payment_option": {
    "network": "Tron",
    "asset": "USDT",
    "option_key": "string",
    "fee_percent": "0",
    "fee_usd_amount": "0",
    "total_payable_usd_amount": "0",
    "amount_crypto": "string",
    "rate_value": "string",
    "rate_locked_until": "2026-07-13T12:00:00Z",
    "required_confirmations": 1,
    "network_logo_url": "Tron",
    "asset_logo_url": "USDT"
  },
  "deposit_addresses": [
    {
      "network": "Tron",
      "address": "TQ9ExampleDestinationAddress123456789"
    }
  ]
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `429` | Слишком много запросов | Увеличьте интервал с небольшой случайной задержкой; учитывайте Retry-After, если он есть. |

- `Too many public invoice requests`
- `Invoice not found`

## POST /api/v1/public/invoices/by-hash/{invoice_hash}/payment-session

Открыть сессию оплаты

Доступ: Cookie страницы оплаты

Сначала откройте /payment_{invoice_hash} для получения cookie доступа. Обычно этот метод вызывает готовая страница оплаты.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `invoice_hash` | path · `string` | Обязательно | Публичный идентификатор из ссылки оплаты. Не публикуйте ссылки чужих заказов.  |

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. мин. длина: 1; макс. длина: 32 |
| `asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. мин. длина: 1; макс. длина: 32 |

```bash
curl --request POST 'https://pay.bitcofy.pro/api/v1/public/invoices/by-hash/YOUR_INVOICE_HASH/payment-session' \
  --cookie checkout-cookies.txt \
  --header 'Content-Type: application/json' \
  --data '{
  "network": "Ethereum",
  "asset": "USDT"
}'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `invoice_id` | `string` | Обязательно | Идентификатор инвойса из ответа создания. |
| `invoice_hash` | `string` | Обязательно | Публичный идентификатор из ссылки оплаты. Не публикуйте ссылки чужих заказов. |
| `invoice_url` | `string` | Обязательно | Готовая ссылка страницы оплаты для покупателя. |
| `requested_usd_amount` | `string` | Обязательно | Requested Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `service_fee_usd_amount` | `string / null` | Необязательно | Service Fee Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `total_payable_usd_amount` | `string / null` | Необязательно | Total Payable Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `expires_at` | `string` | Обязательно | Expires At формат: date-time |
| `status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `buy_type` | `string` | Обязательно | package — оплата заказа; balance — пополнение с учётом фактической подтверждённой суммы после комиссии. |
| `invoice_language` | `string` | Обязательно | Invoice Language |
| `resolved_language` | `string` | Обязательно | Resolved Language |
| `success_url` | `string / null` | Необязательно | Абсолютный HTTP(S) URL возврата после оплаты. Возврат не подтверждает зачисление. |
| `cancel_url` | `string / null` | Необязательно | Абсолютный HTTP(S) URL возврата при отмене. |
| `payment_session_started_at` | `string / null` | Необязательно | Payment Session Started At формат: date-time |
| `payment_session_expires_at` | `string / null` | Необязательно | Payment Session Expires At формат: date-time |
| `payment_session_active` | `boolean` | Необязательно | Payment Session Active по умолчанию: false |
| `selected_network` | `string / null` | Необязательно | Selected Network |
| `selected_asset` | `string / null` | Необязательно | Selected Asset |
| `payment_options` | `array<object>` | Обязательно | Payment Options |
| `payment_options[].network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `payment_options[].asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `payment_options[].option_key` | `string` | Обязательно | Option Key |
| `payment_options[].fee_percent` | `string` | Необязательно | Fee Percent по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].fee_usd_amount` | `string` | Необязательно | Fee Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].total_payable_usd_amount` | `string` | Необязательно | Total Payable Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].amount_crypto` | `string` | Обязательно | Количество криптоактива для выбранного маршрута оплаты. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].rate_value` | `string` | Обязательно | Rate Value шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].rate_locked_until` | `string` | Обязательно | Rate Locked Until формат: date-time |
| `payment_options[].required_confirmations` | `integer` | Обязательно | Порог подтверждений для этой сети; не фиксируйте число в интеграции. |
| `payment_options[].network_logo_url` | `string / null` | Необязательно | Network Logo Url |
| `payment_options[].asset_logo_url` | `string / null` | Необязательно | Asset Logo Url |
| `tracked_payment_option` | `object / null` | Необязательно | tracked payment option |
| `tracked_payment_option.network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `tracked_payment_option.asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `tracked_payment_option.option_key` | `string` | Обязательно | Option Key |
| `tracked_payment_option.fee_percent` | `string` | Необязательно | Fee Percent по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.fee_usd_amount` | `string` | Необязательно | Fee Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.total_payable_usd_amount` | `string` | Необязательно | Total Payable Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.amount_crypto` | `string` | Обязательно | Количество криптоактива для выбранного маршрута оплаты. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.rate_value` | `string` | Обязательно | Rate Value шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.rate_locked_until` | `string` | Обязательно | Rate Locked Until формат: date-time |
| `tracked_payment_option.required_confirmations` | `integer` | Обязательно | Порог подтверждений для этой сети; не фиксируйте число в интеграции. |
| `tracked_payment_option.network_logo_url` | `string / null` | Необязательно | Network Logo Url |
| `tracked_payment_option.asset_logo_url` | `string / null` | Необязательно | Asset Logo Url |
| `deposit_addresses` | `array<object>` | Обязательно | Deposit Addresses |
| `deposit_addresses[].network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `deposit_addresses[].address` | `string` | Обязательно | Address |

```json
{
  "invoice_id": "inv_demo_001",
  "invoice_hash": "dd8659b3058a",
  "invoice_url": "string",
  "requested_usd_amount": "string",
  "service_fee_usd_amount": "string",
  "total_payable_usd_amount": "string",
  "expires_at": "2026-07-13T12:00:00Z",
  "status": "ok",
  "buy_type": "package",
  "invoice_language": "auto",
  "resolved_language": "auto",
  "success_url": "https://merchant.example/payment/success",
  "cancel_url": "https://merchant.example/payment/cancel",
  "payment_session_started_at": "2026-07-13T12:00:00Z",
  "payment_session_expires_at": "2026-07-13T12:00:00Z",
  "payment_session_active": false,
  "selected_network": "Tron",
  "selected_asset": "USDT",
  "payment_options": [
    {
      "network": "Tron",
      "asset": "USDT",
      "option_key": "string",
      "fee_percent": "0",
      "fee_usd_amount": "0",
      "total_payable_usd_amount": "0",
      "amount_crypto": "string",
      "rate_value": "string",
      "rate_locked_until": "2026-07-13T12:00:00Z",
      "required_confirmations": 1,
      "network_logo_url": "Tron",
      "asset_logo_url": "USDT"
    }
  ],
  "tracked_payment_option": {
    "network": "Tron",
    "asset": "USDT",
    "option_key": "string",
    "fee_percent": "0",
    "fee_usd_amount": "0",
    "total_payable_usd_amount": "0",
    "amount_crypto": "string",
    "rate_value": "string",
    "rate_locked_until": "2026-07-13T12:00:00Z",
    "required_confirmations": 1,
    "network_logo_url": "Tron",
    "asset_logo_url": "USDT"
  },
  "deposit_addresses": [
    {
      "network": "Tron",
      "address": "TQ9ExampleDestinationAddress123456789"
    }
  ]
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `400` | Некорректный запрос или состояние | Проверьте detail, параметры, подпись и текущее состояние. Не повторяйте неизменённый запрос. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `429` | Слишком много запросов | Увеличьте интервал с небольшой случайной задержкой; учитывайте Retry-After, если он есть. |

- `Too many public invoice requests`
- `Open the hosted invoice page before starting a payment session`
- `Invoice not found`

## GET /api/v1/public/invoices/by-hash/{invoice_hash}/payments

Платежи по публичному идентификатору

Доступ: Без ключа API

Обнаруженная транзакция ещё не равна зачислению. Проверяйте статус, confirmations, required_confirmations и credited там, где они присутствуют в ответе.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `invoice_hash` | path · `string` | Обязательно | Публичный идентификатор из ссылки оплаты. Не публикуйте ссылки чужих заказов.  |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/public/invoices/by-hash/YOUR_INVOICE_HASH/payments'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `invoice_id` | `string` | Обязательно | Идентификатор инвойса из ответа создания. |
| `invoice_status` | `string` | Обязательно | Invoice Status |
| `items` | `array<object>` | Обязательно | Items |
| `items[].network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `items[].asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `items[].confirmations` | `integer` | Обязательно | Текущее количество подтверждений обнаруженной транзакции. |
| `items[].status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |

```json
{
  "invoice_id": "inv_demo_001",
  "invoice_status": "string",
  "items": [
    {
      "network": "Tron",
      "asset": "USDT",
      "confirmations": 1,
      "status": "ok"
    }
  ]
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `429` | Слишком много запросов | Увеличьте интервал с небольшой случайной задержкой; учитывайте Retry-After, если он есть. |

- `Too many public invoice requests`
- `Invoice not found`

## GET /api/v1/projects/{project_id}/invoices/by-order/{order_id}

Найти инвойс по заказу

Доступ: X-API-Key

Обнаруженная транзакция ещё не равна зачислению. Проверяйте статус, confirmations, required_confirmations и credited там, где они присутствуют в ответе.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `order_id` | path · `string` | Обязательно | Ваш идентификатор заказа. Повтор в том же проекте возвращает прежний инвойс.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/invoices/by-order/YOUR_ORDER_ID' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `invoice_id` | `string` | Обязательно | Идентификатор инвойса из ответа создания. |
| `invoice_hash` | `string` | Обязательно | Публичный идентификатор из ссылки оплаты. Не публикуйте ссылки чужих заказов. |
| `invoice_url` | `string` | Обязательно | Готовая ссылка страницы оплаты для покупателя. |
| `requested_usd_amount` | `string` | Обязательно | Requested Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `service_fee_usd_amount` | `string / null` | Необязательно | Service Fee Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `total_payable_usd_amount` | `string / null` | Необязательно | Total Payable Usd Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `expires_at` | `string` | Обязательно | Expires At формат: date-time |
| `status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `buy_type` | `string` | Обязательно | package — оплата заказа; balance — пополнение с учётом фактической подтверждённой суммы после комиссии. |
| `invoice_language` | `string` | Обязательно | Invoice Language |
| `resolved_language` | `string` | Обязательно | Resolved Language |
| `success_url` | `string / null` | Необязательно | Абсолютный HTTP(S) URL возврата после оплаты. Возврат не подтверждает зачисление. |
| `cancel_url` | `string / null` | Необязательно | Абсолютный HTTP(S) URL возврата при отмене. |
| `payment_session_started_at` | `string / null` | Необязательно | Payment Session Started At формат: date-time |
| `payment_session_expires_at` | `string / null` | Необязательно | Payment Session Expires At формат: date-time |
| `payment_session_active` | `boolean` | Необязательно | Payment Session Active по умолчанию: false |
| `selected_network` | `string / null` | Необязательно | Selected Network |
| `selected_asset` | `string / null` | Необязательно | Selected Asset |
| `payment_options` | `array<object>` | Обязательно | Payment Options |
| `payment_options[].network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `payment_options[].asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `payment_options[].option_key` | `string` | Обязательно | Option Key |
| `payment_options[].fee_percent` | `string` | Необязательно | Fee Percent по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].fee_usd_amount` | `string` | Необязательно | Fee Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].total_payable_usd_amount` | `string` | Необязательно | Total Payable Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].amount_crypto` | `string` | Обязательно | Количество криптоактива для выбранного маршрута оплаты. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].rate_value` | `string` | Обязательно | Rate Value шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment_options[].rate_locked_until` | `string` | Обязательно | Rate Locked Until формат: date-time |
| `payment_options[].required_confirmations` | `integer` | Обязательно | Порог подтверждений для этой сети; не фиксируйте число в интеграции. |
| `payment_options[].network_logo_url` | `string / null` | Необязательно | Network Logo Url |
| `payment_options[].asset_logo_url` | `string / null` | Необязательно | Asset Logo Url |
| `tracked_payment_option` | `object / null` | Необязательно | tracked payment option |
| `tracked_payment_option.network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `tracked_payment_option.asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `tracked_payment_option.option_key` | `string` | Обязательно | Option Key |
| `tracked_payment_option.fee_percent` | `string` | Необязательно | Fee Percent по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.fee_usd_amount` | `string` | Необязательно | Fee Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.total_payable_usd_amount` | `string` | Необязательно | Total Payable Usd Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.amount_crypto` | `string` | Обязательно | Количество криптоактива для выбранного маршрута оплаты. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.rate_value` | `string` | Обязательно | Rate Value шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tracked_payment_option.rate_locked_until` | `string` | Обязательно | Rate Locked Until формат: date-time |
| `tracked_payment_option.required_confirmations` | `integer` | Обязательно | Порог подтверждений для этой сети; не фиксируйте число в интеграции. |
| `tracked_payment_option.network_logo_url` | `string / null` | Необязательно | Network Logo Url |
| `tracked_payment_option.asset_logo_url` | `string / null` | Необязательно | Asset Logo Url |
| `order_id` | `string` | Обязательно | Ваш идентификатор заказа. Повтор в том же проекте возвращает прежний инвойс. |
| `fiat_currency` | `string` | Обязательно | Fiat Currency |
| `amount_fiat` | `string` | Обязательно | Amount Fiat шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `deposit_addresses` | `array<object>` | Обязательно | Deposit Addresses |
| `deposit_addresses[].network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `deposit_addresses[].address` | `string` | Обязательно | Address |
| `deposit_addresses[].derivation_path` | `string` | Обязательно | Derivation Path |
| `deposit_addresses[].wallet_status` | `string` | Обязательно | Wallet Status |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |

```json
{
  "invoice_id": "inv_demo_001",
  "invoice_hash": "dd8659b3058a",
  "invoice_url": "string",
  "requested_usd_amount": "string",
  "service_fee_usd_amount": "string",
  "total_payable_usd_amount": "string",
  "expires_at": "2026-07-13T12:00:00Z",
  "status": "ok",
  "buy_type": "package",
  "invoice_language": "auto",
  "resolved_language": "auto",
  "success_url": "https://merchant.example/payment/success",
  "cancel_url": "https://merchant.example/payment/cancel",
  "payment_session_started_at": "2026-07-13T12:00:00Z",
  "payment_session_expires_at": "2026-07-13T12:00:00Z",
  "payment_session_active": false,
  "selected_network": "Tron",
  "selected_asset": "USDT",
  "payment_options": [
    {
      "network": "Tron",
      "asset": "USDT",
      "option_key": "string",
      "fee_percent": "0",
      "fee_usd_amount": "0",
      "total_payable_usd_amount": "0",
      "amount_crypto": "string",
      "rate_value": "string",
      "rate_locked_until": "2026-07-13T12:00:00Z",
      "required_confirmations": 1,
      "network_logo_url": "Tron",
      "asset_logo_url": "USDT"
    }
  ],
  "tracked_payment_option": {
    "network": "Tron",
    "asset": "USDT",
    "option_key": "string",
    "fee_percent": "0",
    "fee_usd_amount": "0",
    "total_payable_usd_amount": "0",
    "amount_crypto": "string",
    "rate_value": "string",
    "rate_locked_until": "2026-07-13T12:00:00Z",
    "required_confirmations": 1,
    "network_logo_url": "Tron",
    "asset_logo_url": "USDT"
  },
  "order_id": "order_1001",
  "fiat_currency": "USD",
  "amount_fiat": "string",
  "deposit_addresses": [
    {
      "network": "Tron",
      "address": "TQ9ExampleDestinationAddress123456789",
      "derivation_path": "string",
      "wallet_status": "string"
    }
  ],
  "project_id": "project_demo_001"
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Invoice not found`
- `Project API key is required`

## GET /api/v1/invoices/{invoice_id}/qr

QR-код инвойса

Доступ: X-API-Key

Обнаруженная транзакция ещё не равна зачислению. Проверяйте статус, confirmations, required_confirmations и credited там, где они присутствуют в ответе.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `invoice_id` | path · `string` | Обязательно | Идентификатор инвойса из ответа создания.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/invoices/YOUR_INVOICE_ID/qr' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · image/svg+xml

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

```xml
<svg xmlns="http://www.w3.org/2000/svg">…</svg>
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Invoice not found`
- `Project API key is required`

## GET /api/v1/public/invoices/by-hash/{invoice_hash}/payment-qr

QR-код выбранного способа оплаты

Доступ: Без ключа API

Обнаруженная транзакция ещё не равна зачислению. Проверяйте статус, confirmations, required_confirmations и credited там, где они присутствуют в ответе.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `invoice_hash` | path · `string` | Обязательно | Публичный идентификатор из ссылки оплаты. Не публикуйте ссылки чужих заказов.  |
| `network` | query · `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса.  |
| `asset` | query · `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте.  |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/public/invoices/by-hash/YOUR_INVOICE_HASH/payment-qr?network=tron&asset=USDT'
```

### 200 · image/svg+xml

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

```xml
<svg xmlns="http://www.w3.org/2000/svg">…</svg>
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `429` | Слишком много запросов | Увеличьте интервал с небольшой случайной задержкой; учитывайте Retry-After, если он есть. |

- `Too many public invoice requests`
- `Invoice not found`
- `Payment option not found`

## Проект и ключи

## GET /api/v1/projects/{project_id}/api-keys

Ключи API проекта

Доступ: X-API-Key

При выпуске ключ и секрет возвращаются один раз. В списке доступны префиксы и состояние.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/api-keys' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `[].key_id` | `string` | Обязательно | Идентификатор ключа из списка ключей проекта. |
| `[].project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `[].name` | `string` | Обязательно | Название ключа для удобного различения в списке. |
| `[].key_prefix` | `string` | Обязательно | Key Prefix |
| `[].secret_prefix` | `string / null` | Необязательно | Secret Prefix |
| `[].api_key` | `string / null` | Необязательно | Ключ доступа к API проекта; при выпуске сохраните сразу. |
| `[].api_secret` | `string / null` | Необязательно | Секрет для запросов записи; возвращается при выпуске, храните на сервере. |
| `[].is_active` | `boolean` | Обязательно | Is Active |
| `[].last_used_at` | `string / null` | Необязательно | Last Used At формат: date-time |
| `[].created_at` | `string` | Обязательно | Created At формат: date-time |

```json
[
  {
    "key_id": "string",
    "project_id": "project_demo_001",
    "name": "string",
    "key_prefix": "string",
    "secret_prefix": "secret_123456",
    "api_key": "string",
    "api_secret": "secret_123456",
    "is_active": false,
    "last_used_at": "2026-07-13T12:00:00Z",
    "created_at": "2026-07-13T12:00:00Z"
  }
]
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Project API key is required`

## POST /api/v1/projects/{project_id}/api-keys

Выпустить ключ API

Доступ: X-API-Key + X-API-Secret

При выпуске ключ и секрет возвращаются один раз. В списке доступны префиксы и состояние.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |
| `X-API-Secret` | header | Обязательно | Секрет API этого ключа; требуется для записи. |

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `name` | `string` | Обязательно | Название ключа для удобного различения в списке. мин. длина: 1; макс. длина: 128 |

```bash
curl --request POST 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/api-keys' \
  --header "X-API-Key: $BITCOFY_API_KEY" \
  --header "X-API-Secret: $BITCOFY_API_SECRET" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Integration key"
}'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `key_id` | `string` | Обязательно | Идентификатор ключа из списка ключей проекта. |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `name` | `string` | Обязательно | Название ключа для удобного различения в списке. |
| `key_prefix` | `string` | Обязательно | Key Prefix |
| `secret_prefix` | `string / null` | Необязательно | Secret Prefix |
| `api_key` | `string` | Обязательно | Ключ доступа к API проекта; при выпуске сохраните сразу. |
| `api_secret` | `string` | Обязательно | Секрет для запросов записи; возвращается при выпуске, храните на сервере. |
| `is_active` | `boolean` | Обязательно | Is Active |
| `last_used_at` | `string / null` | Необязательно | Last Used At формат: date-time |
| `created_at` | `string` | Обязательно | Created At формат: date-time |

```json
{
  "key_id": "string",
  "project_id": "project_demo_001",
  "name": "string",
  "key_prefix": "string",
  "secret_prefix": "secret_123456",
  "api_key": "string",
  "api_secret": "secret_123456",
  "is_active": false,
  "last_used_at": "2026-07-13T12:00:00Z",
  "created_at": "2026-07-13T12:00:00Z"
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `400` | Некорректный запрос или состояние | Проверьте detail, параметры, подпись и текущее состояние. Не повторяйте неизменённый запрос. |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`

## POST /api/v1/projects/{project_id}/api-keys/{key_id}/deactivate

Отключить ключ API

Доступ: X-API-Key + X-API-Secret



### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `key_id` | path · `string` | Обязательно | Идентификатор ключа из списка ключей проекта.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |
| `X-API-Secret` | header | Обязательно | Секрет API этого ключа; требуется для записи. |

Тело запроса не требуется.

```bash
curl --request POST 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/api-keys/YOUR_KEY_ID/deactivate' \
  --header "X-API-Key: $BITCOFY_API_KEY" \
  --header "X-API-Secret: $BITCOFY_API_SECRET"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `key_id` | `string` | Обязательно | Идентификатор ключа из списка ключей проекта. |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `name` | `string` | Обязательно | Название ключа для удобного различения в списке. |
| `key_prefix` | `string` | Обязательно | Key Prefix |
| `secret_prefix` | `string / null` | Необязательно | Secret Prefix |
| `api_key` | `string / null` | Необязательно | Ключ доступа к API проекта; при выпуске сохраните сразу. |
| `api_secret` | `string / null` | Необязательно | Секрет для запросов записи; возвращается при выпуске, храните на сервере. |
| `is_active` | `boolean` | Обязательно | Is Active |
| `last_used_at` | `string / null` | Необязательно | Last Used At формат: date-time |
| `created_at` | `string` | Обязательно | Created At формат: date-time |

```json
{
  "key_id": "string",
  "project_id": "project_demo_001",
  "name": "string",
  "key_prefix": "string",
  "secret_prefix": "secret_123456",
  "api_key": "string",
  "api_secret": "secret_123456",
  "is_active": false,
  "last_used_at": "2026-07-13T12:00:00Z",
  "created_at": "2026-07-13T12:00:00Z"
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `400` | Некорректный запрос или состояние | Проверьте detail, параметры, подпись и текущее состояние. Не повторяйте неизменённый запрос. |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`

## POST /api/v1/projects/{project_id}/security/payout-key

Зарегистрировать открытый ключ выплат

Доступ: X-API-Key + X-API-Secret



### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |
| `X-API-Secret` | header | Обязательно | Секрет API этого ключа; требуется для записи. |

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `public_key` | `string` | Обязательно | Открытый ключ Ed25519, 32 байта в Base64. мин. длина: 32 |
| `algorithm` | `string` | Необязательно | Ed25519. по умолчанию: "Ed25519" |
| `name` | `string / null` | Необязательно | Название ключа для удобного различения в списке. макс. длина: 128 |

```bash
curl --request POST 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/security/payout-key' \
  --header "X-API-Key: $BITCOFY_API_KEY" \
  --header "X-API-Secret: $BITCOFY_API_SECRET" \
  --header 'Content-Type: application/json' \
  --data '{
  "public_key": "BASE64_ED25519_PUBLIC_KEY",
  "algorithm": "Ed25519",
  "name": "string"
}'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `key_id` | `string` | Обязательно | Идентификатор ключа из списка ключей проекта. |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `name` | `string` | Обязательно | Название ключа для удобного различения в списке. |
| `algorithm` | `string` | Обязательно | Ed25519. |
| `public_key` | `string` | Обязательно | Открытый ключ Ed25519, 32 байта в Base64. |
| `public_key_preview` | `string` | Обязательно | Public Key Preview |
| `origin` | `string` | Обязательно | Origin |
| `is_active` | `boolean` | Обязательно | Is Active |
| `created_at` | `string` | Обязательно | Created At формат: date-time |
| `private_key` | `string / null` | Необязательно | Закрытый ключ: возвращается только при генерации. Сразу сохраните в защищённом хранилище. |
| `signing_message_example` | `string` | Обязательно | Пример канонического сообщения; замените значения своими перед подписью. |

```json
{
  "key_id": "string",
  "project_id": "project_demo_001",
  "name": "string",
  "algorithm": "string",
  "public_key": "BASE64_ED25519_PUBLIC_KEY",
  "public_key_preview": "BASE64_ED25519_PUBLIC_KEY",
  "origin": "string",
  "is_active": false,
  "created_at": "2026-07-13T12:00:00Z",
  "private_key": "BASE64_ED25519_PRIVATE_KEY",
  "signing_message_example": "string"
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `400` | Некорректный запрос или состояние | Проверьте detail, параметры, подпись и текущее состояние. Не повторяйте неизменённый запрос. |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`

## GET /api/v1/projects/{project_id}/payout-keys

Ключи подписи выплат

Доступ: X-API-Key



### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/payout-keys' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `[].key_id` | `string` | Обязательно | Идентификатор ключа из списка ключей проекта. |
| `[].project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `[].name` | `string` | Обязательно | Название ключа для удобного различения в списке. |
| `[].algorithm` | `string` | Обязательно | Ed25519. |
| `[].public_key` | `string` | Обязательно | Открытый ключ Ed25519, 32 байта в Base64. |
| `[].public_key_preview` | `string` | Обязательно | Public Key Preview |
| `[].origin` | `string` | Обязательно | Origin |
| `[].is_active` | `boolean` | Обязательно | Is Active |
| `[].created_at` | `string` | Обязательно | Created At формат: date-time |

```json
[
  {
    "key_id": "string",
    "project_id": "project_demo_001",
    "name": "string",
    "algorithm": "string",
    "public_key": "BASE64_ED25519_PUBLIC_KEY",
    "public_key_preview": "BASE64_ED25519_PUBLIC_KEY",
    "origin": "string",
    "is_active": false,
    "created_at": "2026-07-13T12:00:00Z"
  }
]
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Project API key is required`

## POST /api/v1/projects/{project_id}/payout-keys/generate

Сгенерировать пару ключей выплат

Доступ: X-API-Key + X-API-Secret

Сервис создаёт пару Ed25519 и возвращает private_key один раз. Можно сгенерировать пару у себя и зарегистрировать только public_key через /security/payout-key.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |
| `X-API-Secret` | header | Обязательно | Секрет API этого ключа; требуется для записи. |

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `name` | `string / null` | Необязательно | Название ключа для удобного различения в списке. макс. длина: 128 |

```bash
curl --request POST 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/payout-keys/generate' \
  --header "X-API-Key: $BITCOFY_API_KEY" \
  --header "X-API-Secret: $BITCOFY_API_SECRET" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "string"
}'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `key_id` | `string` | Обязательно | Идентификатор ключа из списка ключей проекта. |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `name` | `string` | Обязательно | Название ключа для удобного различения в списке. |
| `algorithm` | `string` | Обязательно | Ed25519. |
| `public_key` | `string` | Обязательно | Открытый ключ Ed25519, 32 байта в Base64. |
| `public_key_preview` | `string` | Обязательно | Public Key Preview |
| `origin` | `string` | Обязательно | Origin |
| `is_active` | `boolean` | Обязательно | Is Active |
| `created_at` | `string` | Обязательно | Created At формат: date-time |
| `private_key` | `string / null` | Необязательно | Закрытый ключ: возвращается только при генерации. Сразу сохраните в защищённом хранилище. |
| `signing_message_example` | `string` | Обязательно | Пример канонического сообщения; замените значения своими перед подписью. |

```json
{
  "key_id": "string",
  "project_id": "project_demo_001",
  "name": "string",
  "algorithm": "string",
  "public_key": "BASE64_ED25519_PUBLIC_KEY",
  "public_key_preview": "BASE64_ED25519_PUBLIC_KEY",
  "origin": "string",
  "is_active": false,
  "created_at": "2026-07-13T12:00:00Z",
  "private_key": "BASE64_ED25519_PRIVATE_KEY",
  "signing_message_example": "string"
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `400` | Некорректный запрос или состояние | Проверьте detail, параметры, подпись и текущее состояние. Не повторяйте неизменённый запрос. |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`

## POST /api/v1/projects/{project_id}/payout-keys/{key_id}/delete

Удалить ключ выплат

Доступ: X-API-Key + X-API-Secret



### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `key_id` | path · `string` | Обязательно | Идентификатор ключа из списка ключей проекта.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |
| `X-API-Secret` | header | Обязательно | Секрет API этого ключа; требуется для записи. |

Тело запроса не требуется.

```bash
curl --request POST 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/payout-keys/YOUR_KEY_ID/delete' \
  --header "X-API-Key: $BITCOFY_API_KEY" \
  --header "X-API-Secret: $BITCOFY_API_SECRET"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `key_id` | `string` | Обязательно | Идентификатор ключа из списка ключей проекта. |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `name` | `string` | Обязательно | Название ключа для удобного различения в списке. |
| `algorithm` | `string` | Обязательно | Ed25519. |
| `public_key` | `string` | Обязательно | Открытый ключ Ed25519, 32 байта в Base64. |
| `public_key_preview` | `string` | Обязательно | Public Key Preview |
| `origin` | `string` | Обязательно | Origin |
| `is_active` | `boolean` | Обязательно | Is Active |
| `created_at` | `string` | Обязательно | Created At формат: date-time |

```json
{
  "key_id": "string",
  "project_id": "project_demo_001",
  "name": "string",
  "algorithm": "string",
  "public_key": "BASE64_ED25519_PUBLIC_KEY",
  "public_key_preview": "BASE64_ED25519_PUBLIC_KEY",
  "origin": "string",
  "is_active": false,
  "created_at": "2026-07-13T12:00:00Z"
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `400` | Некорректный запрос или состояние | Проверьте detail, параметры, подпись и текущее состояние. Не повторяйте неизменённый запрос. |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`

## GET /api/v1/projects/{project_id}/payout-keys/{key_id}/signing-message-example

Пример сообщения для подписи

Доступ: X-API-Key



### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `key_id` | path · `string` | Обязательно | Идентификатор ключа из списка ключей проекта.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/payout-keys/YOUR_KEY_ID/signing-message-example' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `key_id` | `string` | Обязательно | Идентификатор ключа из списка ключей проекта. |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `algorithm` | `string` | Обязательно | Ed25519. |
| `public_key` | `string` | Обязательно | Открытый ключ Ed25519, 32 байта в Base64. |
| `origin` | `string` | Обязательно | Origin |
| `signing_message_example` | `string` | Обязательно | Пример канонического сообщения; замените значения своими перед подписью. |

```json
{
  "key_id": "string",
  "project_id": "project_demo_001",
  "algorithm": "string",
  "public_key": "BASE64_ED25519_PUBLIC_KEY",
  "origin": "string",
  "signing_message_example": "string"
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Project API key is required`

## GET /api/v1/projects/{project_id}/balances

Балансы проекта

Доступ: X-API-Key



### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/balances' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `balances` | `array<object>` | Обязательно | Balances |
| `balances[].project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `balances[].network` | `string / null` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `balances[].asset` | `string / null` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `balances[].account_code` | `string` | Обязательно | Account Code |
| `balances[].balance` | `string` | Обязательно | Balance шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `balances[].available_for_withdrawal` | `string / null` | Необязательно | Available For Withdrawal шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `balances[].pending_aggregation_balance` | `string / null` | Необязательно | Pending Aggregation Balance шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

```json
{
  "balances": [
    {
      "project_id": "project_demo_001",
      "network": "Tron",
      "asset": "USDT",
      "account_code": "string",
      "balance": "string",
      "available_for_withdrawal": "string",
      "pending_aggregation_balance": "string"
    }
  ]
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Project API key is required`

## GET /api/v1/projects/{project_id}/transactions

Операции проекта

Доступ: X-API-Key



### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/transactions' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `items` | `array<object>` | Обязательно | Items |
| `items[].transaction_type` | `string` | Обязательно | Transaction Type |
| `items[].reference_id` | `string` | Обязательно | Reference Id |
| `items[].status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `items[].network` | `string / null` | Необязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `items[].asset` | `string / null` | Необязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `items[].amount` | `string` | Обязательно | Сумма > 0: для инвойса в currency; для выплаты в единицах asset, включая комиссию. Передавайте десятичной строкой. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `items[].currency` | `string / null` | Необязательно | USD или RUB; валюта стоимости заказа, не криптоактив. |
| `items[].created_at` | `string` | Обязательно | Created At формат: date-time |
| `items[].meta` | `object` | Необязательно | Meta |

```json
{
  "items": [
    {
      "transaction_type": "string",
      "reference_id": "string",
      "status": "ok",
      "network": "Tron",
      "asset": "USDT",
      "amount": "string",
      "currency": "USD",
      "created_at": "2026-07-13T12:00:00Z",
      "meta": {
        "example_key": "string"
      }
    }
  ]
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Project API key is required`

## GET /api/v1/projects/{project_id}/transactions/export.csv

Экспорт операций в CSV

Доступ: X-API-Key



### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/transactions/export.csv' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · text/csv

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

```text
CSV-файл операций. Набор колонок зависит от формата экспорта.
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Project API key is required`

## GET /api/v1/projects/{project_id}/transactions/export-quickbooks.csv

Экспорт операций в QuickBooks

Доступ: X-API-Key



### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/transactions/export-quickbooks.csv' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · text/csv

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

```text
CSV-файл операций. Набор колонок зависит от формата экспорта.
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Project API key is required`

## Выплаты

## GET /api/v1/projects/{project_id}/payout-requests

Заявки на выплату

Доступ: X-API-Key



### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/payout-requests' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `[].request_id` | `string` | Обязательно | Идентификатор заявки на выплату. |
| `[].project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `[].network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `[].asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `[].amount` | `string` | Обязательно | Сумма > 0: для инвойса в currency; для выплаты в единицах asset, включая комиссию. Передавайте десятичной строкой. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `[].destination_address` | `string` | Обязательно | Адрес получателя в указанной сети. Проверяйте сеть до подписи. |
| `[].status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `[].idempotency_key` | `string` | Обязательно | Ваш постоянный идентификатор одной логической выплаты; повторно используйте при сверке. |
| `[].requested_via` | `string` | Обязательно | Requested Via |
| `[].requested_by_user_id` | `string / null` | Необязательно | Requested By User Id |
| `[].approved_by_user_id` | `string / null` | Необязательно | Approved By User Id |
| `[].rejected_by_user_id` | `string / null` | Необязательно | Rejected By User Id |
| `[].approved_payout_id` | `string / null` | Необязательно | Approved Payout Id |
| `[].approved_payout_status` | `string / null` | Необязательно | Approved Payout Status |
| `[].rejection_reason` | `string / null` | Необязательно | Причина отказа; входит в подписываемое сообщение без изменения. |
| `[].note` | `string / null` | Необязательно | Необязательное пояснение к заявке. |
| `[].created_at` | `string` | Обязательно | Created At формат: date-time |
| `[].decided_at` | `string / null` | Необязательно | Decided At формат: date-time |

```json
[
  {
    "request_id": "req_demo_001",
    "project_id": "project_demo_001",
    "network": "Tron",
    "asset": "USDT",
    "amount": "string",
    "destination_address": "TQ9ExampleDestinationAddress123456789",
    "status": "ok",
    "idempotency_key": "action_001",
    "requested_via": "string",
    "requested_by_user_id": "string",
    "approved_by_user_id": "string",
    "rejected_by_user_id": "string",
    "approved_payout_id": "payout_demo_001",
    "approved_payout_status": "string",
    "rejection_reason": "string",
    "note": "string",
    "created_at": "2026-07-13T12:00:00Z",
    "decided_at": "2026-07-13T12:00:00Z"
  }
]
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Project API key is required`

## POST /api/v1/projects/{project_id}/payout-requests

Создать заявку на выплату

Доступ: X-API-Key + X-API-Secret

Комиссия входит в amount. Принятие операции API не подтверждает отправку в блокчейн; отслеживайте состояние выплаты.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |
| `X-API-Secret` | header | Обязательно | Секрет API этого ключа; требуется для записи. |

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `amount` | `number / string` | Обязательно | Сумма > 0: для инвойса в currency; для выплаты в единицах asset, включая комиссию. Передавайте десятичной строкой. >: 0; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `destination_address` | `string` | Обязательно | Адрес получателя в указанной сети. Проверяйте сеть до подписи. |
| `idempotency_key` | `string` | Обязательно | Ваш постоянный идентификатор одной логической выплаты; повторно используйте при сверке. мин. длина: 1; макс. длина: 255 |
| `note` | `string / null` | Необязательно | Необязательное пояснение к заявке. макс. длина: 500 |

```bash
curl --request POST 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/payout-requests' \
  --header "X-API-Key: $BITCOFY_API_KEY" \
  --header "X-API-Secret: $BITCOFY_API_SECRET" \
  --header 'Content-Type: application/json' \
  --data '{
  "network": "Tron",
  "asset": "USDT",
  "amount": "50.00",
  "destination_address": "TQ9ExampleDestinationAddress123456789",
  "idempotency_key": "withdraw_001",
  "note": "Manual withdrawal from merchant UI"
}'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `request_id` | `string` | Обязательно | Идентификатор заявки на выплату. |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `amount` | `string` | Обязательно | Сумма > 0: для инвойса в currency; для выплаты в единицах asset, включая комиссию. Передавайте десятичной строкой. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `destination_address` | `string` | Обязательно | Адрес получателя в указанной сети. Проверяйте сеть до подписи. |
| `status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `idempotency_key` | `string` | Обязательно | Ваш постоянный идентификатор одной логической выплаты; повторно используйте при сверке. |
| `requested_via` | `string` | Обязательно | Requested Via |
| `requested_by_user_id` | `string / null` | Необязательно | Requested By User Id |
| `approved_by_user_id` | `string / null` | Необязательно | Approved By User Id |
| `rejected_by_user_id` | `string / null` | Необязательно | Rejected By User Id |
| `approved_payout_id` | `string / null` | Необязательно | Approved Payout Id |
| `approved_payout_status` | `string / null` | Необязательно | Approved Payout Status |
| `rejection_reason` | `string / null` | Необязательно | Причина отказа; входит в подписываемое сообщение без изменения. |
| `note` | `string / null` | Необязательно | Необязательное пояснение к заявке. |
| `created_at` | `string` | Обязательно | Created At формат: date-time |
| `decided_at` | `string / null` | Необязательно | Decided At формат: date-time |

```json
{
  "request_id": "req_demo_001",
  "project_id": "project_demo_001",
  "network": "Tron",
  "asset": "USDT",
  "amount": "string",
  "destination_address": "TQ9ExampleDestinationAddress123456789",
  "status": "ok",
  "idempotency_key": "action_001",
  "requested_via": "string",
  "requested_by_user_id": "string",
  "approved_by_user_id": "string",
  "rejected_by_user_id": "string",
  "approved_payout_id": "payout_demo_001",
  "approved_payout_status": "string",
  "rejection_reason": "string",
  "note": "string",
  "created_at": "2026-07-13T12:00:00Z",
  "decided_at": "2026-07-13T12:00:00Z"
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `400` | Некорректный запрос или состояние | Проверьте detail, параметры, подпись и текущее состояние. Не повторяйте неизменённый запрос. |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `409` | Выплата пока недоступна | Проверьте error_code и доступный баланс. insufficient_project_reserve — недостаточен резерв; insufficient_aggregated_balance — средства ещё не готовы к отправке. Сначала сверьте состояние. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Payout availability conflict; inspect structured error fields`

## GET /api/v1/projects/{project_id}/payout-requests/by-idempotency/{idempotency_key}

Найти заявку по ключу повтора

Доступ: X-API-Key



### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `idempotency_key` | path · `string` | Обязательно | Ваш постоянный идентификатор одной логической выплаты; повторно используйте при сверке.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/payout-requests/by-idempotency/YOUR_IDEMPOTENCY_KEY' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `request_id` | `string` | Обязательно | Идентификатор заявки на выплату. |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `amount` | `string` | Обязательно | Сумма > 0: для инвойса в currency; для выплаты в единицах asset, включая комиссию. Передавайте десятичной строкой. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `destination_address` | `string` | Обязательно | Адрес получателя в указанной сети. Проверяйте сеть до подписи. |
| `status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `idempotency_key` | `string` | Обязательно | Ваш постоянный идентификатор одной логической выплаты; повторно используйте при сверке. |
| `requested_via` | `string` | Обязательно | Requested Via |
| `requested_by_user_id` | `string / null` | Необязательно | Requested By User Id |
| `approved_by_user_id` | `string / null` | Необязательно | Approved By User Id |
| `rejected_by_user_id` | `string / null` | Необязательно | Rejected By User Id |
| `approved_payout_id` | `string / null` | Необязательно | Approved Payout Id |
| `approved_payout_status` | `string / null` | Необязательно | Approved Payout Status |
| `rejection_reason` | `string / null` | Необязательно | Причина отказа; входит в подписываемое сообщение без изменения. |
| `note` | `string / null` | Необязательно | Необязательное пояснение к заявке. |
| `created_at` | `string` | Обязательно | Created At формат: date-time |
| `decided_at` | `string / null` | Необязательно | Decided At формат: date-time |

```json
{
  "request_id": "req_demo_001",
  "project_id": "project_demo_001",
  "network": "Tron",
  "asset": "USDT",
  "amount": "string",
  "destination_address": "TQ9ExampleDestinationAddress123456789",
  "status": "ok",
  "idempotency_key": "action_001",
  "requested_via": "string",
  "requested_by_user_id": "string",
  "approved_by_user_id": "string",
  "rejected_by_user_id": "string",
  "approved_payout_id": "payout_demo_001",
  "approved_payout_status": "string",
  "rejection_reason": "string",
  "note": "string",
  "created_at": "2026-07-13T12:00:00Z",
  "decided_at": "2026-07-13T12:00:00Z"
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Payout request not found`
- `Project API key is required`

## POST /api/v1/projects/{project_id}/payout-requests/{request_id}/approve

Подтвердить заявку

Доступ: X-API-Key + X-API-Secret

Нужны ключ API, секрет API и подпись Ed25519. Формат сообщения, UTC, nonce и окно в 5 минут описаны в разделе «Подписи».

Комиссия входит в amount. Принятие операции API не подтверждает отправку в блокчейн; отслеживайте состояние выплаты.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `request_id` | path · `string` | Обязательно | Идентификатор заявки на выплату.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |
| `X-API-Secret` | header | Обязательно | Секрет API этого ключа; требуется для записи. |

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `nonce` | `string` | Обязательно | Уникальное значение для новой попытки подписанного запроса; защищает от повтора подписи. мин. длина: 1; макс. длина: 255 |
| `timestamp` | `string` | Обязательно | UTC date-time в пределах ±5 минут. Подписывайте каноническую строку с +00:00; см. Подписи. формат: date-time |
| `signature` | `string` | Обязательно | Подпись Ed25519 канонического сообщения, 64 байта в Base64. мин. длина: 32 |

```bash
curl --request POST 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/payout-requests/YOUR_REQUEST_ID/approve' \
  --header "X-API-Key: $BITCOFY_API_KEY" \
  --header "X-API-Secret: $BITCOFY_API_SECRET" \
  --header 'Content-Type: application/json' \
  --data '{
  "nonce": "nonce_20260713_approve_001",
  "timestamp": "2026-07-13T12:00:00Z",
  "signature": "BASE64_ED25519_SIGNATURE"
}'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `request_id` | `string` | Обязательно | Идентификатор заявки на выплату. |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `amount` | `string` | Обязательно | Сумма > 0: для инвойса в currency; для выплаты в единицах asset, включая комиссию. Передавайте десятичной строкой. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `destination_address` | `string` | Обязательно | Адрес получателя в указанной сети. Проверяйте сеть до подписи. |
| `status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `idempotency_key` | `string` | Обязательно | Ваш постоянный идентификатор одной логической выплаты; повторно используйте при сверке. |
| `requested_via` | `string` | Обязательно | Requested Via |
| `requested_by_user_id` | `string / null` | Необязательно | Requested By User Id |
| `approved_by_user_id` | `string / null` | Необязательно | Approved By User Id |
| `rejected_by_user_id` | `string / null` | Необязательно | Rejected By User Id |
| `approved_payout_id` | `string / null` | Необязательно | Approved Payout Id |
| `approved_payout_status` | `string / null` | Необязательно | Approved Payout Status |
| `rejection_reason` | `string / null` | Необязательно | Причина отказа; входит в подписываемое сообщение без изменения. |
| `note` | `string / null` | Необязательно | Необязательное пояснение к заявке. |
| `created_at` | `string` | Обязательно | Created At формат: date-time |
| `decided_at` | `string / null` | Необязательно | Decided At формат: date-time |

```json
{
  "request_id": "req_demo_001",
  "project_id": "project_demo_001",
  "network": "Tron",
  "asset": "USDT",
  "amount": "string",
  "destination_address": "TQ9ExampleDestinationAddress123456789",
  "status": "ok",
  "idempotency_key": "action_001",
  "requested_via": "string",
  "requested_by_user_id": "string",
  "approved_by_user_id": "string",
  "rejected_by_user_id": "string",
  "approved_payout_id": "payout_demo_001",
  "approved_payout_status": "string",
  "rejection_reason": "string",
  "note": "string",
  "created_at": "2026-07-13T12:00:00Z",
  "decided_at": "2026-07-13T12:00:00Z"
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `400` | Некорректный запрос или состояние | Проверьте detail, параметры, подпись и текущее состояние. Не повторяйте неизменённый запрос. |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `409` | Выплата пока недоступна | Проверьте error_code и доступный баланс. insufficient_project_reserve — недостаточен резерв; insufficient_aggregated_balance — средства ещё не готовы к отправке. Сначала сверьте состояние. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Payout availability conflict; inspect structured error fields`

## POST /api/v1/projects/{project_id}/payout-requests/{request_id}/reject

Отклонить заявку

Доступ: X-API-Key + X-API-Secret

Нужны ключ API, секрет API и подпись Ed25519. Формат сообщения, UTC, nonce и окно в 5 минут описаны в разделе «Подписи».

Комиссия входит в amount. Принятие операции API не подтверждает отправку в блокчейн; отслеживайте состояние выплаты.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `request_id` | path · `string` | Обязательно | Идентификатор заявки на выплату.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |
| `X-API-Secret` | header | Обязательно | Секрет API этого ключа; требуется для записи. |

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `nonce` | `string` | Обязательно | Уникальное значение для новой попытки подписанного запроса; защищает от повтора подписи. мин. длина: 1; макс. длина: 255 |
| `timestamp` | `string` | Обязательно | UTC date-time в пределах ±5 минут. Подписывайте каноническую строку с +00:00; см. Подписи. формат: date-time |
| `signature` | `string` | Обязательно | Подпись Ed25519 канонического сообщения, 64 байта в Base64. мин. длина: 32 |
| `rejection_reason` | `string` | Обязательно | Причина отказа; входит в подписываемое сообщение без изменения. мин. длина: 1; макс. длина: 500 |

```bash
curl --request POST 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/payout-requests/YOUR_REQUEST_ID/reject' \
  --header "X-API-Key: $BITCOFY_API_KEY" \
  --header "X-API-Secret: $BITCOFY_API_SECRET" \
  --header 'Content-Type: application/json' \
  --data '{
  "nonce": "nonce_20260713_reject_001",
  "timestamp": "2026-07-13T12:00:00Z",
  "signature": "BASE64_ED25519_SIGNATURE",
  "rejection_reason": "KYC check failed"
}'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `request_id` | `string` | Обязательно | Идентификатор заявки на выплату. |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `amount` | `string` | Обязательно | Сумма > 0: для инвойса в currency; для выплаты в единицах asset, включая комиссию. Передавайте десятичной строкой. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `destination_address` | `string` | Обязательно | Адрес получателя в указанной сети. Проверяйте сеть до подписи. |
| `status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `idempotency_key` | `string` | Обязательно | Ваш постоянный идентификатор одной логической выплаты; повторно используйте при сверке. |
| `requested_via` | `string` | Обязательно | Requested Via |
| `requested_by_user_id` | `string / null` | Необязательно | Requested By User Id |
| `approved_by_user_id` | `string / null` | Необязательно | Approved By User Id |
| `rejected_by_user_id` | `string / null` | Необязательно | Rejected By User Id |
| `approved_payout_id` | `string / null` | Необязательно | Approved Payout Id |
| `approved_payout_status` | `string / null` | Необязательно | Approved Payout Status |
| `rejection_reason` | `string / null` | Необязательно | Причина отказа; входит в подписываемое сообщение без изменения. |
| `note` | `string / null` | Необязательно | Необязательное пояснение к заявке. |
| `created_at` | `string` | Обязательно | Created At формат: date-time |
| `decided_at` | `string / null` | Необязательно | Decided At формат: date-time |

```json
{
  "request_id": "req_demo_001",
  "project_id": "project_demo_001",
  "network": "Tron",
  "asset": "USDT",
  "amount": "string",
  "destination_address": "TQ9ExampleDestinationAddress123456789",
  "status": "ok",
  "idempotency_key": "action_001",
  "requested_via": "string",
  "requested_by_user_id": "string",
  "approved_by_user_id": "string",
  "rejected_by_user_id": "string",
  "approved_payout_id": "payout_demo_001",
  "approved_payout_status": "string",
  "rejection_reason": "string",
  "note": "string",
  "created_at": "2026-07-13T12:00:00Z",
  "decided_at": "2026-07-13T12:00:00Z"
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `400` | Некорректный запрос или состояние | Проверьте detail, параметры, подпись и текущее состояние. Не повторяйте неизменённый запрос. |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`

## POST /api/v1/payouts

Создать подписанную выплату

Доступ: X-API-Key + X-API-Secret

Нужны ключ API, секрет API и подпись Ed25519. Формат сообщения, UTC, nonce и окно в 5 минут описаны в разделе «Подписи».

Комиссия входит в amount. Принятие операции API не подтверждает отправку в блокчейн; отслеживайте состояние выплаты.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |
| `X-API-Secret` | header | Обязательно | Секрет API этого ключа; требуется для записи. |

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `amount` | `number / string` | Обязательно | Сумма > 0: для инвойса в currency; для выплаты в единицах asset, включая комиссию. Передавайте десятичной строкой. >: 0; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `destination_address` | `string` | Обязательно | Адрес получателя в указанной сети. Проверяйте сеть до подписи. |
| `idempotency_key` | `string` | Обязательно | Ваш постоянный идентификатор одной логической выплаты; повторно используйте при сверке. |
| `nonce` | `string` | Обязательно | Уникальное значение для новой попытки подписанного запроса; защищает от повтора подписи. |
| `timestamp` | `string` | Обязательно | UTC date-time в пределах ±5 минут. Подписывайте каноническую строку с +00:00; см. Подписи. формат: date-time |
| `signature` | `string` | Обязательно | Подпись Ed25519 канонического сообщения, 64 байта в Base64. мин. длина: 32 |

```bash
curl --request POST 'https://pay.bitcofy.pro/api/v1/payouts' \
  --header "X-API-Key: $BITCOFY_API_KEY" \
  --header "X-API-Secret: $BITCOFY_API_SECRET" \
  --header 'Content-Type: application/json' \
  --data '{
  "project_id": "project_demo_001",
  "network": "Tron",
  "asset": "USDT",
  "amount": "25.00",
  "destination_address": "TQ9ExampleDestinationAddress123456789",
  "idempotency_key": "payout_001",
  "nonce": "nonce_20260713_001",
  "timestamp": "2026-07-13T12:00:00Z",
  "signature": "BASE64_ED25519_SIGNATURE"
}'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `payout_id` | `string` | Обязательно | Идентификатор выплаты. |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `request_id` | `string / null` | Необязательно | Идентификатор заявки на выплату. |
| `note` | `string / null` | Необязательно | Необязательное пояснение к заявке. |
| `operational_expense` | `boolean / null` | Необязательно | Operational Expense |
| `source_scope` | `string / null` | Необязательно | Source Scope |
| `network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `amount` | `string` | Обязательно | Сумма > 0: для инвойса в currency; для выплаты в единицах asset, включая комиссию. Передавайте десятичной строкой. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `gross_amount` | `string / null` | Необязательно | Gross Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `net_amount` | `string / null` | Необязательно | Net Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `fee_amount` | `string` | Необязательно | Fee Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `provider_fee_amount` | `string` | Необязательно | Provider Fee Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `total_reserved` | `string / null` | Необязательно | Total Reserved шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `destination_address` | `string` | Обязательно | Адрес получателя в указанной сети. Проверяйте сеть до подписи. |
| `status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `provider_status` | `string / null` | Необязательно | Provider Status |
| `final` | `boolean` | Необязательно | Final по умолчанию: false |
| `funds_reserved` | `boolean` | Необязательно | Funds Reserved по умолчанию: false |
| `funds_released` | `boolean` | Необязательно | Funds Released по умолчанию: false |
| `idempotency_key` | `string` | Обязательно | Ваш постоянный идентификатор одной логической выплаты; повторно используйте при сверке. |
| `request_nonce` | `string` | Обязательно | Request Nonce |
| `request_timestamp` | `string` | Обязательно | Request Timestamp формат: date-time |
| `gas_mode` | `string / null` | Необязательно | Gas Mode |
| `rental_provider` | `string / null` | Необязательно | Rental Provider |
| `rental_order_id` | `string / null` | Необязательно | Rental Order Id |
| `gas_preparation_status` | `string / null` | Необязательно | Gas Preparation Status |
| `payout_submitted_fee_native` | `string / null` | Необязательно | Payout Submitted Fee Native шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payout_actual_fee_native` | `string / null` | Необязательно | Payout Actual Fee Native шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payout_gas_fee_source` | `string / null` | Необязательно | Payout Gas Fee Source |
| `payout_native_required_amount` | `string / null` | Необязательно | Payout Native Required Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payout_native_current_balance` | `string / null` | Необязательно | Payout Native Current Balance шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `reserve_floor_reached_for_sweeps` | `boolean / null` | Необязательно | Reserve Floor Reached For Sweeps |
| `tx_hash` | `string / null` | Необязательно | Tx Hash |
| `explorer_url` | `string / null` | Необязательно | Explorer Url |
| `processed_at` | `string / null` | Необязательно | Processed At формат: date-time |
| `confirmed_at` | `string / null` | Необязательно | Confirmed At формат: date-time |
| `error_reason` | `string / null` | Необязательно | Error Reason |
| `status_history` | `array<object>` | Необязательно | Status History |
| `status_history[].status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `status_history[].provider_status` | `string / null` | Необязательно | Provider Status |
| `status_history[].event_type` | `string / null` | Необязательно | Event Type |
| `status_history[].final` | `boolean` | Необязательно | Final по умолчанию: false |
| `status_history[].at` | `string` | Обязательно | At формат: date-time |
| `status_history[].actor` | `string / null` | Необязательно | Actor |
| `status_history[].reason` | `string / null` | Необязательно | Reason |

```json
{
  "payout_id": "payout_demo_001",
  "project_id": "project_demo_001",
  "request_id": "req_demo_001",
  "note": "string",
  "operational_expense": false,
  "source_scope": "string",
  "network": "Tron",
  "asset": "USDT",
  "amount": "string",
  "gross_amount": "string",
  "net_amount": "string",
  "fee_amount": "0",
  "provider_fee_amount": "0",
  "total_reserved": "string",
  "destination_address": "TQ9ExampleDestinationAddress123456789",
  "status": "ok",
  "provider_status": "string",
  "final": false,
  "funds_reserved": false,
  "funds_released": false,
  "idempotency_key": "action_001",
  "request_nonce": "nonce_20260713_001",
  "request_timestamp": "2026-07-13T12:00:00Z",
  "gas_mode": "string",
  "rental_provider": "string",
  "rental_order_id": "order_1001",
  "gas_preparation_status": "string",
  "payout_submitted_fee_native": "string",
  "payout_actual_fee_native": "string",
  "payout_gas_fee_source": "string",
  "payout_native_required_amount": "string",
  "payout_native_current_balance": "string",
  "reserve_floor_reached_for_sweeps": false,
  "tx_hash": "0xabc123def456",
  "explorer_url": "string",
  "processed_at": "2026-07-13T12:00:00Z",
  "confirmed_at": "2026-07-13T12:00:00Z",
  "error_reason": "string",
  "status_history": [
    {
      "status": "ok",
      "provider_status": "string",
      "event_type": "string",
      "final": false,
      "at": "2026-07-13T12:00:00Z",
      "actor": "string",
      "reason": "string"
    }
  ]
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `400` | Некорректный запрос или состояние | Проверьте detail, параметры, подпись и текущее состояние. Не повторяйте неизменённый запрос. |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `409` | Выплата пока недоступна | Проверьте error_code и доступный баланс. insufficient_project_reserve — недостаточен резерв; insufficient_aggregated_balance — средства ещё не готовы к отправке. Сначала сверьте состояние. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Payout availability conflict; inspect structured error fields`

## GET /api/v1/payouts/{payout_id}

Получить выплату

Доступ: X-API-Key



### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `payout_id` | path · `string` | Обязательно | Идентификатор выплаты.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/payouts/YOUR_PAYOUT_ID' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `payout_id` | `string` | Обязательно | Идентификатор выплаты. |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `request_id` | `string / null` | Необязательно | Идентификатор заявки на выплату. |
| `note` | `string / null` | Необязательно | Необязательное пояснение к заявке. |
| `operational_expense` | `boolean / null` | Необязательно | Operational Expense |
| `source_scope` | `string / null` | Необязательно | Source Scope |
| `network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `amount` | `string` | Обязательно | Сумма > 0: для инвойса в currency; для выплаты в единицах asset, включая комиссию. Передавайте десятичной строкой. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `gross_amount` | `string / null` | Необязательно | Gross Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `net_amount` | `string / null` | Необязательно | Net Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `fee_amount` | `string` | Необязательно | Fee Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `provider_fee_amount` | `string` | Необязательно | Provider Fee Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `total_reserved` | `string / null` | Необязательно | Total Reserved шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `destination_address` | `string` | Обязательно | Адрес получателя в указанной сети. Проверяйте сеть до подписи. |
| `status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `provider_status` | `string / null` | Необязательно | Provider Status |
| `final` | `boolean` | Необязательно | Final по умолчанию: false |
| `funds_reserved` | `boolean` | Необязательно | Funds Reserved по умолчанию: false |
| `funds_released` | `boolean` | Необязательно | Funds Released по умолчанию: false |
| `idempotency_key` | `string` | Обязательно | Ваш постоянный идентификатор одной логической выплаты; повторно используйте при сверке. |
| `request_nonce` | `string` | Обязательно | Request Nonce |
| `request_timestamp` | `string` | Обязательно | Request Timestamp формат: date-time |
| `gas_mode` | `string / null` | Необязательно | Gas Mode |
| `rental_provider` | `string / null` | Необязательно | Rental Provider |
| `rental_order_id` | `string / null` | Необязательно | Rental Order Id |
| `gas_preparation_status` | `string / null` | Необязательно | Gas Preparation Status |
| `payout_submitted_fee_native` | `string / null` | Необязательно | Payout Submitted Fee Native шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payout_actual_fee_native` | `string / null` | Необязательно | Payout Actual Fee Native шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payout_gas_fee_source` | `string / null` | Необязательно | Payout Gas Fee Source |
| `payout_native_required_amount` | `string / null` | Необязательно | Payout Native Required Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payout_native_current_balance` | `string / null` | Необязательно | Payout Native Current Balance шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `reserve_floor_reached_for_sweeps` | `boolean / null` | Необязательно | Reserve Floor Reached For Sweeps |
| `tx_hash` | `string / null` | Необязательно | Tx Hash |
| `explorer_url` | `string / null` | Необязательно | Explorer Url |
| `processed_at` | `string / null` | Необязательно | Processed At формат: date-time |
| `confirmed_at` | `string / null` | Необязательно | Confirmed At формат: date-time |
| `error_reason` | `string / null` | Необязательно | Error Reason |
| `status_history` | `array<object>` | Необязательно | Status History |
| `status_history[].status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `status_history[].provider_status` | `string / null` | Необязательно | Provider Status |
| `status_history[].event_type` | `string / null` | Необязательно | Event Type |
| `status_history[].final` | `boolean` | Необязательно | Final по умолчанию: false |
| `status_history[].at` | `string` | Обязательно | At формат: date-time |
| `status_history[].actor` | `string / null` | Необязательно | Actor |
| `status_history[].reason` | `string / null` | Необязательно | Reason |

```json
{
  "payout_id": "payout_demo_001",
  "project_id": "project_demo_001",
  "request_id": "req_demo_001",
  "note": "string",
  "operational_expense": false,
  "source_scope": "string",
  "network": "Tron",
  "asset": "USDT",
  "amount": "string",
  "gross_amount": "string",
  "net_amount": "string",
  "fee_amount": "0",
  "provider_fee_amount": "0",
  "total_reserved": "string",
  "destination_address": "TQ9ExampleDestinationAddress123456789",
  "status": "ok",
  "provider_status": "string",
  "final": false,
  "funds_reserved": false,
  "funds_released": false,
  "idempotency_key": "action_001",
  "request_nonce": "nonce_20260713_001",
  "request_timestamp": "2026-07-13T12:00:00Z",
  "gas_mode": "string",
  "rental_provider": "string",
  "rental_order_id": "order_1001",
  "gas_preparation_status": "string",
  "payout_submitted_fee_native": "string",
  "payout_actual_fee_native": "string",
  "payout_gas_fee_source": "string",
  "payout_native_required_amount": "string",
  "payout_native_current_balance": "string",
  "reserve_floor_reached_for_sweeps": false,
  "tx_hash": "0xabc123def456",
  "explorer_url": "string",
  "processed_at": "2026-07-13T12:00:00Z",
  "confirmed_at": "2026-07-13T12:00:00Z",
  "error_reason": "string",
  "status_history": [
    {
      "status": "ok",
      "provider_status": "string",
      "event_type": "string",
      "final": false,
      "at": "2026-07-13T12:00:00Z",
      "actor": "string",
      "reason": "string"
    }
  ]
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Payout not found`
- `Project API key is required`

## GET /api/v1/projects/{project_id}/payouts/by-idempotency/{idempotency_key}

Найти выплату по ключу повтора

Доступ: X-API-Key



### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `idempotency_key` | path · `string` | Обязательно | Ваш постоянный идентификатор одной логической выплаты; повторно используйте при сверке.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/payouts/by-idempotency/YOUR_IDEMPOTENCY_KEY' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `payout_id` | `string` | Обязательно | Идентификатор выплаты. |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `request_id` | `string / null` | Необязательно | Идентификатор заявки на выплату. |
| `note` | `string / null` | Необязательно | Необязательное пояснение к заявке. |
| `operational_expense` | `boolean / null` | Необязательно | Operational Expense |
| `source_scope` | `string / null` | Необязательно | Source Scope |
| `network` | `string` | Обязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `asset` | `string` | Обязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `amount` | `string` | Обязательно | Сумма > 0: для инвойса в currency; для выплаты в единицах asset, включая комиссию. Передавайте десятичной строкой. шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `gross_amount` | `string / null` | Необязательно | Gross Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `net_amount` | `string / null` | Необязательно | Net Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `fee_amount` | `string` | Необязательно | Fee Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `provider_fee_amount` | `string` | Необязательно | Provider Fee Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `total_reserved` | `string / null` | Необязательно | Total Reserved шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `destination_address` | `string` | Обязательно | Адрес получателя в указанной сети. Проверяйте сеть до подписи. |
| `status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `provider_status` | `string / null` | Необязательно | Provider Status |
| `final` | `boolean` | Необязательно | Final по умолчанию: false |
| `funds_reserved` | `boolean` | Необязательно | Funds Reserved по умолчанию: false |
| `funds_released` | `boolean` | Необязательно | Funds Released по умолчанию: false |
| `idempotency_key` | `string` | Обязательно | Ваш постоянный идентификатор одной логической выплаты; повторно используйте при сверке. |
| `request_nonce` | `string` | Обязательно | Request Nonce |
| `request_timestamp` | `string` | Обязательно | Request Timestamp формат: date-time |
| `gas_mode` | `string / null` | Необязательно | Gas Mode |
| `rental_provider` | `string / null` | Необязательно | Rental Provider |
| `rental_order_id` | `string / null` | Необязательно | Rental Order Id |
| `gas_preparation_status` | `string / null` | Необязательно | Gas Preparation Status |
| `payout_submitted_fee_native` | `string / null` | Необязательно | Payout Submitted Fee Native шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payout_actual_fee_native` | `string / null` | Необязательно | Payout Actual Fee Native шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payout_gas_fee_source` | `string / null` | Необязательно | Payout Gas Fee Source |
| `payout_native_required_amount` | `string / null` | Необязательно | Payout Native Required Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payout_native_current_balance` | `string / null` | Необязательно | Payout Native Current Balance шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `reserve_floor_reached_for_sweeps` | `boolean / null` | Необязательно | Reserve Floor Reached For Sweeps |
| `tx_hash` | `string / null` | Необязательно | Tx Hash |
| `explorer_url` | `string / null` | Необязательно | Explorer Url |
| `processed_at` | `string / null` | Необязательно | Processed At формат: date-time |
| `confirmed_at` | `string / null` | Необязательно | Confirmed At формат: date-time |
| `error_reason` | `string / null` | Необязательно | Error Reason |
| `status_history` | `array<object>` | Необязательно | Status History |
| `status_history[].status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `status_history[].provider_status` | `string / null` | Необязательно | Provider Status |
| `status_history[].event_type` | `string / null` | Необязательно | Event Type |
| `status_history[].final` | `boolean` | Необязательно | Final по умолчанию: false |
| `status_history[].at` | `string` | Обязательно | At формат: date-time |
| `status_history[].actor` | `string / null` | Необязательно | Actor |
| `status_history[].reason` | `string / null` | Необязательно | Reason |

```json
{
  "payout_id": "payout_demo_001",
  "project_id": "project_demo_001",
  "request_id": "req_demo_001",
  "note": "string",
  "operational_expense": false,
  "source_scope": "string",
  "network": "Tron",
  "asset": "USDT",
  "amount": "string",
  "gross_amount": "string",
  "net_amount": "string",
  "fee_amount": "0",
  "provider_fee_amount": "0",
  "total_reserved": "string",
  "destination_address": "TQ9ExampleDestinationAddress123456789",
  "status": "ok",
  "provider_status": "string",
  "final": false,
  "funds_reserved": false,
  "funds_released": false,
  "idempotency_key": "action_001",
  "request_nonce": "nonce_20260713_001",
  "request_timestamp": "2026-07-13T12:00:00Z",
  "gas_mode": "string",
  "rental_provider": "string",
  "rental_order_id": "order_1001",
  "gas_preparation_status": "string",
  "payout_submitted_fee_native": "string",
  "payout_actual_fee_native": "string",
  "payout_gas_fee_source": "string",
  "payout_native_required_amount": "string",
  "payout_native_current_balance": "string",
  "reserve_floor_reached_for_sweeps": false,
  "tx_hash": "0xabc123def456",
  "explorer_url": "string",
  "processed_at": "2026-07-13T12:00:00Z",
  "confirmed_at": "2026-07-13T12:00:00Z",
  "error_reason": "string",
  "status_history": [
    {
      "status": "ok",
      "provider_status": "string",
      "event_type": "string",
      "final": false,
      "at": "2026-07-13T12:00:00Z",
      "actor": "string",
      "reason": "string"
    }
  ]
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Payout not found`
- `Project API key is required`

## GET /api/v1/projects/{project_id}/payouts/reconcile

Сверить состояние выплаты

Доступ: X-API-Key

Передайте ровно один параметр: request_id, payout_id или idempotency_key. Используйте после таймаута записи до новой попытки.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `request_id` | query · `string / null` | Необязательно | Идентификатор заявки на выплату. Передайте ровно один из трёх идентификаторов.  |
| `payout_id` | query · `string / null` | Необязательно | Идентификатор выплаты. Передайте ровно один из трёх идентификаторов.  |
| `idempotency_key` | query · `string / null` | Необязательно | Ваш постоянный идентификатор одной логической выплаты; повторно используйте при сверке. Передайте ровно один из трёх идентификаторов.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/payouts/reconcile?idempotency_key=YOUR_IDEMPOTENCY_KEY' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `query_type` | `string` | Обязательно | Query Type |
| `request_id` | `string / null` | Необязательно | Идентификатор заявки на выплату. Передайте ровно один из трёх идентификаторов. |
| `payout_id` | `string / null` | Необязательно | Идентификатор выплаты. Передайте ровно один из трёх идентификаторов. |
| `idempotency_key` | `string / null` | Необязательно | Ваш постоянный идентификатор одной логической выплаты; повторно используйте при сверке. Передайте ровно один из трёх идентификаторов. |
| `request_status` | `string / null` | Необязательно | Request Status |
| `payout_status` | `string / null` | Необязательно | Payout Status |
| `status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `provider_status` | `string / null` | Необязательно | Provider Status |
| `final` | `boolean` | Необязательно | Final по умолчанию: false |
| `funds_reserved` | `boolean` | Необязательно | Funds Reserved по умолчанию: false |
| `funds_released` | `boolean` | Необязательно | Funds Released по умолчанию: false |
| `network` | `string / null` | Необязательно | Код сети из /api/v1/public/networks. Для оплаты берите сеть из payment_options инвойса. |
| `asset` | `string / null` | Необязательно | Код актива (например USDT). Он должен быть доступен в выбранной сети и проекте. |
| `gross_amount` | `string / null` | Необязательно | Gross Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `fee_amount` | `string` | Необязательно | Fee Amount по умолчанию: "0"; шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `net_amount` | `string / null` | Необязательно | Net Amount шаблон: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `destination_address` | `string / null` | Необязательно | Адрес получателя в указанной сети. Проверяйте сеть до подписи. |
| `tx_hash` | `string / null` | Необязательно | Tx Hash |
| `explorer_url` | `string / null` | Необязательно | Explorer Url |
| `processed_at` | `string / null` | Необязательно | Processed At формат: date-time |
| `confirmed_at` | `string / null` | Необязательно | Confirmed At формат: date-time |
| `rejection_reason` | `string / null` | Необязательно | Причина отказа; входит в подписываемое сообщение без изменения. |
| `error_reason` | `string / null` | Необязательно | Error Reason |
| `status_history` | `array<object>` | Необязательно | Status History |
| `status_history[].status` | `string` | Обязательно | Состояние объекта; значения и действия описаны в разделе соответствующего сценария. |
| `status_history[].provider_status` | `string / null` | Необязательно | Provider Status |
| `status_history[].event_type` | `string / null` | Необязательно | Event Type |
| `status_history[].final` | `boolean` | Необязательно | Final по умолчанию: false |
| `status_history[].at` | `string` | Обязательно | At формат: date-time |
| `status_history[].actor` | `string / null` | Необязательно | Actor |
| `status_history[].reason` | `string / null` | Необязательно | Reason |

```json
{
  "project_id": "project_demo_001",
  "query_type": "string",
  "request_id": "req_demo_001",
  "payout_id": "payout_demo_001",
  "idempotency_key": "action_001",
  "request_status": "string",
  "payout_status": "string",
  "status": "ok",
  "provider_status": "string",
  "final": false,
  "funds_reserved": false,
  "funds_released": false,
  "network": "Tron",
  "asset": "USDT",
  "gross_amount": "string",
  "fee_amount": "0",
  "net_amount": "string",
  "destination_address": "TQ9ExampleDestinationAddress123456789",
  "tx_hash": "0xabc123def456",
  "explorer_url": "string",
  "processed_at": "2026-07-13T12:00:00Z",
  "confirmed_at": "2026-07-13T12:00:00Z",
  "rejection_reason": "string",
  "error_reason": "string",
  "status_history": [
    {
      "status": "ok",
      "provider_status": "string",
      "event_type": "string",
      "final": false,
      "at": "2026-07-13T12:00:00Z",
      "actor": "string",
      "reason": "string"
    }
  ]
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `400` | Некорректный запрос или состояние | Проверьте detail, параметры, подпись и текущее состояние. Не повторяйте неизменённый запрос. |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Provide exactly one of request_id, payout_id, or idempotency_key`
- `Payout not found`
- `Payout request not found`
- `Project API key is required`

## Уведомления

## POST /api/v1/projects/{project_id}/webhook/config

Настроить адрес webhook

Доступ: X-API-Key + X-API-Secret

Метод сохраняет webhook_url. Поле callback_secret оставлено для совместимости и не меняет секрет проекта.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |
| `X-API-Secret` | header | Обязательно | Секрет API этого ключа; требуется для записи. |

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `webhook_url` | `string` | Обязательно | Публичный HTTPS URL обработчика уведомлений; без логина/пароля в URL. |
| `callback_secret` | `string / null` | Необязательно | Поле совместимости: этот метод не меняет секрет подписи webhook; не передавайте его для ротации. мин. длина: 6 |

```bash
curl --request POST 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/webhook/config' \
  --header "X-API-Key: $BITCOFY_API_KEY" \
  --header "X-API-Secret: $BITCOFY_API_SECRET" \
  --header 'Content-Type: application/json' \
  --data '{
  "webhook_url": "https://merchant.example/webhooks/bitcofy"
}'
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API. |
| `webhook_url` | `string` | Обязательно | Публичный HTTPS URL обработчика уведомлений; без логина/пароля в URL. |
| `callback_secret_masked` | `string` | Обязательно | Callback Secret Masked |

```json
{
  "project_id": "project_demo_001",
  "webhook_url": "https://merchant.example/api/bitcofy/webhook",
  "callback_secret_masked": "secret_123456"
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `400` | Некорректный запрос или состояние | Проверьте detail, параметры, подпись и текущее состояние. Не повторяйте неизменённый запрос. |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Project not found`

## POST /api/v1/projects/{project_id}/webhook/test

Отправить тестовый webhook

Доступ: X-API-Key + X-API-Secret

Создаёт событие в очереди. Успешный ответ не означает, что ваш обработчик уже принял уведомление.

### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |
| `X-API-Secret` | header | Обязательно | Секрет API этого ключа; требуется для записи. |

Тело запроса не требуется.

```bash
curl --request POST 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/webhook/test' \
  --header "X-API-Key: $BITCOFY_API_KEY" \
  --header "X-API-Secret: $BITCOFY_API_SECRET"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `event_id` | `string` | Обязательно | Event Id |
| `event_type` | `string` | Обязательно | Event Type |
| `delivered` | `boolean` | Обязательно | Delivered |
| `dead` | `boolean` | Обязательно | Dead |
| `attempts` | `integer` | Обязательно | Attempts |
| `last_error` | `string / null` | Необязательно | Last Error |
| `last_response_status` | `integer / null` | Необязательно | Last Response Status |
| `next_attempt_at` | `string / null` | Необязательно | Next Attempt At формат: date-time |
| `delivered_at` | `string / null` | Необязательно | Delivered At формат: date-time |
| `payload` | `object` | Обязательно | Payload |

```json
{
  "event_id": "string",
  "event_type": "string",
  "delivered": false,
  "dead": false,
  "attempts": 1,
  "last_error": "string",
  "last_response_status": 1,
  "next_attempt_at": "2026-07-13T12:00:00Z",
  "delivered_at": "2026-07-13T12:00:00Z",
  "payload": {
    "example_key": "string"
  }
}
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `400` | Некорректный запрос или состояние | Проверьте detail, параметры, подпись и текущее состояние. Не повторяйте неизменённый запрос. |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `404` | Объект не найден | Проверьте идентификатор и проект. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Project not found`
- `Project webhook_url or callback_secret is not configured`

## GET /api/v1/projects/{project_id}/webhook/events

Журнал уведомлений

Доступ: X-API-Key



### Параметры

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `project_id` | path · `string` | Обязательно | Идентификатор проекта; должен принадлежать ключу API.  |
| `X-API-Key` | header | Обязательно* | Ключ проекта. Альтернатива: Authorization: Bearer <project_api_key>. |

Тело запроса не требуется.

```bash
curl --request GET 'https://pay.bitcofy.pro/api/v1/projects/YOUR_PROJECT_ID/webhook/events' \
  --header "X-API-Key: $BITCOFY_API_KEY"
```

### 200 · application/json

Иллюстрация структуры: значения приведены для примера; фактическое состояние может отличаться.

| Поле | Тип | Наличие | Значение и ограничения |
| --- | --- | --- | --- |
| `[].event_id` | `string` | Обязательно | Event Id |
| `[].event_type` | `string` | Обязательно | Event Type |
| `[].delivered` | `boolean` | Обязательно | Delivered |
| `[].dead` | `boolean` | Обязательно | Dead |
| `[].attempts` | `integer` | Обязательно | Attempts |
| `[].last_error` | `string / null` | Необязательно | Last Error |
| `[].last_response_status` | `integer / null` | Необязательно | Last Response Status |
| `[].next_attempt_at` | `string / null` | Необязательно | Next Attempt At формат: date-time |
| `[].delivered_at` | `string / null` | Необязательно | Delivered At формат: date-time |
| `[].payload` | `object` | Обязательно | Payload |

```json
[
  {
    "event_id": "string",
    "event_type": "string",
    "delivered": false,
    "dead": false,
    "attempts": 1,
    "last_error": "string",
    "last_response_status": 1,
    "next_attempt_at": "2026-07-13T12:00:00Z",
    "delivered_at": "2026-07-13T12:00:00Z",
    "payload": {
      "example_key": "string"
    }
  }
]
```

### Ошибки

Ошибки обработчика перечислены ниже. detail может зависеть от проверки и состояния; текст не является стабильным кодом ошибки. При 5xx результат записи может быть неизвестен — сначала сверьте операцию.

| HTTP | Что означает | Что делать |
| --- | --- | --- |
| `401` | Неверные реквизиты доступа | Проверьте ключ API, активность и секрет для записи. |
| `403` | Доступ запрещён | Проверьте принадлежность и активацию проекта; для сессии оплаты — cookie страницы инвойса. |
| `422` | Ошибка формата данных | detail содержит массив: loc — поле, msg — причина, type — код. Исправьте обязательные поля и типы. |
| `423` | Проект заблокирован | Проверьте активацию и ограничения проекта в кабинете. Повтор неизменённого запроса не поможет. |

- `API key does not have access to this project`
- `Project API key is required`
