> Источник: https://apipay.kz/guides/api-klyuch-i-webhook-secret · Обновлено: 2026-07-06 · apipay.kz
> ApiPay — независимый сервис приёма платежей поверх вашего Kaspi Pay.

# API-ключ и вебхук-секрет ApiPay: в чём разница?

**TL;DR.** Это два разных credential'а с противоположными направлениями. **API-ключ** — ваш пропуск К нам: кладётся в заголовок `X-API-Key` каждого запроса к API (лимит 200 запросов/мин на ключ). **Вебхук-секрет** — проверка того, что К вам пришли действительно мы: им вы считаете HMAC-подпись входящего вебхука и сравниваете с заголовком `X-Webhook-Signature`; в запросах он **никогда не отправляется** — ни вами, ни нами. Оба показываются целиком **один раз** — при создании/генерации; дальше видна только маска (`key_hint`). Ключ жёстко привязан к организации: sandbox-ключи не работают с боевой организацией, а при переходе партнёра в рабочий режим тестовые организации удаляются вместе с ключами — это by design.

## Коротко

| | API-ключ | Вебхук-секрет |
|---|---|---|
| Направление | Ваши запросы → ApiPay | Вебхуки ApiPay → ваш сервер |
| Где используется | Заголовок `X-API-Key` в каждом запросе | Локальная проверка подписи `X-Webhook-Signature: sha256=<hex>` (HMAC-SHA256 по raw body) |
| Передаётся ли по сети | Да, в каждом вашем запросе | **Нет, никогда** — только результат HMAC |
| Где взять | Кабинет → Настройки → API-ключи → создать | Там же: после указания `webhook_url` появляется кнопка «Сгенерировать подпись» |
| Показывается целиком | Один раз при создании; потом `key_hint` (хвост) | Один раз при генерации; потом маска |
| Перегенерация | `regenerate` — старый ключ сразу мёртв | `regenerate-secret` — старый секрет сразу мёртв |
| Привязка | Жёстко к организации (`organization_id`) | К тому же API-ключу (пара «URL + секрет» живёт на ключе) |

## Почему их постоянно путают?

Потому что оба — «длинные секретные строки из настроек». Но роли противоположные:

- **API-ключ отвечает на вопрос «кто ко мне пришёл?» для ApiPay.** Вы выставляете счёт → кладёте ключ в `X-API-Key` → мы понимаем, чья это организация.
- **Вебхук-секрет отвечает на тот же вопрос для вас.** Мы присылаем вебхук об оплате → вы считаете HMAC от сырого тела запроса своим секретом → сверяете с заголовком `X-Webhook-Signature`. Совпало — это точно ApiPay, а не злоумышленник, слепивший фейковый «paid».

Две зеркальные ошибки из практики поддержки:

1. **Подписывают исходящие запросы секретом** (кладут его в `X-API-Key` или городят HMAC на POST /invoices) → получают `401`. Ваши запросы к API подписывать не нужно — только ключ в заголовке.
2. **Проверяют вебхук API-ключом** → подпись «не сходится» при идеально правильном коде. HMAC считается от вебхук-секрета. Код проверки на Node/Python/PHP — в «[Как настроить вебхуки ApiPay](/guides/nastroyka-webhookov-apipay)».

## Где взять API-ключ

Кабинет apipay.kz → **Настройки → API-ключи → «Создать»**. Задаёте имя (уникально в пределах организации), опционально — `webhook_url` и срок действия. Полный ключ показывается **только в этот момент** — скопируйте в менеджер секретов/переменные окружения. Дальше в списке виден лишь `key_hint` — последние символы, чтобы отличать ключи друг от друга.

Нюанс, который экономит час отладки: ключ создаётся **внутри организации**. Нет организации — нет ключа (`400 organization_required`); ключ тестовой организации никогда не заработает с боевой — это разные организации с разными ключами.

## Где взять вебхук-секрет (кнопка, которую «обычно не находят»)

Секрет генерируется **на API-ключе** и только **после того, как у ключа указан `webhook_url`**. Порядок строго такой:

1. Откройте ключ в «Настройки → API-ключи».
2. Впишите `webhook_url` (публичный HTTPS) и сохраните.
3. Появится кнопка **«Сгенерировать подпись»** — нажмите. Это и есть вебхук-секрет; показывается один раз.

Пока URL не задан, кнопки нет — и это не баг: секрет нужен для проверки вебхуков, а без URL вебхуков не будет («нет вебхука — нечего валидировать»). Именно на этом шаге чаще всего «не могут найти секрет».

## Когда ключи «внезапно» перестают работать

Все случаи ниже — документированное поведение, а не потеря данных:

