Как настроить полностью автоматический приём Kaspi для клиентов?

Обновлено 10 июля 2026 · Для вашего бизнеса · Версия в Markdown
Содержание
  1. Что означает «полностью автоматически»
  2. Шаг 1. Создать организацию клиента (авто)
  3. Шаг 2. Авторизация кассира — единственный ручной штрих
  4. Шаг 3. Выдать клиенту ключ и вебхук (авто)
  5. Шаг 4. Счета, каталог, статусы, возвраты (авто)
  6. Шаг 5. Оплата тарифа ApiPay — два способа
  7. Шаг 6. Вебхуки закрывают петлю без поллинга
  8. Сначала — sandbox
  9. Частые ошибки
  10. Частые вопросы

Что означает «полностью автоматически»

Полностью автоматически — это когда клиент партнёра пользуется вашим продуктом (CRM, платформа, SaaS, 1С), а приём Kaspi «просто работает» под вашим брендом. У клиента нет отдельного аккаунта ApiPay: организацию, ключи и вебхук держит партнёр на своей стороне. Единственная точка, где нужен живой человек со стороны клиента, — подтверждение кода из Kaspi-SMS при авторизации кассира (граница доверия: код приходит на номер кассира клиента, а не партнёру). Всё до и после этого — программно.

Ключей два, не путайте их — это главный источник ошибок:

  • X-Partner-Key — партнёрский, server-to-server: онбординг, авторизация кассира, выдача ключей, тариф, health. Хост .../api/partner.
  • per-org X-API-Key — ключ конкретного клиента: счета, статусы, возвраты, каталог, lookup. Хост .../api/v1.

Разбор пары ключей — в статье «Partner API white-label».

Шаг 1. Создать организацию клиента (авто)

POST /organizations с телом { "external_id": "crm-client-42", "name": "ТОО Клиент", "has_catalog": false }. external_id — ваш референс клиента в CRM и ключ идемпотентности: повторный вызов с тем же external_id вернёт ту же организацию (200), дубля не будет. В ответе — organization.id, status: "pending", sandbox_mode. Никакого участия клиента.

Шаг 2. Авторизация кассира — единственный ручной штрих

Три вызова подряд: POST /organizations/{id}/kaspi-auth/initsend-phoneverify-otp. На send-phone вы передаёте телефон кассира клиента в формате 7XXXXXXXXXX; Kaspi шлёт SMS-код на этот номер. Клиент диктует код — вы отправляете его в verify-otp ({ "otp": "1234" }). Всё, организация становится verified.

  • process_id живёт ~10 минут — уложите send-phone + verify-otp в это окно.
  • Неверный код — это тоже HTTP 200 с { "success": false, "error": "invalid_otp" }, сессия не сбрасывается: просто попросите код заново и повторите verify-otp.
  • Слетела сессия позже — переавторизация тем же флоу с init + "force": true.

Пошаговый онбординг с разбором каждой ошибки send-phone — в статье «Как партнёру подключить организацию».

Шаг 3. Выдать клиенту ключ и вебхук (авто)

POST /organizations/{id}/api-key с обязательным webhook_url (проходит SSRF-валидацию — приватный адрес 422). В ответе key (это X-API-Key) и webhook_secret приходят в открытом виде ровно один раз — сохраните оба сразу в своё секрет-хранилище, привязав к записи клиента. Клиент этих ключей не видит и не хранит — они живут у партнёра. Как ключ соотносится с секретом подписи — «API-ключ и вебхук-секрет».

Шаг 4. Счета, каталог, статусы, возвраты (авто)

Дальше работаете выданным X-API-Key против https://api.apipay.kz/api/v1 — от имени клиента, но без его участия:

  • Счёт по номеру — POST /api/v1/invoices (201, обработка асинхронная).
  • QR-счёт на экране кассы — POST /api/v1/invoices/qr (TTL минуты).
  • Возврат — POST /api/v1/invoices/{id}/refund (полный или частичный).

Полный платёжный API — в мерчантской документации /docs; создание счетов по номеру — «Счёт Kaspi по номеру».

Шаг 5. Оплата тарифа ApiPay — два способа

Партнёр сам платит ApiPay за подписку клиента (start 10 000 ₸/мес до 30 счетов/день, business 25 000 ₸ до 100, pro 60 000 ₸ 100–300; больше 300 — договорная). Это подписочная плата клиент→ApiPay, не оборот клиента. Два независимых способа оплатить один тариф:

  • По телефонуPOST /organizations/{id}/tariff/pay с { "tier_id", "period_months", "phone": "8XXXXXXXXXX" }. Push-счёт через Kaspi на телефон плательщика; активация асинхронная после оплаты.
  • Счётом на юрлицоPOST /organizations/{id}/tariff/invoice с реквизитами покупателя (buyer_bin 12 цифр, buyer_name, опц. buyer_address/contract). Синхронно возвращает download_url — публичную ссылку на PDF-счёт, который оплачивается банковским переводом. Тариф активируется вручную владельцем ApiPay после поступления средств — автоактивации у счёта нет.

