> For the complete documentation index, see [llms.txt](https://docs.esimpay.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.esimpay.net/autentifikaciya-i-bezopasnost.md).

# Аутентификация и безопасность

### ESIMPAY использует криптографическую аутентификацию на основе HMAC-SHA256.

### Обзор

Каждый запрос требует двух заголовков:

| Заголовок        | Назначение                            | Пример           |
| ---------------- | ------------------------------------- | ---------------- |
| `CF-MERCHANT-ID` | Идентификатор вашего мерчанта         | `merchant_12345` |
| `CF-ACCESS-SIGN` | HMAC-SHA256 подпись (только для POST) | `dGVzdA==`       |

### Получение учетных данных

1. Авторизуйтесь в личном кабинете ESIMPAY
2. Перейдите в раздел "API Keys"
3. Создайте новый ключ
4. Скопируйте:
   * `Merchant ID`
   * `API Secret`

{% hint style="warning" %}
**Важно**: Никогда не делитесь `API Secret`! Сохраняйте в переменных окружения.
{% endhint %}

### Генерирование подписи

#### Алгоритм

1. **Сериализация**
   * JSON с отсортированными ключами
   * Без пробелов (compact format)
   * UTF-8 кодировка
2. **Вычисление HMAC-SHA256**
   * Используйте API Secret как ключ
   * Используйте JSON как сообщение
3. **Base64 кодирование**
   * Результат в заголовок `CF-ACCESS-SIGN`

#### Пример на Python

```python
import json
import hmac
import hashlib
import base64

MERCHANT_ID = 'your_merchant_id'
API_SECRET = 'your_api_secret'

def sign_request(payload):
    """Генерирует подпись для запроса"""
    
    # Шаг 1: JSON с отсортированными ключами, без пробелов
    json_body = json.dumps(
        payload,
        separators=(',', ':'),      # {"a":1} не {"a": 1}
        ensure_ascii=False,         # UTF-8 как есть
        sort_keys=True,             # ОБЯЗАТЕЛЬНО!
    )
    
    # Шаг 2: HMAC-SHA256
    digest = hmac.new(
        API_SECRET.encode('utf-8'),
        json_body.encode('utf-8'),
        hashlib.sha256,
    ).digest()
    
    # Шаг 3: Base64
    signature = base64.b64encode(digest).decode('utf-8')
    
    return json_body, signature

# Использование
payload = {
    'orderId': 'order_abc123',
    'productId': 'b27bfd74-c46d-479c-b628-ec7ca69a146f',
    'activationMode': 'NOW',
}

json_body, signature = sign_request(payload)
print(f"JSON: {json_body}")
print(f"Signature: {signature}")
```

#### Пример на Node.js

```javascript
const crypto = require('crypto');

const MERCHANT_ID = 'your_merchant_id';
const API_SECRET = 'your_api_secret';

function signRequest(payload) {
    // Сортируем JSON
    const jsonBody = JSON.stringify(payload, Object.keys(payload).sort());
    
    // HMAC-SHA256
    const signature = crypto
        .createHmac('sha256', API_SECRET)
        .update(jsonBody, 'utf-8')
        .digest('base64');
    
    return { jsonBody, signature };
}

// Использование
const payload = {
    orderId: 'order_abc123',
    productId: 'b27bfd74-c46d-479c-b628-ec7ca69a146f',
    activationMode: 'NOW'
};

const { jsonBody, signature } = signRequest(payload);
console.log('JSON:', jsonBody);
console.log('Signature:', signature);
```

#### Пример на PHP

```php
<?php

function signRequest($payload) {
    $apiSecret = 'your_api_secret';
    
    // Сортируем и кодируем в JSON
    ksort($payload);
    $jsonBody = json_encode($payload, JSON_UNESCAPED_UNICODE);
    
    // HMAC-SHA256
    $signature = base64_encode(
        hash_hmac('sha256', $jsonBody, $apiSecret, true)
    );
    
    return [$jsonBody, $signature];
}

// Использование
$payload = [
    'orderId' => 'order_abc123',
    'productId' => 'b27bfd74-c46d-479c-b628-ec7ca69a146f',
    'activationMode' => 'NOW'
];

[$jsonBody, $signature] = signRequest($payload);
echo "JSON: $jsonBody\n";
echo "Signature: $signature\n";
```

### Полный пример с запросом

#### Python + requests

```python
import json
import hmac
import hashlib
import base64
import requests

MERCHANT_ID = 'your_merchant_id'
API_SECRET = 'your_api_secret'
BASE_URL = 'https://api.esimpay.net/api/v1'

def create_order(order_id, product_id):
    payload = {
        'orderId': order_id,
        'productId': product_id,
        'activationMode': 'NOW',
    }
    
    # Генерируем подпись
    json_body = json.dumps(
        payload,
        separators=(',', ':'),
        ensure_ascii=False,
        sort_keys=True,
    )
    
    signature = base64.b64encode(
        hmac.new(
            API_SECRET.encode('utf-8'),
            json_body.encode('utf-8'),
            hashlib.sha256,
        ).digest()
    ).decode('utf-8')
    
    # Отправляем запрос
    response = requests.post(
        f'{BASE_URL}/orders/submit',
        data=json_body,
        headers={
            'Content-Type': 'application/json',
            'CF-MERCHANT-ID': MERCHANT_ID,
            'CF-ACCESS-SIGN': signature,
        },
    )
    
    return response.json()

# Использование
result = create_order('order_123', 'b27bfd74-c46d-479c-b628-ec7ca69a146f')
print(json.dumps(result, indent=2))
```

### Лучшие практики безопасности

#### 1. Защита учетных данных

```python
import os
from dotenv import load_dotenv

load_dotenv()

MERCHANT_ID = os.getenv('ESIMPAY_MERCHANT_ID')
API_SECRET = os.getenv('ESIMPAY_API_SECRET')

if not MERCHANT_ID or not API_SECRET:
    raise ValueError("Missing ESIMPAY credentials")
```

#### 2. Никогда не коммитьте secrets

```bash
# .gitignore
.env
.env.local
secrets.txt
```

#### 3. Используйте HTTPS

Все запросы должны идти через HTTPS (не HTTP).

#### 4. Ротируйте ключи

Регулярно обновляйте API ключи (минимум раз в год).

### Типичные ошибки

#### ❌ Неправильно

```python
# Пробелы в JSON
json_body = json.dumps(payload)  # {"key": "value"}

# Не сортируем ключи
json_body = json.dumps(payload, sort_keys=False)

# Используем кодировку ASCII
json_body = json.dumps(payload, ensure_ascii=True)
```

#### ✅ Правильно

```python
# Compact JSON без пробелов, отсортированные ключи, UTF-8
json_body = json.dumps(
    payload,
    separators=(',', ':'),
    sort_keys=True,
    ensure_ascii=False,
)
```

### Отладка подписей

```python
# Отладочный скрипт
import json
import hmac
import hashlib
import base64

payload = {'orderId': 'test', 'productId': 'prod_id'}
api_secret = 'your_secret'

print("1. Original payload:")
print(json.dumps(payload, indent=2))

json_body = json.dumps(payload, separators=(',', ':'), sort_keys=True)
print(f"\n2. JSON body: {json_body}")

hmac_digest = hmac.new(
    api_secret.encode('utf-8'),
    json_body.encode('utf-8'),
    hashlib.sha256,
).digest()
print(f"\n3. HMAC hex: {hmac_digest.hex()}")

signature = base64.b64encode(hmac_digest).decode('utf-8')
print(f"\n4. Signature: {signature}")
```

***

**Готовы к интеграции? Смотрите примеры кода!**
