Skip to Content
Справочник APIАутентификация
View as Markdown

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

В InfraIO Pay есть два API-уровня с разными моделями аутентификации. Выбирайте тот, который соответствует вызывающей стороне:

УровеньПрефикс путиАудиторияАутентификация
Мерчантский B2B/b2b/v1/*Ваш серверПодпись запросов HMAC-SHA256
Панель управленияИспользуется панелью мерчантаБраузерные сессии для панели мерчантаBearer JWT

Эта страница описывает B2B-уровень — тот, который вы вызываете со своего сервера с парой API-ключей. Уровень панели управления используется панелью мерчанта InfraIO Pay и не является публичным интеграционным уровнем.

Всегда отправляйте полный путь вместе с префиксом /b2b и подписывайте этот же путь (см. ниже).

Endpoint’ы

ОкружениеBase URL
Тестовоеhttps://api-dev.infraio.xyz
Боевоеhttps://api.infraio.xyz

Шаблон URL тот же — окружение определяется по префиксу ключа (pk_test_… или pk_live_…), а не по URL.

Пара ключей

Из панели мерчанта вы получаете два значения (Developers → API keys → + Add key):

  • Publishable-ключ (pk_test_… или pk_live_…) — идентифицирует ваш аккаунт. Передаётся как X-Client-ID. Безопасно встраивать в ваш браузерный бандл (SDK уже это делает).
  • Secret-ключ (sk_test_… или sk_live_…) — ключ HMAC-подписи. Только серверный. Относитесь к нему как к паролю базы данных.

Если secret-ключ когда-либо попал в браузерный бандл, git-репозиторий, лог-строку или общий чат — немедленно отзовите его из панели. Отзыв мгновенный, окна перекрытия нет. Выпустите новый ключ и переразверните.

Подписание запроса

Каждый вызов /b2b/v1/* несёт три заголовка:

X-Client-ID: pk_live_70d0becbd7a53047b0dfe88a960d10ad X-Timestamp: 1715990400 X-Signature: 9a8b7c6d… (hex HMAC-SHA256)

Подпись вычисляется по канонической строке:

METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + BODY
  • METHOD — HTTP-глагол в верхнем регистре (POST, GET, …).
  • PATH — путь запроса включая префикс /b2b, без хоста и без query-строки (например, /b2b/v1/checkout-sessions/quick). Префикс должен присутствовать. Query-параметры не подписываются — для GET …?cursor=…&limit=20 подписывайте только путь, без части ?….
  • TIMESTAMP — unix-секунды как десятичная строка (например, "1715990400"), точно совпадающая с X-Timestamp.
  • BODY — сырые байты тела запроса. Пустая строка для GET/DELETE.

Подписывайте с помощью HMAC-SHA256 ключом secret, вывод hex:

import { createHmac } from "node:crypto"; function sign({ method, path, body, secret }: { method: string; path: string; body: string; secret: string; }) { const timestamp = Math.floor(Date.now() / 1000).toString(); const input = [method.toUpperCase(), path, timestamp, body].join("\n"); const signature = createHmac("sha256", secret).update(input).digest("hex"); return { timestamp, signature }; }

Почему HMAC, а не Bearer?

API на чистых Bearer-токенах отправляет ваш единственный секрет по сети при каждом запросе. Любой, кто получит лог одного прокси с TLS-терминацией, получает ключи от вашего аккаунта. Подпись HMAC означает, что секрет никогда не путешествует — только его производная подпись, одноразовая (привязанная к этому конкретному запросу и к этой конкретной минуте).

Компромисс: подпись нужно вычислять для каждого вызова. Серверного SDK пока нет, но хелпер выше занимает около 15 строк на каждом языке.

Допуск по времени

Допуск составляет ±5 минут (300 секунд). Запрос за пределами этого окна отклоняется с ошибкой 401 invalid_signature. Из этого следуют две вещи:

  1. Синхронизируйте часы сервера через NTP. Долгоживущий cron со смещёнными часами будет давать сбои время от времени.
  2. Не предвычисляйте и не ставьте подписи в очередь. Если запрос просидит в очереди повторов более 5 минут, его подпись истечёт.

Scope’ы ключей

Secret-ключи несут один или несколько из этих наборов scope’ов:

ScopeНазначение
readЧтение списков и единичных заказов, сессий, возвратов
write_orderСоздание сессий checkout, заказов
write_refundВыпуск возвратов, генерация refund-request token’ов
webhook_manageСоздание/обновление/удаление webhook-endpoint’ов

По умолчанию панель выдаёт ключ с «полным доступом» (все четыре scope’а). Вы можете выпустить ключ с ограниченным scope’ом из Developers → API keys → + Add key, отметив только те scope’ы, которые нужны интеграции.

Scope’ы пока не применяются. Scope’ы записываются на ключе и показываются в панели, но любой валидный ключ sk_… может вызвать любой endpoint /b2b/v1/* вашего мерчанта. Не полагайтесь на scope’ы как на границу безопасности. Для ограничения доступа используйте ротацию или отзыв ключей.

Неудачная проверка

Если подпись, X-Client-ID или временная метка недействительны, запрос отклоняется с 401 INVALID_SIGNATURE до того, как попадёт в API. Таким образом подписываются только запросы /b2b/v1/*. Webhooks используют отдельную схему (см. ниже).

Что дальше

  • Ошибки — форма ответа при 4xx/5xx.
  • Безопасность → API-ключи — ротация, отзыв, что делать, если секрет утёк.
  • Webhooks → Проверка подписи — использует другую схему HMAC (заголовок X-Signature: sha256=…, подписывает X-Timestamp + "." + raw_body плюс опциональный X-Signature-Prev в течение 24-часового grace-окна ротации). Не путайте схемы — алгоритм хэширования общий, но подписываемые байты и семейство секретов (whsec_… против sk_…) разные.