Модель ключа
- Один ключ — и приём, и выплаты. Отдельных ключей нет.
- Радиус поражения ограничен одним вашим мерчантом. Утёкший ключ не трогает чужие данные и баланс, но со своим балансом может сделать всё, включая вывод.
- За хранение ключа отвечаете вы.
1. Хранение секрета
- Секрет живёт только на сервере, в секрет‑хранилище (Vault, KMS, зашифрованные переменные окружения) — не в коде, не в репозитории, не в браузере, не в мобильном приложении.
Что за Vault/KMS? Это специальные хранилища секретов (например HashiCorp Vault или облачный
Key Management Service), которые держат ключи отдельно от кода и выдают их приложению по запросу.
На старте достаточно переменных окружения сервера — Vault/KMS подключают по мере роста, когда
секретов и людей становится больше.
- Подпись считается на бэкенде. Клиент никогда не видит
secret. - Секрет вебхука (
secretиз/v1/webhooks) — тоже секрет: храните так же.
2. IP‑allowlist
Ограничьте, с каких IP принимаются подписанные запросы. Когда список включён, запрос с чужого IP получает401 auth.ip_not_allowed, даже если подпись верна.
POST /v1/api-allowlist/*.
3. Ротация ключа
Ротация ключа не входит в публичный API. По подписанному запросу ключ ротировать нельзя — это
сделано специально, чтобы утёкший ключ не мог сам себя сменить и заблокировать владельца.
- Владелец мерчанта заходит в кабинет.
- Проходит подтверждение (2FA — двухфакторная аутентификация: помимо пароля вводится одноразовый код, например из приложения‑аутентификатора).
- Получает новый
public_id+secret(секрет показывается один раз).
Особенности денежных операций
- Выплаты по API‑ключу авто‑одобряются и уходят сразу — без белых списков и периодов выдержки, и
они необратимы. Валидируйте адрес получателя на своей стороне до вызова
/v1/payout. - Вывод из личного кошелька — только в кабинете под 2FA. На API‑ключе доступен лишь ввод средств В
личный кошелёк (
/v1/transfer/to-personal); вывод оттуда через API намеренно закрыт. - Идемпотентность обязательна. Отправляйте денежные запросы с HTTP‑заголовком
Idempotency-Key(одно значение на действие, неизменное во всех попытках) и задавайтеorder_id/reference(для выплат он обязателен). Это два независимых механизма защиты от дублей при ретраях: заголовок — на уровне транспорта,order_id— на уровне вашей бизнес‑логики. См. Идемпотентность.
Дополнительно
- Rate limit. При превышении —
429с телом{"state":1,"message":"rate limit exceeded"}и заголовкомRetry-After; подождите и повторяйте с backoff. → Ограничение частоты - Часы сервера. Держите время синхронизированным (NTP): подпись живёт в окне ±5 минут, при
расхождении сверка подписи не пройдёт и придёт
merchant.bad_signature(окно проверяется внутри проверки подписи). Кодauth.bad_timestamp— это только про отсутствующий или нечисловойX-Timestamp. - Мониторинг. Следите за балансом и статусами выплат; храните сопоставление
order_id↔ ваш заказ.