Подпись запросов
Подпись подтверждает подлинность запроса. Поддерживаются две версии алгоритма: 3 (по логину) и 4 (с привязкой к телу запроса).
Общие шаги
JSON API v3
Внутренний хеш
innerHash = lowercase(hmac_sha256(password, timestamp))password— секретный ключ мерчанта, хранится в настройках проекта на стороне платформы.login— значение заголовкаX-Login.timestamp— значение заголовкаX-Timestamp.
password — секрет. Он не передаётся в запросе, не логируется и не должен попадать в клиентский код: подпись считается только на сервере мерчанта.
Версия 3 — по логину
signature = lowercase(hmac_sha256(password, login + innerHash))Пример
password = "password"
login = "login"
timestamp = "2025-02-10T17:56:37Z"
innerHash = lowercase(hmac_sha256("password", "2025-02-10T17:56:37Z"))
signature = lowercase(hmac_sha256("password", "login" + innerHash))
→ "5f9e4f4a7a805b898cac96a6c3e7a81dd0e06e200c291d51663e6f250b10853f"Реализация подписи v3
Sandbox
curl
LOGIN=demo_login
PASSWORD=demo_password
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
INNER=$(printf '%s' "$TS" \
| openssl dgst -sha256 -hmac "$PASSWORD" | awk '{print $NF}')
SIG=$(printf '%s%s' "$LOGIN" "$INNER" \
| openssl dgst -sha256 -hmac "$PASSWORD" | awk '{print $NF}')Для версии 4 к сообщению добавляется requestPayload — та же функция, но подписывается requestPayload + login + innerHash.
Версия 4 — с привязкой к телу запроса
signature = lowercase(hmac_sha256(password, requestPayload + login + innerHash))requestPayload — детерминированная конкатенация значимых полей запроса без разделителей:
| Метод и путь | Payload |
|---|---|
POST /invoices | {order.merchant_order_id}{customerPayload}{order.price.amount}{order.price.currency}{contract.merchant_contract_id}{client_ip} |
POST /invoices/{id}/authorize | {invoice_id}{pin_code}{client_ip} |
POST /invoices/{id}/cancel | {invoice_id}{client_ip} |
POST /invoices/{id}/refund | {invoice_id}{client_ip} |
GET /invoices/{id} | {invoice_id} |
GET /invoices?merchant_order_id=... | {merchant_order_id} |
POST /contracts | {merchant_contract_id}{customerPayload}{pin_code}{client_ip} |
POST /contracts/{id}/authorize | {contract_id}{merchant_contract_id}{pin_code}{client_ip} |
POST /contracts/{id}/cancel | {contract_id}{merchant_contract_id}{client_ip} |
POST /billing/check | {customerPayload} |
customerPayload зависит от customer.:
| Тип | Payload |
|---|---|
mobile_phone | {msisdn} |
undefined_bank_card, bank_card | {source}{country}{merchant_customer_id}{email} |
| (иное / нет) | (пустая строка) |
Любое отсутствующее поле подставляется как пустая строка. ID счёта или контракта берётся из URL пути.