Kaspi Pay через REST API — интеграция для сайтов и SaaS

Три HTTP-запроса: создать счёт, получить webhook, вернуть деньги. Без процента с продаж, деньги на ваш Kaspi Business.

Что делает API

Наш сервис оборачивает недокументированный протокол Kaspi POS в чистый REST API. Ваш сервер отправляет три типа запросов: POST /invoices — создать счёт, приём webhook — получить статус, POST /refunds — вернуть деньги. Всё остальное — очереди, ретраи, шифрование, подписи RSA/ECDH — работает автоматически на нашей стороне.

Как это работает — от POST до PAID за 15 секунд

Ваш сервер вызывает POST /api/v1/invoices с суммой и номером телефона клиента. Мы подписываем и отправляем запрос в Kaspi. Клиент получает push в приложении Kaspi.kz — одна кнопка «Оплатить». Деньги идут напрямую на ваш Kaspi Business счёт. Ваш сервер получает HMAC-подписанный webhook invoice.status_changed с финальным статусом paid.

Почему без процента с продаж

Мы не банк-эквайер. Деньги идут напрямую от клиента на ваш Kaspi Business счёт — мы только автоматизируем протокол. Наш доход — фиксированная подписка от 10 000 ₸/мес. Оборот 10 млн ₸ или 1 млн — тариф не меняется. Это принципиально дешевле классического эквайринга при среднем и высоком чеке.

Sandbox без реальных транзакций

Тестовые ключи kpa_test_* не проводят реальных Kaspi-платежей — но структура ответов API соответствует продакшену, а webhook-и приходят на ваш sandbox URL. Идеально для CI, интеграционных тестов и локальной разработки без риска для реальных клиентов.

Webhooks: HMAC-SHA256, ретраи, dead-letter

Каждое уведомление подписано HMAC-SHA256 над raw body. Заголовок X-Webhook-Signature: sha256=<hex>. Не получили 2xx — мы повторяем с экспоненциальным backoff (0, 5, 30 сек, 2, 10, 30 мин). После 6 попыток — dead-letter, доступный в дашборде. Секрет вы задаёте сами и можете ротировать без даунтайма.

Примеры кода

Пример: создать счёт (curl)

curl -X POST https://pos.satushi.me/api/v1/invoices \
  -H 'X-API-Key: kpa_live_...' \
  -H 'Content-Type: application/json' \
  -d '{
    "amount": 15000,
    "phone_number": "87001234567",
    "comment": "Заказ #42"
  }'

Пример: Node.js

const res = await fetch('https://pos.satushi.me/api/v1/invoices', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.KPA_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    amount: 15000,
    phone_number: '87001234567',
  }),
});
const invoice = await res.json();

Пример: Python

import requests

res = requests.post(
    'https://pos.satushi.me/api/v1/invoices',
    headers={'X-API-Key': KPA_KEY},
    json={'amount': 15000, 'phone_number': '87001234567'},
)
invoice = res.json()

Тарифы для API-интеграций

Три тарифа: Старт 10 000 ₸/мес (до 30 счетов в день), Бизнес 25 000 ₸/мес, Про 100 000 ₸/мес. Первые 7 дней бесплатно, без привязки карты.

Смотреть тарифы

Вопросы разработчиков

Какой rate limit?
Ограничение — по количеству созданных счетов в день (задаётся тарифом). Мгновенных HTTP rate-limit нет — API не блокирует burst-запросы. Отдельный ретрай-график на исходящие webhook: 6 попыток за 43 минуты, затем dead-letter.
Есть ли SLA?
На тарифе Про — SLA 99.5% uptime и время ответа в рабочее время (10:00–19:00 Астана). На Старт и Бизнес — best-effort, без формальных гарантий.
Какие статусы у инвойса?
pending, cancelling, paid, cancelled, expired, partially_refunded, refunded. Полный статусный ромб описан в OpenAPI 3.0 (/docs/openapi.yaml).
Как хранятся API-ключи?
API-ключи (kpa_live_*, kpa_test_*) показываются один раз при создании — вы должны сохранить их сами. Мы храним только SHA-256 хеш. Kaspi-сессия шифруется AES-256-GCM с ключом из TOKEN_SECRET_KEY, живущим только в памяти сервера.
Можно ли принимать подписки?
Да. POST /api/v1/subscriptions с периодом (daily, weekly, biweekly, monthly, quarterly, yearly). Мы автоматически выставляем счета по расписанию и присылаем webhook с результатом.
Кто владеет Kaspi Business?
Вы. Мы подключаемся к вашему Kaspi-аккаунту как «Кассир» через SMS-подтверждение. Деньги от клиентов приходят к вам напрямую — мы к ним не имеем доступа и не можем их перенаправить.