Finem документация API для мерчантов · v1

Приём криптоплатежей Finem

Finem принимает оплату в USDT (TRC-20, сеть TRON) по инвойсовой модели: вы создаёте инвойс через API, показываете покупателю ссылку на страницу оплаты, Finem отслеживает поступление в блокчейне и уведомляет вас вебхуком.

Как это работает

  1. Ваш сервер создаёт инвойс — POST /api/invoice — и получает paymentUrl.
  2. Покупатель переходит по paymentUrl: видит сумму в USDT, QR-код и адрес кошелька, отправляет перевод.
  3. Finem видит транзакцию в сети (статус Confirming), дожидается подтверждения и закрывает инвойс (Success).
  4. На каждую смену статуса вам уходит вебхук на urlCallback.

Аутентификация

Все запросы мерчанта подписываются заголовком X-API-KEY — ключ выдаётся вместе с аккаунтом и виден в панели (Settings). Ключ секретный: не публикуйте его в клиентском коде и репозиториях.

X-API-KEY: ваш-ключ-мерчанта

Создание инвойса

POST/api/invoice
ПолеТипОписание
amount обязательноеnumber Сумма в валюте currency. Больше нуля.
currency обязательноеstring Код валюты: фиат (RUB, KZT, …) или USDT. Фиат конвертируется в USDT по курсу на момент создания, курс фиксируется в инвойсе.
orderId обязательноеstring Идентификатор заказа в вашей системе. Ключ идемпотентности: повторный запрос с тем же orderId вернёт уже созданный инвойс, а не новый.
lifetimeint Срок жизни инвойса в секундах, 300–43200. По умолчанию 1800 (30 минут).
urlCallbackstring URL для вебхуков по этому инвойсу. Если не задан — берётся callback-адрес мерчанта из профиля.
urlSuccessstring Кнопка «Вернуться в магазин» на странице оплаты после успешной оплаты.
urlReturnstring Кнопка возврата при отмене или недоплате.
curl -X POST {baseUrl}/api/invoice \
  -H "X-API-KEY: <ключ>" -H "Content-Type: application/json" \
  -d '{
    "amount": 1000,
    "currency": "RUB",
    "orderId": "shop-order-482",
    "urlCallback": "https://shop.example/finem/hook",
    "urlSuccess": "https://shop.example/thanks"
  }'

Ответ:

{
  "orderId": 42,
  "merchantOrderId": "shop-order-482",
  "paymentUrl": "{baseUrl}/pay.html?pt=WtzAkHHVPP-RMV3lhpcazQ...",
  "walletAddress": "T...",
  "network": "TRC20",
  "amountUsdt": 10.53,
  "amountFiat": 1000,
  "currency": "RUB",
  "rate": 95,
  "status": "Pending",
  "expiresAt": "2026-07-05T12:00:00Z"
}

paymentUrl — ссылка для покупателя. amountUsdt — сумма, которую он должен отправить (страница оплаты показывает её сама).

Статус инвойса

GET/api/invoice/status?pt={token}

Публичный эндпоинт (без ключа): pt — токен из paymentUrl. Его же опрашивает страница оплаты. Удобен, чтобы сверить статус при получении вебхука.

{
  "orderId": 42,
  "status": "Success",
  "walletAddress": "T...",
  "network": "TRC20",
  "amountUsdt": 10.53,
  "amountFiat": 1000,
  "receivedUsdt": 12.0,
  "paidOver": true,
  "currency": "RUB",
  "expiresAt": "2026-07-05T12:00:00Z",
  "uiPollSeconds": 5,
  "urlSuccess": "https://shop.example/thanks",
  "urlReturn": null
}

Статусы и жизненный цикл

Основной путь: Pending → Confirming → Success. Терминальные статусы: Success, WrongAmount, Expired, Canceled.

СтатусЗначение
Pending Инвойс создан, ждём поступление в блокчейне.
Confirming Транзакция видна в сети, ждём подтверждения. Деньги ещё не зачислены. Обычно длится меньше минуты.
Success Оплачено и подтверждено сетью. receivedUsdt — фактически полученная сумма; при переплате в пределах допуска paidOver = true, зачисляется всё полученное.
WrongAmount Недоплата сверх допуска. Терминальный: инвойс закрыт, средства ожидают ручного разбора оператором. Покупатель видит «получена неполная сумма».
Expired Не оплачен в течение lifetime.
Canceled Отменён вручную оператором.
Подтверждение, пришедшее чуть позже дедлайна, не пропадает: если транзакция была видна в сети до истечения срока (Confirming), инвойс всё равно закроется в Success.

Допуски сумм

Сумма перевода сверяется с суммой инвойса. Значения по умолчанию (настраиваются на стороне Finem):

