Аутентификация
Каждый запрос к API авторизуется секретным ключом проекта. Поддерживаются два способа: Bearer-токен (проще) и HMAC-подпись тела (привычна тем, кто мигрирует с других шлюзов).
API v1 · обновлено 2026-09-12
Ключи проекта
Ключи выпускаются на каждый проект отдельно в кабинете, раздел «API-ключи». Секретный ключ показывается один раз и хранится у нас только в виде SHA-256-хэша — восстановить его нельзя, только перевыпустить (с подтверждением паролем). После перевыпуска старый ключ перестаёт работать сразу.
| Значение | Формат | Секретность |
|---|---|---|
public_id | строка идентификатора проекта | Публичное: может встречаться в URL и телах запросов. |
secret_key | sk_live_… боевой, sk_test_… тестовый | Секрет. Только на сервере, только в переменных окружения. Никогда — в браузере, мобильном приложении или репозитории. |
webhook_secret | строка (раздел «Вебхуки» проекта) | Секрет. Секрет подписи проекта: им мы подписываем вебхуки вам, и им же вы подписываете запросы к API в режиме HMAC (см. ниже). |
Способ 1. Bearer-токен
Передайте секретный ключ в заголовке Authorization. Это рекомендуемый способ: он не требует вычисления подписи и работает с любым HTTP-клиентом.
Тип ключа определяет режим: sk_test_ создаёт счета в песочнице, sk_live_ — боевые. Тестовые и боевые счета не пересекаются.
Способ 2. Подпись HMAC-SHA256
Вместо передачи ключа в каждом запросе можно подписывать тело. Мы вычисляем HMAC-SHA256(timestamp + "." + rawBody, webhook_secret) и сравниваем с вашим значением в hex. Ключом подписи служит webhook_secret проекта — единственный секрет, который хранится у нас в открытом виде (секретный API-ключ хранится хэшем и для HMAC непригоден). Нужны три заголовка:
| Заголовок | Значение |
|---|---|
X-Public-Id | публичный ключ проекта pk_live_… / pk_test_… — по нему мы находим проект и режим. |
X-Timestamp | unix-время отправки запроса в секундах. Принимается в окне ±5 минут от времени сервера — синхронизируйте часы (NTP). |
X-Signature | HMAC-SHA256 от строки timestamp + "." + rawBody — значение X-Timestamp, точка и точная байтовая строка тела запроса — с ключом webhook_secret, в нижнем регистре hex. Для совместимости с кодом, написанным под другие шлюзы, подпись принимается и в заголовке Signature. |
Для GET-запросов без тела подписывается строка timestamp + "." (тело пустое). Подпись считается от того самого тела, которое уйдёт по сети: сериализуйте JSON один раз и отправляйте именно эту строку — переформатирование (пробелы, порядок ключей, экранирование юникода) изменит подпись.
Каждая подпись одноразовая: повтор того же запроса (метод, путь, X-Public-Id, X-Signature) в течение 10 минут отклоняется с 401 signature_invalid. Практически это значит: один и тот же GET-запрос — не чаще раза в секунду; для повторной отправки сформируйте новую подпись с текущим X-Timestamp.
Если в запросе есть и Authorization: Bearer, и X-Signature, используется Bearer.
Ошибки авторизации
401 unauthorized— заголовок отсутствует, ключ не найден или отозван.401 timestamp_invalid— нет заголовкаX-Timestamp, он не unix-секунды или отличается от времени сервера больше чем на 5 минут.401 signature_invalid—X-Signatureне совпала с HMAC отtimestamp + "." + body(чаще всего тело пересериализовано после подписи) либо подпись уже использовалась (повтор запроса).403 project_not_active— ключ верный, но проект заблокирован или ещё не прошёл модерацию (для боевых ключей).429 rate_limited— больше 60 запросов в секунду на ключ; в ответе естьRetry-After. Повторите с экспоненциальной задержкой.
Рекомендации по безопасности
- Храните ключи в переменных окружения или менеджере секретов; для тестового и боевого контура — раздельно.
- Вызывайте API только с сервера. Страница оплаты у нас размещённая (hosted), поэтому фронтенду ключи не нужны вовсе.
- При подозрении на утечку перевыпустите ключ в кабинете — это мгновенно и не затрагивает уже созданные счета.
- Ограничьте исходящие запросы к
payrapay.netтолько по HTTPS; HTTP-запросы отклоняются.