DEVELOPER API · v1 · SANDBOX

Документация Nova Pay

Универсальная интеграция для интернет-магазинов, SaaS, игр, маркетплейсов и других цифровых продуктов: от создания счёта до безопасного webhook и выплаты партнёру.

Получить API-ключ
Sandbox без реальных средствВсе адреса начинаются с TEST_ONLY_. Не отправляйте на них криптовалюту.
Без доплаты для покупателяamount всегда равен expectedAmount. После AML сервис фиксирует 98% во внутреннем балансе партнёра, 2% — как комиссию Nova Pay. Сбор с депозитных адресов запускается только вручную.
00

Архитектура средств и баланса

При регистрации мерчант не получает блокчейн-кошелёк и не передаёт seed phrase. Для каждого счёта платформа выдаёт уникальный депозитный адрес под своим контролем. После AML 98% сразу появляются в ledger мерчанта, но сама криптовалюта не переводится с каждого адреса немедленно.

ДепозитAML98% / 2% ledgerочередьРучной сбор
  • Баланс ведётся отдельно по сети и активу: USDT TRC-20 не смешивается с USDT SPL.
  • Автоматическая консолидация отключена: сбор запускается только отдельным ручным действием.
  • Перед ручным запуском система проверяет, что комиссия Nova Pay покрывает сетевую стоимость с запасом.
  • В TRON используется центральный Energy-пул: ресурс делегируется депозитным адресам перед сбором.
  • Высокорисковый перевод остаётся на изолированном адресе, блокируется для вывода на 21 день и уходит на ручную проверку.
  • Мерчант может запросить вывод в любое время; на первом этапе заявка одобряется вручную.
01

Быстрый старт

  1. Зарегистрируйте проект и сохраните показанные один раз API key и webhook secret.
  2. В настройках укажите публичный HTTPS webhook URL.
  3. Создайте счёт через API и перенаправьте клиента на checkoutUrl.
  4. Меняйте заказ только после проверенного события invoice.paid.
  5. Сохраняйте X-Gateway-Delivery, чтобы не обработать повторную доставку дважды.
Ваш backendPOST /v1/invoicesHosted checkoutinvoice.paidВаш webhook
02

Авторизация

Передавайте API-ключ только с вашего backend. Не помещайте его в браузерный JavaScript, мобильное приложение или URL.

Authorization: Bearer np_test_...

Ключ можно перевыпустить в настройках. Старый ключ перестаёт работать сразу. Для каждого запроса создания требуется отдельный Idempotency-Key длиной 8–128 символов.

POST/v1/invoices

Создать счёт

curl -X POST https://gateway.kurazolotaya.site/v1/invoices \
  -H "Authorization: Bearer np_test_..." \
  -H "Idempotency-Key: order-1001-attempt-1" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "order-1001",
    "network": "TRON",
    "asset": "USDT",
    "amount": "10.50",
    "successUrl": "https://partner.example/payment/success",
    "failureUrl": "https://partner.example/payment/failed",
    "metadata": { "customerId": "42" }
  }'

Поля запроса

externalIdstring · requiredID заказа в вашей системе, до 100 символов.
networkenum · requiredTRON, SOLANA, ETHEREUM, BSC, POLYGON или TON.
assetenum · requiredНа первом этапе поддерживается USDT.
amountdecimal · requiredОт динамического минимума выбранной сети до 10 000, максимум 6 знаков после запятой.
successUrl / failureUrlURL · optionalСтраницы возврата пользователя.
metadataobject · optionalВаши служебные данные; не передавайте секреты.

Ответ 201

{
  "ok": true,
  "invoice": {
    "id": "inv_...",
    "externalId": "order-1001",
    "network": "TRON",
    "asset": "USDT",
    "merchantAmount": "10.500000",
    "networkFee": "0.000000",
    "expectedAmount": "10.500000",
    "minimumAmount": "1.000000",
    "collectionStrategy": "ENERGY_POOL_BATCH",
    "collectionProtected": true,
    "status": "PENDING",
    "depositAddress": "TEST_ONLY_TRON_...",
    "checkoutUrl": "https://gateway.kurazolotaya.site/pay/inv_...",
    "expiresAt": "2026-09-09T12:00:00.000Z"
  },
  "idempotentReplay": false
}
ИдемпотентностьПовтор с тем же ключом вернёт исходный счёт с HTTP 200 и idempotentReplay: true, даже если тело запроса изменилось.
GET/v1/invoices/{invoiceId}

Получить текущий статус

curl https://gateway.kurazolotaya.site/v1/invoices/inv_... \
  -H "Authorization: Bearer np_test_..."

Получить последние счета проекта: GET /v1/invoices?limit=50. API-ключ одного партнёра никогда не даёт доступ к счетам другого.