СитуацияПравило по умолчаниюРезультат
Недоплата «на комиссию» не больше 5 USDT и не больше 20% от суммы Success, зачисляется фактическая сумма
Переплата не больше 5 USDT Success, paidOver = true, зачисляется всё полученное
Недоплата сверх допуска получено ≥ 50% суммы WrongAmount, средства на ручном разборе
Прочее (слишком мало / слишком много) Инвойс остаётся активным, перевод уходит в очередь ручного разбора
Типичный случай недоплаты — биржа покупателя удержала комиссию вывода из суммы перевода. Учитывайте это в ценообразовании: допуск покрывает такие случаи автоматически.

Страница оплаты

paymentUrl ведёт на хостед-страницу Finem: сумма в USDT, QR-код (генерируется локально, адреса не передаются третьим сторонам), адрес кошелька с кнопкой копирования и таймер. Страница сама обновляет состояние: «платёж обнаружен, ждём подтверждения», «оплачено», «получена неполная сумма», «время истекло». Кнопки возврата берутся из urlSuccess / urlReturn.

POS-терминал

Альтернатива серверному API — публичная страница приёма оплаты без интеграции. Включается в панели мерчанта (Settings → «POS-терминал») и выдаёт постоянную ссылку с публичным токеном PosToken: он позволяет только создавать инвойсы в вашу пользу, доступа к данным или балансу не даёт.

Обычная ссылка

{baseUrl}/terminal.html?m={PosToken}

Покупатель сам вводит сумму и валюту, видит конвертацию в USDT и таймер актуальности курса (2 минуты), затем нажимает «Перейти к оплате» — инвойс создаётся тем же способом, что и через POST /api/invoice, и покупатель попадает на обычную страницу оплаты.

Ссылка с фиксированной суммой

Чтобы покупателю не приходилось вводить сумму — например, для ссылки на конкретный товар или готовый счёт — добавьте в ту же ссылку параметры amount и currency:

{baseUrl}/terminal.html?m={PosToken}&amount=1500&currency=RUB
ПараметрОписание
amountСумма в указанной валюте. Больше нуля.
currencyКод валюты — тот же список, что и при создании инвойса через API.

Поля суммы и валюты становятся нередактируемыми и уже заполнены переданными значениями, но форма, котировка в USDT и кнопка «Перейти к оплате» остаются видимыми — покупатель подтверждает переход сам. Такую ссылку можно собрать и прямо в панели мерчанта (Settings → «Ссылка с фиксированной суммой»).

Токен PosToken отзывается и перегенерируется мгновенно (кнопки «Перегенерировать» / «Выключить» в Settings) — старые ссылки терминала после этого перестают работать.

Вебхуки: формат и доставка

При каждой смене статуса Finem отправляет POST с JSON на urlCallback инвойса (или callback-адрес мерчанта, если у инвойса свой не задан):

{
  "orderId": 42,
  "merchantOrderId": "shop-order-482",
  "status": "Success",
  "amountUsdt": 10.53,
  "receivedUsdt": 10.53,
  "paidOver": false,
  "currency": "RUB",
  "txHash": "9df31a..."
}

Правила доставки:

Вебхуки пока не подписываются. До появления подписи рекомендуем при получении вебхука сверять статус запросом GET /api/invoice/status и не доверять только телу уведомления.

Переотправка вебхука

POST/api/invoice/resend-webhook

Ставит в очередь вебхук с текущим статусом инвойса — например, если ваш обработчик был недоступен дольше окна ретраев. Требует X-API-KEY.

{ "orderId": "shop-order-482" }   // ваш orderId из создания инвойса

Ответ 202 — поставлено в очередь; 400 — у инвойса нет callback-адреса; 404 — инвойс не найден.

Тестовый вебхук

POST/api/invoice/test-webhook

Для отладки обработчика: синхронно шлёт payload той же формы, что и боевой, с полем "test": true, и сразу возвращает результат. В очередь не пишется, ретраев нет. Требует X-API-KEY.

// запрос
{ "url": "https://shop.example/finem/hook", "status": "WrongAmount" }
// url необязателен (возьмётся callback мерчанта), status по умолчанию Success

// ответ
{ "delivered": true, "httpStatus": 200, "url": "https://shop.example/finem/hook" }

Ошибки

КодТелоПричина
401текстНет заголовка X-API-KEY или ключ неверный/неактивный.
400{"error":"invalid"}Сумма ≤ 0 или пустой orderId.
400{"error":"bad_currency"}Валюта не поддерживается / нет курса.
409{"error":"no_available_wallets"} Нет свободного кошелька под эту сумму — повторите позже или измените сумму на несколько USDT.
404Инвойс не найден (статус/переотправка).

Валюты и сеть

Приём — только USDT TRC-20 (сеть TRON). Валюта инвойса: USDT либо фиат — RUB, KZT, UZS, TJS, KGS, VND, PHP, GEL, IDR, MDL, THB (список расширяется). Курс фиксируется на момент создания инвойса и возвращается в поле rate.

Finem · документация API v1 · вопросы — вашему менеджеру