01 С чего начать
API OneSix позволяет принимать платежи через счета (invoice) и выводить средства (transfer) программно. Запросы авторизуются API-ключом проекта с HMAC-подписью.
Интеграция строится в три шага:
- Создайте проект в личном кабинете и подтвердите владение доменом (DNS).
- Получите API-ключ проекта: пару
id+secret. - Подписывайте запросы ключом (HMAC-SHA256) и вызывайте методы API.
Registration → Project (pending) → Domain verification → Moderation → Project (active) → API key → API requestsAPI-ключ начинает работать только когда и ключ, и проект находятся в статусе active. Пока проект на модерации (pending) или отклонён (rejected), запросы по ключу не проходят.
Форматы идентификаторов
| Сущность | Формат |
|---|---|
id проекта, счёта, API-ключа | UUID как есть (aabbccdd-...) |
user.id, logo_img_id, id свопа в conversions, id операции | Encoded string (как в остальном кабинете) |
02 Подпись запросов (HMAC)
Все запросы к публичному API авторизуются по API-ключу и подписываются алгоритмом HMAC-SHA256. Сессия (cookie / Authorization: Bearer) для API не используется.
Ключи
| Ключ | Где взять | Для чего |
|---|---|---|
id (X-API-Key-ID) | Кабинет → проект → API-ключи, поле id | Идентификатор ключа в заголовке |
key (secret) | Там же, поле key (hex, 64 символа) | Секрет для вычисления подписи |
У проекта один активный ключ (status: active). Ротации ключей пока нет. Секрет key возвращается методом GET /api/projects/{project_id}/api-keys/, храните его в безопасном месте.
Заголовки запроса
| Заголовок | Описание |
|---|---|
X-API-Key-ID | UUID ключа (поле id, не секрет) |
X-Timestamp | Unix timestamp в секундах. Окно ±15 секунд от серверного времени |
X-Signature | HMAC-SHA256 в hex |
Content-Type | application/json для запросов с телом |
Подпись обязательна для всех методов публичного API (GET и POST).
Алгоритм подписи
Шаг 1. Соберите объект данных:
{
"params": "url_encoded_query_string",
"body": {},
"path": "/api/invoice/"
}params: query-строка как в URL, без?(напримерproject_id=...&page=1). Для запроса без query это пустая строка"".body: распарсенный JSON тела запроса. Для GET-запросов без тела это пустой объект{}.path: путь запроса со слешами, включая префикс/api(например/api/invoice/).
Шаг 2. Сериализуйте объект строго с сортировкой ключей:
json.dumps(data, separators=(",", ":"), sort_keys=True)sort_keys=True обязателен. Подписывается объект после JSON-парсинга тела, а не сырая строка.
Шаг 3. Вычислите подпись:
payload = str(timestamp) + json_string
signature = HMAC-SHA256(key=secret, message=payload).hexdigest()Шаг 4. Передайте X-API-Key-ID, X-Timestamp, X-Signature в заголовках.
Важно
X-Timestampдолжен быть в пределах ±15 секунд от серверного времени. При расхождении часов синхронизируйтесь черезGET /api/-/time/.- Подпись одноразовая. Повтор того же
X-Signatureвернёт401 Signature already used!. Для каждого запроса нужны новый timestamp и новая подпись. - TOTP (2FA) на пути API не требуется.
- Если у ключа задан список разрешённых IP, запросы принимаются только с них.
Генерация подписи
import hmac, hashlib, json, time
def sign(secret: str, timestamp: int, data: dict) -> str:
s = json.dumps(data, separators=(",", ":"), sort_keys=True)
payload = f"{timestamp}{s}"
return hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()
secret = "<key>"
api_key_id = "<uuid>"
path = "/api/invoice/"
params = ""
body = {
"name": "Order 1",
"target_amount": 100,
"is_termless": True,
"is_payer_comission": True,
"description": "",
"private_description": "",
}
ts = int(time.time())
data = {"params": params, "body": body, "path": path}
signature = sign(secret, ts, data)
headers = {
"X-API-Key-ID": api_key_id,
"X-Timestamp": str(ts),
"X-Signature": signature,
"Content-Type": "application/json",
}В JS следите, чтобы JSON.stringify давал тот же результат, что и Python json.dumps(..., separators=(",",":"), sort_keys=True): без пробелов и с сортировкой ключей на всех уровнях. Для вложенных объектов в body при необходимости сортируйте ключи рекурсивно.
Примеры запросов
# params = "" (no query)
# body = {} (no body)
# path = "/api/invoice/my/<invoice_id>/"
# data = {"body":{},"params":"","path":"/api/invoice/my/<invoice_id>/"}
curl "https://devonesite.site/api/invoice/my/<invoice_id>/" \
-H "X-API-Key-ID: <UUID>" \
-H "X-Timestamp: 1718659200" \
-H "X-Signature: <hex>"Серверное время
/api/-/time/Без авторизацииСерверное время (unix)Возвращает текущее серверное время (unix, число). Используйте для синхронизации X-Timestamp, если часы клиента могут расходиться более чем на 15 секунд.
Какие методы принимают API-ключ
| Авторизация | Методы |
|---|---|
| API-ключ (HMAC) | POST /api/invoice/ · GET /api/invoice/my/{invoice_id}/ · POST /api/gw/transfer/ |
| Без авторизации | GET /api/invoice/{invoice_id}/ · GET /api/gw/currencies/ · GET /api/gw/currencies/rates/ · GET /api/gw/fees/ · GET /api/gw/fees/calculate/ · GET /api/-/time/ |
| Только сессия (кабинет) | Управление проектами, верификация, api-keys, operations, conversions, списки с project_id |
Любой метод вне списка «API-ключ (HMAC)» при вызове с ключом вернёт 401 API key not allowed for this endpoint!.
Ошибки подписи и авторизации
| Код 401, detail | Причина |
|---|---|
Invalid API key! | Неверный X-API-Key-ID |
API key deactivated! | Ключ архивирован или проект не active |
Invalid signature! | Подпись не сошлась (проверьте сериализацию, path, timestamp) |
Signature already used! | Повтор одноразовой подписи |
API key not allowed for this endpoint! | Метод не поддерживает авторизацию по ключу |
Token not provided! | Не передана авторизация |
03 Счета (Invoice)
Счёт - это запрос на оплату фиксированной суммы. После создания возвращается адрес для оплаты и платёжная страница. Сумма указывается в фиате (target_amount), оплата поступает в USDT по текущему курсу (rate_pair: USDT_RUB, rate приходит в ответе).
/api/invoice/API-ключСоздать счёт/api/invoice/my/{invoice_id}/API-ключСвой счёт (с private_description)/api/invoice/{invoice_id}/Без авторизацииПубличная страница счётаPOST /api/invoice/
Тело запроса (InvoiceCreateDTO)
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
name | string | ✔ | Название. Мин. 3 символа, латиница/кириллица |
target_amount | number | ✔ | Сумма к оплате. Минимум 0.1 |
is_termless | bool | Бессрочный счёт. По умолчанию false | |
deadline | datetime (ISO 8601) | Срок счёта. Обязателен при is_termless=false; при is_termless=true должен быть null или не передан | |
is_payer_comission | bool | Комиссию платит плательщик. По умолчанию true | |
description | string | Публичное описание | |
private_description | string | Приватное описание (видно только вам) | |
img | string | null | Изображение счёта | |
project_id | uuid | null | На этом методе не используется. По ключу project_id подставляется из проекта ключа автоматически |
По API-ключу 2FA не требуется.
Ответ (MyInvoiceDTO)
| Поле | Тип | Описание |
|---|---|---|
id | uuid | ID счёта |
address | string | Адрес для оплаты |
name | string | Название |
img | string | null | Изображение |
description | string | Публичное описание |
private_description | string | Приватное описание |
status | enum | opened / expired / executed / closed |
target_amount | number | Сумма к оплате |
current_amount | number | Оплачено на текущий момент |
comission | number | Комиссия |
is_termless | bool | Бессрочный |
is_payer_comission | bool | Комиссию платит плательщик |
deadline | datetime | null | Срок |
rate_pair | enum | Пара курса (USDT_RUB, ALTYN_USDT_RUB) |
rate | number | Курс на момент создания |
created_at | datetime | Дата создания |
closed_at | datetime | null | Дата закрытия |
project_id | uuid | null | Проект счёта |
GET /api/invoice/my/{invoice_id}/
Возвращает ваш счёт (MyInvoiceDTO, с private_description). По ключу действует дополнительный фильтр: доступны только счета проекта этого ключа.
GET /api/invoice/{invoice_id}/
Публичная страница счёта, без авторизации. Возвращает PublicInvoiceDTO: то же, что MyInvoiceDTO, но без private_description и project_id. Используется для платёжной страницы.
Статусы счёта
| status | Описание |
|---|---|
opened | Открыт, ожидает оплаты |
executed | Оплачен (сумма набрана) |
expired | Истёк срок без полной оплаты |
closed | Закрыт |
Отслеживание статуса. Исходящих вебхуков о смене статуса в текущей версии API нет. Актуальный статус запрашивайте опросом GET /api/invoice/my/{invoice_id}/ (status, current_amount).
04 Выводы (Transfer)
Создание вывода средств на внешний блокчейн-адрес.
/api/gw/transfer/API-ключСоздать выводPOST /api/gw/transfer/
Тело запроса (WithdrawalCreateDTO)
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
symbol_id | string | ✔ | Идентификатор символа (валюта в сети), например USDTTRC20. Список: GET /api/gw/currencies/ |
to_address | string | ✔ | Адрес получателя |
amount | number | ✔ | Сумма. Больше 0 |
По API-ключу 2FA не требуется.
Ответ: JSON-объект транзакции вывода (тип, статус, идентификатор операции).
Как и у счетов, вебхуков о завершении вывода нет. Отслеживайте статус опросом операций проекта (GET /api/projects/{project_id}/operations/) или в кабинете.
05 Справочные данные
Публичные методы без авторизации, полезные при интеграции.
/api/gw/currencies/Без авторизацииСписок валют и символов/api/gw/currencies/rates/Без авторизацииКурсы валютных пар/api/gw/fees/Без авторизацииКомиссии и лимиты по символам/api/gw/fees/calculate/Без авторизацииРасчёт комиссии по сумме/api/-/time/Без авторизацииСерверное время (unix)GET /api/gw/currencies/
Список поддерживаемых валют. Используйте поле symbol как значение symbol_id при создании вывода.
Query: search - фильтр. Ответ пагинированный (data[], pages_count, current_page, total).
Каждый элемент (CurrencyDTO):
| Поле | Описание |
|---|---|
symbol | Идентификатор символа для API (symbol_id) |
short_name | Краткое название валюты |
name | Полное название |
blockchain | Сеть (id, name, ссылки на explorer) |
contract_address | Адрес контракта токена, если есть |
precision | Точность |
is_active | Доступен ли символ |
logo_url | Логотип |
min_deposit_confirms / min_withdrawal_confirms | Подтверждений для депозита / вывода |
GET /api/gw/fees/
Комиссии и минимальные суммы по символам (GwFeeDTO[]):
| Поле | Описание |
|---|---|
symbol_id | Идентификатор символа |
min_deposit_amount | Минимальный депозит |
min_withdrawal_amount | Минимальный вывод |
deposit_fee_amount / deposit_fee_percentage | Комиссия депозита (фикс / процент) |
withdrawal_fee_amount / withdrawal_fee_percentage | Комиссия вывода (фикс / процент) |
swap_fee_amount / swap_fee_percentage | Комиссия конверсии |
swap_from_min_amount / swap_to_min_amount | Минимумы для конверсии |
GET /api/gw/fees/calculate/
Расчёт комиссии для конкретной суммы.
Query (все обязательны): amount, operation_type (deposit / withdrawal / swap), symbol_id.
Ответ (GwServiceFeeCalculationDTO): symbol_id, operation_type, amount, fee_amount, net_amount, gross_amount.
GET /api/gw/currencies/rates/
Курсы валютных пар (CurrencyRateDTO[]):
| Поле | Описание |
|---|---|
from_symbol_id | Символ/код исходной валюты |
to_symbol_name | Код валюты котировки |
value | Курс |
created_at | Время обновления |
06 Управление проектами
Создание и настройка проектов, верификация домена и выпуск ключей выполняются из личного кабинета по сессии (cookie или Authorization: Bearer), без API-ключа. Этот раздел нужен, если вы автоматизируете кабинет; для обычной интеграции достаточно пройти шаги в интерфейсе.
Проекты
/api/projects/СессияСписок своих проектов. Без status - все, кроме disabled. Фильтр ?status=pending|active|rejected|disabled/api/projects/СессияСоздать проект (статус pending). Ключ создаётся сразу, но в ответе его нет: берите через api-keys/api/projects/{project_id}/СессияКарточка проекта/api/projects/{project_id}/СессияИзменить проект (все поля необязательные). Нельзя править disabled/api/projects/{project_id}/СессияМягкое удаление → status: disabled. Ответ {"status": true}POST /api/projects/ (ProjectCreateDTO)
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
name | string | ✔ | 3-128 символов, уникально у пользователя |
category | enum | ✔ | goods / services / digital / other |
site_url | string (uri) | ✔ | http(s), публичный хост (не localhost и не приватный IP) |
contact_telegram | string | ✔ | 1-64 символа |
description | string | null | Описание |
PATCH /api/projects/{project_id}/ (ProjectUpdateDTO): category, description, logo_img_id (encoded id вашей картинки), brand_color (# + 6 hex). Логотип должен принадлежать вам.
Карточка проекта (ProjectDTO)
{
"id": "uuid",
"public_id": "aabbccddeeff",
"name": "Shop",
"status": "pending",
"category": "goods",
"site_url": "https://shop.example.com",
"contact_telegram": "@shop",
"description": null,
"logo_img_id": null,
"brand_color": null,
"is_site_verified": false,
"verify_method": null,
"verify_token": null,
"verified_at": null,
"rejected_reason": null,
"created_at": "...",
"updated_at": "..."
}status: pending → active (после верификации и одобрения модератором) / rejected / disabled.
Верификация домена (DNS)
/api/projects/{project_id}/verification/СессияНачать верификацию. Только при status=pending и is_site_verified=false/api/projects/{project_id}/verification/check/СессияПроверить TXT-запись (без тела)POST /verification/: тело {"method": "dns"}. Ответ:
{
"method": "dns",
"verify_token": "<hex>",
"instruction": "Add a TXT record for shop.example.com with value j1ulwfmkyj0-site-verification=<token>"
}Покажите пользователю: добавить TXT-запись на хост из site_url со значением j1ulwfmkyj0-site-verification=<verify_token>.
POST /verification/check/: если TXT найден, is_site_verified=true, заполняется verified_at, статус остаётся pending (ждёт модерацию). Если домен уже подтверждён, вернётся 200 без ошибки. Если TXT нет, вернётся 400 Site verification failed.
API-ключи проекта
/api/projects/{project_id}/api-keys/СессияКлючи проекта с секретом[
{
"id": "key uuid, this is X-API-Key-ID",
"key": "hex secret, 64 chars",
"status": "active",
"created_at": "...",
"archived_at": null
}
]status: active / archived. У проекта один активный ключ. Ротации пока нет.
Операции и конверсии проекта
/api/projects/{project_id}/operations/?page=1&per_page=10СессияТранзакции проекта/api/projects/{project_id}/conversions/?page=1&per_page=10СессияСвопы проектаПагинация: page с 1, per_page по умолчанию 10. В ответе current_page = page - 1 (с нуля), pages_count, total, data[].
Операция (ProjectAdminTransactionDTO): id, type, subject (usdt/rub), symbol_id, is_incoming, amount, state (created/pending/dirty_lock/executed/cancelled), tx_hash, description, executed_at, created_at, project_id.
Конверсия (SwapOrderResponseDTO): id, from_symbol_id, to_symbol_id, from_amount, to_amount, rate, status (created/processing/executed/cancelled/failed), created_at, project_id, user.
Списки в кабинете с фильтром проекта
GET /api/invoice/?project_id=<uuid>
GET /api/transaction/?project_id=<uuid>
GET /api/gw/swap_order/?project_id=<uuid>07 Коды ошибок
Проекты и верификация (400)
| detail | Причина |
|---|---|
Project with this name already exists | Имя проекта занято |
site_url must be an http(s) URL | Неверный формат URL |
site host must be a public address | Хост - localhost / приватный IP |
brand_color must be a HEX color like #1A2B3C | Неверный цвет |
Image not found | Картинка логотипа не найдена |
Project is disabled | Проект отключён, правка запрещена |
Project is not pending verification | Верификацию нельзя начать в текущем статусе |
Site is already verified | Домен уже подтверждён |
Verification is not started | Проверка до начала верификации |
Site verification failed | TXT-запись не найдена |
Project is not pending | Действие доступно только для pending |
Site is not verified | Домен не подтверждён |
Авторизация и подпись (401)
| detail | Причина |
|---|---|
Invalid API key! | Неверный X-API-Key-ID |
API key deactivated! | Ключ архивирован или проект не active |
Invalid signature! | Подпись не сошлась (проверьте сериализацию, path, timestamp) |
Signature already used! | Повтор одноразовой подписи |
API key not allowed for this endpoint! | Метод не поддерживает авторизацию по ключу |
Token not provided! | Не передана авторизация |
Не найдено (404)
| detail | Причина |
|---|---|
Project not found | Проект не найден / недоступен |
Invoice not found | Счёт не найден |