SafeMatch API
Публичное API платформы SafeMatch для P2P-обмена криптовалюты на фиат. Данный документ описывает все доступные методы для интеграции площадок с SafeMatch.
https://api.safematch.proСодержание
1. Аутентификация
Все запросы к API (кроме /health) требуют аутентификации. Для аутентификации используются три обязательных заголовка:
| Заголовок | Описание |
|---|---|
X-API-Key | Ваш API-ключ, выданный при регистрации |
X-Timestamp | Текущий UNIX-timestamp (секунды) |
X-Signature | HMAC-SHA256 подпись запроса |
Формирование подписи
Подпись формируется по следующему алгоритму:
- Составить строку для подписи:
HTTP_МЕТОД+ПУТЬ+TIMESTAMP+ТЕЛО_ЗАПРОСАHTTP_МЕТОД— метод запроса заглавными буквами (POST,GET,DELETE)ПУТЬ— путь запроса (например,/orders)TIMESTAMP— значение заголовкаX-TimestampТЕЛО_ЗАПРОСА— JSON-тело, сериализованное с отсортированными ключами и без пробелов (разделители:,и:). Для запросов без тела эта часть опускается
- Вычислить HMAC-SHA256 от полученной строки, используя ваш секретный ключ
- Результат передать в заголовке
X-Signatureв hex-формате
Пример (Python):
import hmac
import hashlib
import json
import time
api_key = "ваш-api-key"
secret_key = "ваш-secret-key"
method = "POST"
path = "/orders"
timestamp = str(int(time.time()))
body = {"side": "IN", "min_price": 90.0, "max_price": 95.0,
"fiat": "RUB", "token": "USDT", "fiat_qty": 10000}
body_str = json.dumps(body, sort_keys=True, separators=(",", ":"))
message = method + path + timestamp + body_str
signature = hmac.new(secret_key.encode(), message.encode(), hashlib.sha256).hexdigest()
headers = {
"X-API-Key": api_key,
"X-Timestamp": timestamp,
"X-Signature": signature,
"Content-Type": "application/json"
}
Для загрузки файлов (например, чек в формате PDF) подпись формируется аналогично, но тело запроса в подпись не включается — используется только МЕТОД + ПУТЬ + TIMESTAMP.
2. Управление заявками
Сводная таблица
| Метод | Путь | Описание |
|---|---|---|
POST | /orders | Создание заявки (IN или OUT) |
DELETE | /orders/{order_id} | Удаление заявки |
POST | /orders/{order_id}/receipt | Загрузка чека (PDF) |
POST | /orders/{order_id}/confirm-payment | Подтверждение получения оплаты |
POST | /orders/{order_id}/dispute-receipt | Оспаривание чека |
POST | /orders/{order_id}/cancel-search | Отмена поиска замены |
Создаёт новую заявку на покупку (IN) или продажу (OUT) криптовалюты.
Тело запроса (IN — покупка криптовалюты):
{
"side": "IN",
"min_price": 90.0,
"max_price": 95.0,
"fiat": "RUB",
"token": "USDT",
"fiat_qty": 10000
}
Тело запроса (OUT — продажа криптовалюты):
{
"side": "OUT",
"min_price": 90.0,
"max_price": 95.0,
"fiat": "RUB",
"token": "USDT",
"fiat_qty": 50000,
"max_payments": 3,
"banks": [
{
"bank_name": "Сбербанк",
"recipient_details": "2200 0000 0000 0000",
"recipient_name": "Иван Иванов",
"detail_type": "CARD",
"priority": 1
}
]
}
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
side | string | да | "IN" (покупка) или "OUT" (продажа) |
min_price | number | да | Минимальная цена (курс) |
max_price | number | да | Максимальная цена (курс) |
fiat | string | да | Фиатная валюта (например, "RUB") |
token | string | да | Криптовалюта (например, "USDT") |
fiat_qty | number | да | Сумма в фиатной валюте |
max_payments | number | только для OUT | Максимальное количество встречных платежей |
banks | array | только для OUT | Список банковских реквизитов |
client_data | object | нет | Данные клиента: name_ru, name_en, passport_series_number |
Объект banks[]:
| Поле | Тип | Описание |
|---|---|---|
bank_name | string | Название банка |
recipient_details | string | Реквизиты получателя (номер карты или телефон) |
recipient_name | string | Имя получателя |
detail_type | string | Тип реквизитов: "CARD" или "PHONE_NUMBER" |
priority | number | Приоритет (1 — наивысший) |
Успешный ответ:
{
"id": "a1b2c3d4-...",
"side": "IN",
"min_price": 90.0,
"max_price": 95.0,
"fiat": "RUB",
"token": "USDT",
"fiat_qty": 10000,
"max_payments": null,
"banks": null,
"status": "waiting",
"created_at": "2026-03-09T12:00:00"
}
Возможные ошибки:
| Ошибка | Причина |
|---|---|
| Недостаточно средств для заморозки | На счёте недостаточно криптовалюты для создания OUT-заявки |
| Недостаточно средств для комиссии | На счёте недостаточно средств для покрытия комиссии по IN-заявке |
| Торговля запрещена | Торговля заблокирована для данного аккаунта. Обратитесь к администратору |
| Превышен лимит апелляций | Слишком много апелляций в истории. Создание заявок временно заблокировано |
| Превышен лимит отмен | Слишком высокий процент отмен. Создание заявок заблокировано |
| Некорректная цена | Указано неверное значение цены |
Удаляет вашу заявку. Удаление возможно только для заявок в статусе «Ожидание сопоставления».
Параметры:
| Параметр | Тип | Где | Описание |
|---|---|---|---|
order_id | string | путь | ID заявки |
Успешный ответ:
{
"id": "a1b2c3d4-...",
"result": "success"
}
Возможные ошибки:
| Ошибка | Причина |
|---|---|
| Заявка не найдена | Заявка с указанным ID не существует |
| Нет доступа | Вы не являетесь создателем этой заявки |
| Нельзя удалить заявку в апелляции | Заявка находится в процессе рассмотрения апелляции |
| Неверный статус заявки | Заявку можно удалить только в статусе «Ожидание сопоставления» |
Загружает PDF-файл чека об оплате для IN-заявки (покупка). После загрузки заявка переходит в статус «Ожидание подтверждения» — продавец должен подтвердить получение средств.
Формат запроса: multipart/form-data
Параметры:
| Параметр | Тип | Где | Описание |
|---|---|---|---|
order_id | string | путь | ID заявки |
payment_method | number | query | Приоритет выбранного банка (из списка реквизитов продавца) |
receipt_file | file | тело | PDF-файл чека |
Успешный ответ:
{
"id": "a1b2c3d4-...",
"result": "success"
}
Возможные ошибки:
| Ошибка | Причина |
|---|---|
| Заявка не найдена | Заявка с указанным ID не существует |
| Нет доступа | Вы не являетесь создателем этой заявки |
| Неверный статус заявки | Загрузка чека возможна только в статусах «Ожидание оплаты», «Ожидание ручной проверки», «Ожидание нового чека» |
| Указанный банк не найден | Указан несуществующий приоритет банка |
| Пустой файл | Загружен пустой файл чека |
Создатель OUT-заявки (продавец) подтверждает, что получил фиатный перевод от покупателя. После подтверждения заявка покупателя завершается, криптовалюта зачисляется покупателю.
Параметры:
| Параметр | Тип | Где | Описание |
|---|---|---|---|
order_id | string | путь | ID IN-заявки, по которой подтверждается получение оплаты |
Успешный ответ:
{
"id": "a1b2c3d4-...",
"result": "success"
}
Возможные ошибки:
| Ошибка | Причина |
|---|---|
| Заявка не найдена | IN-заявка с указанным ID не существует |
| Это не IN-заявка | Указанная заявка не является заявкой на покупку |
| Заявка не сопоставлена | IN-заявка ещё не была сопоставлена с вашей OUT-заявкой |
| Нет доступа | Подтверждение доступно только создателю OUT-заявки |
| Неверный статус заявки | IN-заявка должна быть в статусе «Ожидание подтверждения» |
Создатель OUT-заявки (продавец) не подтверждает получение оплаты по загруженному чеку. Автоматически создаётся апелляция для разбирательства.
Параметры:
| Параметр | Тип | Где | Описание |
|---|---|---|---|
order_id | string | путь | ID IN-заявки, по которой оспаривается чек |
Тело запроса:
{
"reason": "check_not_confirmed",
"description": "Оплата не поступила на указанный счёт"
}
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
reason | string | да | Причина оспаривания |
description | string | нет | Дополнительное пояснение |
Допустимые причины (reason): check_not_confirmed
Успешный ответ:
{
"appeal_id": "appeal-uuid-...",
"order_id": "out-order-uuid-...",
"reason": "check_not_confirmed",
"status": "waiting_confirmation",
"created_at": "2026-03-09T12:00:00"
}
Возможные ошибки:
| Ошибка | Причина |
|---|---|
| Недопустимая причина | Указана причина, отсутствующая в списке допустимых |
| Заявка не найдена | IN-заявка с указанным ID не существует |
| Это не IN-заявка | Указанная заявка не является заявкой на покупку |
| Нет доступа | Оспаривание доступно только создателю OUT-заявки |
| Неверный статус заявки | IN-заявка должна быть в статусе «Ожидание подтверждения» |
| Заявка уже в апелляции | По данной заявке уже создана апелляция |
Если один из IN-ордеров в вашей OUT-заявке был отменён, система автоматически ищет замену. Этот метод позволяет отменить поиск замены и продолжить с текущими IN-заявками.
Параметры:
| Параметр | Тип | Где | Описание |
|---|---|---|---|
order_id | string | путь | ID OUT-заявки |
Успешный ответ:
{
"id": "a1b2c3d4-...",
"result": "success"
}
Возможные ошибки:
| Ошибка | Причина |
|---|---|
| Заявка не найдена | Заявка с указанным ID не существует |
| Только для OUT-заявок | Отмена поиска доступна только для заявок на продажу |
| Нет доступа | Вы не являетесь создателем этой заявки |
| Неверный статус заявки | Заявка должна быть в статусе «Поиск замены» |
3. Апелляции
Создаёт апелляцию по завершённой заявке. Доступно для обоих участников сделки (создатель IN и создатель OUT).
Тело запроса:
{
"order_id": "a1b2c3d4-...",
"reason": "no_money_in_account",
"description": "Средства не поступили на счёт в течение 2 часов"
}
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
order_id | string | да | ID заявки, по которой создаётся апелляция |
reason | string | да | Причина апелляции (из списка допустимых) |
description | string | нет | Подробное описание проблемы |
Допустимые причины для IN-заявок (покупка):
| Код | Описание |
|---|---|
no_money_in_account | Средства не поступили на счёт |
wrong_amount | Неверная сумма |
wrong_recipient | Неверный получатель |
payment_delayed | Задержка платежа |
Допустимые причины для OUT-заявок (продажа):
| Код | Описание |
|---|---|
no_crypto_received | Криптовалюта не получена |
wrong_crypto_amount | Неверная сумма криптовалюты |
transaction_failed | Ошибка транзакции |
delayed_transfer | Задержка перевода |
Успешный ответ:
{
"appeal_id": "appeal-uuid-...",
"order_id": "a1b2c3d4-...",
"reason": "no_money_in_account",
"status": "completed",
"created_at": "2026-03-09T12:00:00"
}
Возможные ошибки:
| Ошибка | Причина |
|---|---|
| Заявка не найдена | Заявка с указанным ID не существует |
| Заявка уже в апелляции | По данной заявке уже создана активная апелляция |
| Нет доступа | Вы не являетесь участником этой сделки |
| Заявка не завершена | Апелляции доступны только для завершённых заявок |
| Недопустимая причина | Указана причина, не входящая в список допустимых для данного типа заявки |
4. Получение данных
Возвращает подробную информацию о заявке. Доступно только участникам сделки (создатель или контрагент).
Параметры:
| Параметр | Тип | Где | Описание |
|---|---|---|---|
order_id | string | путь | ID заявки |
Успешный ответ:
{
"id": "a1b2c3d4-...",
"side": "IN",
"user_side": "IN",
"min_price": 90.0,
"max_price": 95.0,
"fiat_qty": 10000,
"fiat": "RUB",
"token": "USDT",
"max_payments": null,
"banks": [...],
"created_at": 1741510800,
"matched_at": 1741510860,
"status": "waiting_payment",
"creator_id": 1,
"contr_id": 2,
"rate": 92.5,
"in_orders_data": null,
"out_order_id": "out-uuid-...",
"receipt_data": null,
"payment_method": null,
"transfer_time": null,
"crypto_amount": 108.1,
"freezeed_crypto": null,
"fee_collected": 0.0,
"expected_fiat_qty": null,
"filled_fiat_qty": null
}
| Поле | Описание |
|---|---|
id | ID заявки |
side | Сторона заявки: IN (покупка) или OUT (продажа) |
user_side | Ваша роль в этой сделке: IN или OUT |
min_price, max_price | Диапазон цены (курса) |
fiat_qty | Сумма в фиатной валюте |
fiat, token | Валютная пара |
banks | Список банковских реквизитов |
created_at | Время создания (UNIX-timestamp) |
matched_at | Время сопоставления (UNIX-timestamp) |
status | Текущий статус заявки |
rate | Итоговый курс сделки |
crypto_amount | Сумма в криптовалюте |
receipt_data | Данные о загруженном чеке |
transfer_time | Время перевода в секундах (от сопоставления до загрузки чека) |
appeal_data | Данные об апелляции (если есть) |
fee_collected | Удержанная комиссия |
expected_fiat_qty | Ожидаемая сумма в фиате (для OUT) |
filled_fiat_qty | Полученная сумма в фиате (для OUT) |
Возвращает список ваших заявок с пагинацией, сортировкой и фильтрами.
Параметры (query):
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
page | number | 1 | Номер страницы |
page_size | number | 10 | Размер страницы (от 1 до 100) |
sort_by | string | created_at | Поле сортировки: created_at, min_price, max_price, fiat_qty, crypto_amount |
sort_order | string | desc | Порядок сортировки: asc или desc |
side | string | — | Фильтр по стороне: IN или OUT |
status | string | — | Фильтр по статусу заявки |
Успешный ответ:
{
"orders": [
{
"id": "a1b2c3d4-...",
"side": "IN",
"status": "waiting",
"fiat_qty": 10000,
"fiat": "RUB",
"token": "USDT",
"created_at": 1741510800,
...
}
],
"total_count": 42,
"page": 1,
"page_size": 10,
"total_pages": 5
}
5. Скачивание чека
Возвращает PDF-файл чека по его идентификатору. Доступно только участникам сделки.
Параметры:
| Параметр | Тип | Где | Описание |
|---|---|---|---|
receipt_id | string | путь | ID чека (без расширения .pdf) |
ID чека можно получить из поля receipt_data в данных заявки.
Ответ: PDF-файл (application/pdf).
Возможные ошибки:
| Ошибка | Причина |
|---|---|
| Чек не найден | Чек с указанным ID не существует |
| Нет доступа | Вы не являетесь участником сделки, к которой относится чек |
6. WebSocket-уведомления
Для получения уведомлений в реальном времени подключитесь к WebSocket-сервису по адресу wss://ws.safematch.pro. Документация по подключению доступна через GET /ws/docs.
Типы уведомлений:
| Тип | Описание |
|---|---|
order_created | Заявка создана |
order_matched | Заявка сопоставлена — получены реквизиты контрагента |
order_updated | Данные заявки обновлены (смена статуса или других параметров) |
order_completed | Заявка успешно завершена |
order_cancelled | Заявка отменена |
order_supplemented | К OUT-заявке добавлена новая встречная IN-заявка |
balance_updated | Баланс изменён (зачисление, списание, заморозка, разморозка) |
Каждое уведомление содержит актуальные данные по заявке, включая статус, реквизиты и прочие параметры.
7. Статусы заявок
| Статус | Пользовательское название | Описание |
|---|---|---|
waiting | Ожидание сопоставления | Заявка размещена и ожидает встречную заявку |
waiting_payment | Ожидание оплаты | IN-заявка сопоставлена, покупатель должен выполнить перевод и загрузить чек |
waiting_payments | Ожидание поступлений | OUT-заявка сопоставлена, продавец ожидает переводы от покупателей |
waiting_confirmation | Ожидание подтверждения | Чек загружен, продавец должен подтвердить получение средств |
waiting_manual_approve | Ожидание ручной проверки | Чек требует ручной проверки |
waiting_new_receipt | Ожидание нового чека | Необходимо загрузить новый чек |
waiting_new_order | Поиск замены | Система ищет новую встречную IN-заявку взамен отменённой |
waiting_moderator | Ожидание модератора | Заявка ожидает решения модератора |
completed | Завершена | Заявка успешно завершена, средства зачислены |
cancelled_wrong_requisites | Отменена | Заявка отменена из-за несоответствия реквизитов |
in_appeal | В апелляции | Заявка находится в процессе рассмотрения апелляции |
8. Общие коды ответов
| Код | Описание |
|---|---|
200 | Запрос выполнен успешно |
400 | Ошибка в запросе (неверные данные, неподходящий статус заявки) |
401 | Ошибка аутентификации (неверный API-ключ, подпись или timestamp) |
403 | Доступ запрещён (нет прав на данное действие) |
404 | Ресурс не найден (заявка, чек) |
500 | Внутренняя ошибка сервера |