Неоплаченный счёт (payment_method=invoice) не блокирует tariff/pay, и наоборот — способы независимы. Точную сумму за выбранный период возвращает сервер (GET /tariff-plans), не считайте её сами.

Шаг 6. Вебхуки закрывают петлю без поллинга

Два события снимают необходимость постоянно опрашивать статусы:

  • invoice.status_changed — приходит на per-org webhook_url клиента, когда счёт меняет статус (в т.ч. paid — клиент оплатил). Реагируйте на последний статус: легитимны и cancelled → paid, и expired → paid.
  • tariff.activated — приходит на webhook_url партнёра, когда владелец ApiPay вручную активировал тариф по выписанному счёту. Плоский payload с payment_id, invoice_number, tier, amount, expires_at.

Обе подписи — X-Webhook-Signature: sha256=HMAC-SHA256(raw body, webhook_secret); проверяйте по сырому телу, до JSON-парсинга. Доставка tariff.activated ретраится автоматически (до 11 попыток); при окончательном сбое активацию видно поллингом GET .../tariff/payments (pending → completed). Готовые приёмники и проверка HMAC — «Настройка вебхуков ApiPay».

Сначала — sandbox

Весь пайплайн прогоняется в песочнице партнёра без реального Kaspi и SMS, детерминированно (магические номера кассира, OTP 0000) — можно покрыть автотестами. Тот же код идёт в production, отличаются только реальные значения. Пока партнёр в sandbox, боевые вызовы отбиваются 403 production_access_required; production открывается после ручного одобрения (коммерческий договор).

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

  • Просить клиента зайти в кабинет ApiPay. Не нужно: у клиента нет аккаунта, всё делает партнёр. Единственное действие клиента — продиктовать код из SMS.
  • Путать ключи и хосты. X-Partner-Key.../api/partner; per-org X-API-Key.../api/v1. Перепутать — типовая причина 401.
  • Путать телефоны. Кассир — 7XXXXXXXXXX (авторизация Kaspi), плательщик — 8XXXXXXXXXX (кому выставляете счёт).
  • Ждать активации тарифа по счёту автоматически. У tariff/invoice автоактивации нет — тариф выдаёт владелец ApiPay вручную после банковского перевода; ловите tariff.activated или поллинг tariff/payments.
  • Проверять HMAC по перепарсенному JSON. Только по сырому телу — пересериализация ломает подпись.
  • Не сохранить one-time key/webhook_secret. Показываются один раз; иначе только перевыпуск.

Частые вопросы

Заходит ли клиент в кабинет ApiPay?

Нет, ни разу. У клиента нет отдельного аккаунта ApiPay: организацию, X-API-Key и вебхук держит партнёр. Единственное действие клиента — продиктовать код из Kaspi-SMS при авторизации кассира.

Чем tariff/invoice отличается от tariff/pay?

tariff/pay — push-счёт через Kaspi на телефон плательщика, активация асинхронная после оплаты. tariff/invoice — PDF-«Счёт на оплату» для юрлица, оплата банковским переводом, тариф активируется вручную владельцем ApiPay. Это два независимых способа оплатить один тариф.

Как узнать, что тариф по счёту активирован?

Придёт вебхук tariff.activated на webhook_url партнёра. Если он не дошёл (после ретраев), тот же факт виден поллингом GET .../tariff/payments: статус платежа payment_method=invoice переходит pending → completed.

Куда приходят вебхуки об оплате счетов клиента?

На per-org webhook_url клиента (ключа, создавшего счёт). Партнёрский webhook_url в доставке invoice/refund не участвует — на него идёт только tariff.activated.

Можно ли всё протестировать без реального Kaspi?

Да. Песочница партнёра детерминированно эмулирует онбординг, авторизацию кассира, счета и вебхуки без реального Kaspi и SMS (магические номера, OTP 0000). Тот же код затем работает в production.

Интеграция с ИИ

Не настраивайте вручную — поручите ИИ

Скопируйте готовый промпт и вставьте своему ИИ-ассистенту — он подключит приём платежей примерно за 15 минут. Настраивает ИИ, а не вы.

Для разработчика. Полная спецификация API — apipay.kz/docs. Эта статья в Markdown — /guides/besshovnyy-priyom-kaspi-dlya-klientov-partnyora.md. Справочник фактов для ИИ-агента — apipay.kz/llms.txt.