Перейти к содержанию

Авторизация на выплатах

Данный документ описывает механизм авторизации API на выплатах.

🛠 Обязательные заголовки

Каждый HTTP-запрос должен содержать следующие заголовки:

Заголовок Описание Пример
X-Key-Id Идентификатор клиента. Значение можно получить в личном кабинете: в правом верхнем углу интерфейса ЛК. bd38fb26-673a-42aa-160c-cee751a185df
X-Timestamp Unix timestamp в секундах 1706800000
X-Signature Подпись запроса (SHA-256) 9c8f1d0a2d4e3a...

Требования к Timestamp

  • Должен быть в формате Unix timestamp (секунды)
  • Допустимое расхождение времени сервера и клиента: ±60 секунд

🔐 Алгоритм формирования подписи

Подпись формируется на основе алгоритма SHA-256. Весь процесс состоит из трех шагов.

Шаг 1. Хеширование токена

Сначала создается хеш вашего секретного ключа:

Text Only
token_hash = SHA256_HEX(token)

Результат: hex-строка длиной 64 символа.


Шаг 2. Формирование строки для подписи

Создайте строку message, объединив данные через разделитель :::

Text Only
message = timestamp + "::" + body + "::" + token_hash

Где:

  • timestamp — строка из заголовка X-Timestamp
  • body — точное тело HTTP-запроса (raw bytes). Если тела нет, используется пустая строка
  • token_hash — результат из Шага 1

⚠️ Важно Тело запроса должно полностью совпадать с тем, что отправляется. Любые лишние пробелы, переносы строк или форматирование JSON приведут к ошибке подписи.


Шаг 3. Вычисление итоговой подписи

Итоговое значение X-Signature — это хеш от строки message в нижнем регистре:

Text Only
X-Signature = SHA256_HEX(message)

🚫 Общие ошибки

  • Несоответствие body Подписывается одно тело запроса (например, отформатированное), а отправляется другое (сжатое)
  • Проблемы со временем Часы на клиенте не синхронизированы (расхождение более 60 секунд)
  • Старый подход Попытка передать Token в заголовках
  • Неверный секрет Использование X-Key-Id вместо секретного токена для генерации хеша

💻 Пример реализации (JavaScript / Postman)

Скрипт для использования в Pre-request Script в Postman:

JavaScript
// Функция для хеширования SHA-256
function sha256Hex(str) {
  return CryptoJS.SHA256(str).toString(CryptoJS.enc.Hex);
}

// 1. Получение переменных окружения
const token = pm.environment.get("token");      // Секретный токен
const keyId = pm.environment.get("x_key_id");   // X-Key-Id

if (!token || !keyId) {
  throw new Error("Missing environment variables (token or x_key_id)");
}

// 2. Генерация Timestamp (в секундах)
const timestamp = Math.floor(Date.now() / 1000).toString();

// 3. Подготовка Raw Body
let body = "";
if (pm.request.body && pm.request.body.mode === "raw") {
  body = pm.request.body.raw || "";
}

// 4. Шаг 1: Hash(token)
const tokenHash = sha256Hex(token);

// 5. Шаг 2 + 3: Signature = SHA256(timestamp :: body :: tokenHash)
const signingString = `${timestamp}::${body}::${tokenHash}`;
const signature = sha256Hex(signingString);

// 6. Установка заголовков
pm.request.headers.upsert({ key: "X-Key-Id", value: keyId });
pm.request.headers.upsert({ key: "X-Timestamp", value: timestamp });
pm.request.headers.upsert({ key: "X-Signature", value: signature });

// Debug
console.log("Signing String:", signingString);
console.log("Final Signature:", signature);