Роли
Оба — длинные секретные строки из настроек, но роли противоположные:
- API-ключ отвечает на вопрос «кто ко мне пришёл?» для ApiPay. Вы выставляете счёт → кладёте ключ в
X-API-Key→ мы понимаем, чья это организация. - Вебхук-секрет отвечает на тот же вопрос для вас. Мы присылаем вебхук об оплате → вы считаете HMAC от сырого тела запроса своим секретом → сверяете с заголовком
X-Webhook-Signature. Совпало — это точно ApiPay, а не злоумышленник, слепивший фейковый «paid».
Две зеркальные ошибки:
- Подписывают исходящие запросы секретом (кладут его в
X-API-Keyили городят HMAC на POST /invoices) → получают401. Ваши запросы к API подписывать не нужно — только ключ в заголовке. - Проверяют вебхук API-ключом → подпись «не сходится» при идеально правильном коде. HMAC считается от вебхук-секрета. Код проверки на Node/Python/PHP — в «Как настроить вебхуки ApiPay».
Где взять API-ключ
Кабинет apipay.kz → Настройки → «Подключение» → «Создать». Задаёте имя (уникально в пределах организации), опционально — webhook_url и срок действия. Полный ключ показывается только в этот момент — скопируйте в менеджер секретов/переменные окружения. Дальше в списке виден лишь key_hint — последние символы, чтобы отличать ключи друг от друга.
Ключ создаётся внутри организации. Нет организации — нет ключа (400 organization_required); ключ тестовой организации никогда не заработает с боевой — это разные организации с разными ключами.
Где взять вебхук-секрет
Секрет живёт на API-ключе. В кабинете кнопка генерации появляется только после того, как у ключа сохранён webhook_url, поэтому порядок такой:
- Откройте ключ в разделе Настройки → «Подключение».
- Впишите
webhook_url(публичный HTTPS постоянного домена вашего сервиса — не шортенер и не временная заглушка) и сохраните. - В блоке «Уведомления об оплатах» у поля «Секретный ключ» появится кнопка «Сгенерировать» — нажмите. Это и есть вебхук-секрет; показывается один раз.
Пока webhook_url не сохранён, кнопки нет.
Когда ключи «внезапно» перестают работать
Причины:
- Перегенерация.
regenerate(ключ) иregenerate-secret(секрет) мгновенно убивают старое значение. Если интеграций несколько — обновите значение во всех местах сразу. - Партнёрская повторная выдача. Партнёрский эндпоинт
POST /api/partner/organizations/{id}/api-keyидемпотентен: повторный вызов (например, «на всякий случай» после привязки кассира) перегенерирует ключ той же записи и заменяет её вебхук-настройки — старый ключ мгновенно мёртв. - Переход партнёра в рабочий режим.
PUT /api/partner/mode {"mode":"production"}удаляет тестовые организации и деактивирует их API-ключи; ключи для боевых организаций выпускаются заново. Тестовая организация архитектурно не может стать боевой, поэтому её ключи не «мигрируют». Подробнее о режимах — «Песочница и рабочий режим». - Флаг org-default перескочил. Если у организации не было org-default ключа, первый ключ с
webhook_urlстановится им автоматически; назначение org-default другому ключу снимает флаг с прежнего. На доставку вебхуков это влияет (org-default — второй получатель) — если вебхуки «переехали», проверьте, какой ключ сейчас default. - Организация переехала на другой аккаунт. Если тот же бизнес (тот же БИН) уже был заведён на другом аккаунте ApiPay и перенос подтверждён, организация переезжает вместе с данными, а все её прежние ключи гасятся: значение не меняется, ключ просто перестаёт действовать. Нужен новый ключ и заново указанные у него
webhook_urlи секрет. Обычное подключение кассира к своей же организации ключи не трогает.
Правила хранения (коротко и жёстко)
- Оба значения — только на сервере: переменные окружения или менеджер секретов. Никогда в клиентском JS, репозитории, скриншотах и чатах с поддержкой. ИИ-агенту достаточно сказать, что ключ лежит в переменной окружения
APIPAY_API_KEY. - Утечка ключа = кто угодно выставляет счета от вашего имени → немедленно
regenerate. - Утечка секрета = кто угодно подделывает вебхуки «оплачено» → немедленно
regenerate-secret. - Разные среды — разные ключи: тестовая организация со своим ключом, боевая со своим.
Вопросы и ответы
Обязателен ли вебхук-секрет?
Без секрета вебхуки доставляются, но заголовка X-Webhook-Signature не будет — подделать «paid» сможет кто угодно. Для рабочего режима секрет обязателен.
Можно ли иметь несколько API-ключей?
Да, в одной организации — несколько ключей (например, по ключу на систему), у каждого свой webhook_url и секрет. Учтите правило org-default: он — второй получатель вебхуков организации.
Чем отличается партнёрский ключ?
X-Partner-Key — отдельный server-to-server ключ партнёрского API; к мерчантским X-API-Key он отношения не имеет. Если вы обычный мерчант — вам нужен только X-API-Key.