S
docs.syncra.money
API ReferenceMerchant API

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

Аутентификация запросов к Syncra Merchant API V2 с использованием HMAC-SHA256 подписей

Аутентификация запросов

Безопасность является главным приоритетом при взаимодействии с Syncra Merchant API V2. Все запросы к нашему программному интерфейсу должны проходить обязательную аутентификацию и проверку целостности данных. Это позволяет защитить вашу интеграцию от атак типа «человек посередине» (MITM), подделки параметров и повторного воспроизведения запросов (replay attacks).

Syncra V2 использует схему аутентификации на основе секретных токенов и криптографических подписей HMAC-SHA256.


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

Каждый HTTP-запрос к нашему API должен сопровождаться тремя обязательными заголовками:

Имя заголовкаТип значенияОписание
X-Merchant-TokenСтрока (64-char hex)Уникальный публичный токен идентификации мерчанта. Выдается в личном кабинете.
X-TimestampЦелое число (Unix Epoch)Текущее время выполнения запроса на стороне мерчанта (в секундах).
X-SignatureСтрокаВычисленная криптографическая подпись запроса. Формат: t={timestamp},v1={hmac_sha256_hex}.

Внимание: В отличие от устаревшей версии API V1, в которой заголовки имели имена MERCHANT и SIGNATURE без девелоперских префиксов, в API V2 используются исключительно заголовки с префиксом X-. Подписи вычисляются по алгоритму SHA256 вместо SHA512.


Алгоритм вычисления подписи

Для вычисления подписи вам потребуется ваш приватный Webhook Secret Key (также называемый секретом подписи), который выдается один раз в панели управления мерчанта.

Чтобы сгенерировать корректную подпись для отправки в заголовке X-Signature, выполните следующие шаги:

  1. Получите текущую метку времени: Получите текущее время в формате Unix timestamp (в секундах), например: 1783856120.
  2. Подготовьте тело запроса: Используйте в расчетах исходное сырое текстовое тело JSON-запроса (Raw Request Body) в том виде, в котором оно отправляется по сети. Пробелы, переводы строк и порядок полей имеют значение. Для запросов без тела (например, GET) используйте пустую строку "".
  3. Сформируйте полезную нагрузку (Payload): Объедините метку времени из шага 1 и сырое тело из шага 2 через символ точки (.). Формула: payload = timestamp + "." + raw_body Пример: 1783856120.{"amount":150000,"currency":"RUB"}
  4. Вычислите HMAC-SHA256: Используя ваш приватный секретный ключ (Webhook Secret Key) в качестве ключа подписи, вычислите HMAC-SHA256 от сформированной полезной нагрузки (Payload) из шага 3.
  5. Преобразуйте в Hex-строку: Полученный бинарный результат хэширования преобразуйте в шестнадцатеричную строку в нижнем регистре.
  6. Соберите итоговое значение заголовка: Сформируйте строку в формате: X-Signature: t={timestamp},v1={hex_signature}

Защита от Replay-атак: Сервер Syncra проверяет временной интервал между временем, указанным в заголовке X-Timestamp, и серверным системным временем. Если разница составляет более 5 минут (300 секунд), запрос отклоняется с кодом 401 Unauthenticated. Это предотвращает повторный перехват и отправку легитимных запросов злоумышленниками.


Примеры реализации на различных языках программирования

Ниже приведены готовые к копированию фрагменты кода на популярных языках программирования для генерации подписей.

const crypto = require('crypto');

function generateV2Signature(body, webhookSecret) {
  const timestamp = Math.floor(Date.now() / 1000).toString();
  const payload = `${timestamp}.${body}`;
  
  const signature = crypto
    .createHmac('sha256', webhookSecret)
    .update(payload)
    .digest('hex');
    
  return {
    'X-Merchant-Token': 'your_merchant_token_here',
    'X-Timestamp': timestamp,
    'X-Signature': `t=${timestamp},v1=${signature}`
  };
}
import time
import hmac
import hashlib

def generate_v2_signature(body_str: str, webhook_secret: str):
    timestamp = str(int(time.time()))
    payload = f"{timestamp}.{body_str}"
    
    signature = hmac.new(
        webhook_secret.encode('utf-8'),
        payload.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    
    return {
        'X-Merchant-Token': 'your_merchant_token_here',
        'X-Timestamp': timestamp,
        'X-Signature': f"t={timestamp},v1={signature}"
    }
<?php

function generateV2Signature($bodyStr, $webhookSecret) {
    $timestamp = (string)time();
    $payload = $timestamp . '.' . $bodyStr;
    
    $signature = hash_hmac('sha256', $payload, $webhookSecret);
    
    return [
        'X-Merchant-Token' => 'your_merchant_token_here',
        'X-Timestamp' => $timestamp,
        'X-Signature' => "t={$timestamp},v1={$signature}"
    ];
}
?>
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"strconv"
	"time"
)

func GenerateV2Signature(body []byte, secret []byte) map[string]string {
	timestamp := strconv.FormatInt(time.Now().Unix(), 10)
	payload := fmt.Sprintf("%s.%s", timestamp, string(body))

	mac := hmac.New(sha256.New, secret)
	mac.Write([]byte(payload))
	signature := hex.EncodeToString(mac.Sum(nil))

	return map[string]string{
		"X-Merchant-Token": "your_merchant_token_here",
		"X-Timestamp":      timestamp,
		"X-Signature":      fmt.Sprintf("t=%s,v1=%s", timestamp, signature),
	}
}

Таблица сравнения версий безопасности API

Для разработчиков, мигрирующих с legacy-системы V1, приведена таблица различий:

ПараметрУстаревшая система V1Новая система V2
Алгоритм хешированияHMAC-SHA512HMAC-SHA256
Входной формат подписиРазные строки per endpoint (например, ts;payin_id;salt)Единый формат timestamp.body для всех запросов
Идентификатор мерчантаMERCHANT header (GUID)X-Merchant-Token (64-char hex)
Передача подписиSIGNATURE header (raw hex)X-Signature header (t={ts},v1={hex})
Защита от replay-атакНет (или на стороне мерчанта по соли)Встроена на уровне шлюза (5 минут таймаут)
Заголовок времениПередается внутри формулы подписиОтдельный заголовок X-Timestamp

On this page