- **Перегенерация.** `regenerate` (ключ) и `regenerate-secret` (секрет) мгновенно убивают старое значение. Если интеграций несколько — обновите значение во всех местах сразу.
- **Партнёрская повторная выдача.** Партнёрский эндпоинт `POST /api/partner/organizations/{id}/api-key` **идемпотентен**: повторный вызов (например, «на всякий случай» после привязки кассира) перегенерирует ключ **той же записи** и заменяет её вебхук-настройки — старый ключ мгновенно мёртв. Классический источник «на тестах работало, а сегодня всё упало».
- **Переход партнёра в рабочий режим.** `PUT /api/partner/mode {"mode":"production"}` **удаляет все тестовые организации** со счетами/подписками и **деактивирует их API-ключи** — чистый старт by design. Сохраните боевые ключи заново после перехода. Подробнее о режимах — «[Песочница и рабочий режим](/guides/pesochnitsa-i-rabochiy-rezhim)».
- **Sandbox-ключи не переносятся.** Тестовая организация архитектурно не может стать боевой, поэтому её ключи не «мигрируют» — для боевой организации создаётся новый ключ.
- **Флаг org-default перескочил.** Если у организации не было org-default ключа, первый ключ с `webhook_url` становится им автоматически; назначение org-default другому ключу снимает флаг с прежнего. На доставку вебхуков это влияет (org-default — второй получатель) — если вебхуки «переехали», проверьте, какой ключ сейчас default.

## Правила хранения (коротко и жёстко)

- Оба значения — только на сервере: переменные окружения или менеджер секретов. **Никогда** в клиентском JS, репозитории, скриншотах и чатах с поддержкой.
- Утечка ключа = кто угодно выставляет счета от вашего имени → немедленно `regenerate`.
- Утечка секрета = кто угодно подделывает вебхуки «оплачено» → немедленно `regenerate-secret`.
- Разные среды — разные ключи: тестовая организация со своим ключом, боевая со своим.

## Частые ошибки

- **Искать «Сгенерировать подпись» до ввода `webhook_url`.** Кнопка появляется только после сохранения URL.
- **Класть вебхук-секрет в `X-API-Key`** — `401` на любой запрос.
- **Проверять подпись вебхука API-ключом** — «подпись не сходится» навсегда.
- **Не сохранить значение при создании.** Второго показа не будет — только перегенерация.
- **Использовать ключ из песочницы в бою** (или наоборот) — `401`: ключи привязаны к организации.
- **Перегенерировать партнёрским эндпоинтом «для проверки»** — старый ключ умирает молча.
- **Отдавать ключ ИИ-агенту в публичном чате.** Агенту достаточно сказать, что ключ лежит в переменной окружения `APIPAY_API_KEY`.

## Вопросы и ответы

**Это одно и то же? Можно использовать API-ключ как секрет?**
Нет. Ключ авторизует ваши запросы к ApiPay; секрет проверяет подпись входящих вебхуков. Значения разные, взаимозаменяемости нет.

**Где посмотреть ключ ещё раз?**
Никак — показывается один раз при создании, дальше только `key_hint` (хвост). Потеряли — перегенерируйте и обновите интеграции.

**Обязателен ли вебхук-секрет?**
Формально вебхуки доставляются и без него (заголовка подписи тогда просто нет), но тогда любой может прислать вам фейковый «paid». Для боевой интеграции секрет обязателен по здравому смыслу.

**Можно ли иметь несколько API-ключей?**
Да, в одной организации — несколько ключей (например, по ключу на систему), у каждого свой `webhook_url` и секрет. Учтите правило org-default: он — второй получатель вебхуков организации.

**Почему после перехода в рабочий режим ключи «пропали»?**
Тестовые организации удаляются при переходе партнёра в production вместе со своими ключами — by design. Создайте ключ заново в боевой организации.

**Чем отличается партнёрский ключ?**
`X-Partner-Key` — отдельный server-to-server ключ партнёрского API (его секрет имеет формат `whsec_…`); к мерчантским `X-API-Key` он отношения не имеет. Если вы обычный мерчант — вам нужен только `X-API-Key`.

Смотрите также: [Вебхуки ApiPay](/guides/nastroyka-webhookov-apipay) · [Песочница и рабочий режим](/guides/pesochnitsa-i-rabochiy-rezhim) · [Как создать счёт по номеру](/guides/kak-sozdat-schet-kaspi-po-nomeru) · пиллар «[Как принимать оплату Kaspi через API](/kaspi-api)».

---

ApiPay — независимый сервис и не аффилирован с АО «Kaspi Bank». Kaspi и Kaspi Pay — товарные знаки их правообладателя.
База знаний: https://apipay.kz/guides