Публичная страница checkout доступна по /pay/{invoiceId}. Ограниченный публичный статус — /public/invoices/{invoiceId}.

TEST

Проверка сценариев в sandbox

Те же действия доступны кнопками в карточке счёта. Для автоматического теста используйте API:

POST /v1/sandbox/invoices/{id}/detect
{"amount":"10.50"}

POST /v1/sandbox/invoices/{id}/aml
{"decision":"CLEAR"}  // или BLOCKED

POST /v1/sandbox/invoices/{id}/settle
{}

Рекомендуемый тест: точная сумма → недоплата → доплата → переплата → AML block → просроченный платёж → повтор webhook. Sandbox-методы отсутствуют в production-контракте.

03

Подписанные webhook

Nova Pay отправляет JSON методом POST. Ответьте любым HTTP 2xx не позднее 7 секунд. При ошибке доставка повторяется с увеличивающейся задержкой, максимум 8 попыток.

X-Gateway-DeliveryУникальный ID доставки и ключ дедупликации.
X-Gateway-EventНапример, invoice.paid.
X-Gateway-TimestampUnix timestamp; рекомендуем окно не более 5 минут.
X-Gateway-Signaturev1=<hex HMAC-SHA256>.

Проверка подписи в Node.js

const crypto = require("node:crypto");

function verify(rawBody, headers, secret) {
  const timestamp = headers["x-gateway-timestamp"];
  const actual = headers["x-gateway-signature"];
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;

  const hex = crypto.createHmac("sha256", secret)
    .update(timestamp + "." + rawBody)
    .digest("hex");
  const expected = "v1=" + hex;
  const a = Buffer.from(actual || "");
  const b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Событие invoice.paid

{
  "id": "evt_...",
  "type": "invoice.paid",
  "createdAt": "2026-09-09T12:00:01.000Z",
  "data": { "invoice": { "id": "inv_...", "status": "PAID" } }
}
Правильный порядокСначала проверьте timestamp и HMAC по исходному телу, затем зафиксируйте delivery ID в уникальном поле и только после этого меняйте заказ.
04

Статусы счёта

PENDINGОжидается перевод.
PARTIALLY_PAIDНедоплата; зачисления нет.
AML_REVIEWСумма получена, вывод заблокирован до проверки.
AML_BLOCKEDВысокий риск; доступный баланс не создаётся.
PAIDAML пройден, 98% зачислены в ledger, сбор может ожидать пакета.
SETTLEDОнчейн-средства собраны в экономически безопасном пакете.
EXPIREDПять минут истекли, счёт закрыт.
LATE_PAYMENT_REVIEWПоздний перевод изолирован для ручного решения.
05

Динамический минимум и комиссии

  • merchantAmount = expectedAmount: клиент платит ровно сумму заказа, без доплаты Nova Pay.
  • networkFee для новых счетов равен нулю; кошелёк клиента оплачивает только свой обычный gas.
  • minimumAmount покрывает оценку одного исходящего сбора с конкретного депозитного адреса и запас 50%. Пакетная очередь не делит эту стоимость на число счетов.
  • Текущие защитные пороги: TRON — 18,75; Solana — 0,75; Ethereum — 225; BSC — 3,75; Polygon — 1,50; TON — 1,50 USDT. Перед mainnet они обновляются по реальной fee telemetry.
  • После AML 2% учитываются как комиссия Nova Pay, 98% — в partnerNet.
  • Автоматический сбор отключён. При ручном запуске система проверяет, что комиссия именно этого счёта покрывает сетевую стоимость с запасом.
  • Недоплата не создаёт доступный баланс; переплата отражается в overpaymentAmount.
  • Платёж после истечения срока не зачисляется автоматически.
!

HTTP-коды и ошибки

400Некорректное поле, сумма, сеть или Idempotency-Key.
401API-ключ отсутствует или недействителен.
404Счёт не найден либо принадлежит другому партнёру.
409Операция не разрешена в текущем статусе.
429Превышен лимит запросов.
5xxВременная ошибка; повторите запрос с тем же Idempotency-Key.
{
  "ok": false,
  "code": "invalid_amount",
  "error": "Сумма должна быть от 1 до 10000 USDT."
}
06

Чек-лист безопасности

  • Хранить API key и webhook secret только в Secret Manager или переменных backend.
  • Всегда использовать HTTPS и проверять подпись по сырому телу запроса.
  • Не выполнять зачисление по возврату пользователя на successUrl.
  • Доверять только событию invoice.paid после успешной HMAC-проверки.
  • Сделать обработчик транзакционным и идемпотентным.
  • При утечке немедленно перевыпустить ключи в кабинете.
Переход в productionПотребуются production RPC, AML-провайдер, HSM/Vault signer, gas station, подтверждение владения кошельками и реальные canary-платежи. Опубликованные ранее ключи использовать нельзя.