Главная › Документация API

Reference · v1

Документация API

Полный технический референс Kaspi Pay invoice API: авторизация по SMS, создание счёта, статусы, отмена, возвраты, вебхуки с X-Webhook-Signature: sha256=..., коды ошибок.

Получить API-ключ → Открыть .md Fallback: invoice + PDF → Гайды и статьи Swagger UI Health

Отказ от ответственности

Сервис PayProverkaBot (pay.proverkacheka.kz) не связан и не аффилирован с АО «Kaspi Bank» или любыми другими организациями группы Kaspi. Мы не являемся платёжным сервисом, эквайрингом или финансовой организацией. Мы не являемся партнёрами, представителями или агентами Kaspi.

PayProverkaBot предоставляет техническую услугу — программный интерфейс к функции «удалённый счёт» приложения Kaspi Pay для бизнеса от имени самого мерчанта, после его добровольной авторизации по SMS на его собственный номер.

Ответственность пользователя

Используя сервис, вы подтверждаете, что:

  1. Вы являетесь владельцем (или уполномоченным представителем) аккаунта Kaspi Pay для бизнеса, по которому проходит авторизация.
  2. Вы соблюдаете законодательство Республики Казахстан и условия Kaspi.
  3. Вы используете сервис в законных целях — автоматизация выставления счетов, интеграция с CRM, чат-ботами, кассовыми системами.
  4. Вы не используете сервис для незаконной деятельности, отмывания денег, уклонения от налогов или иных противоправных действий.

Администрация PayProverkaBot не несёт ответственности за прямые или косвенные убытки, возникшие в результате использования сервиса, блокировки аккаунта Kaspi или технических сбоев на стороне Kaspi.

Начало работы

Как получить API-ключ

  1. Откройте @PayProverkaBot в Telegram.
  2. Нажмите /start — получите персональный API_KEY.
  3. Авторизуйтесь в Kaspi Pay: /login → отправьте номер телефона ИП/ТОО → введите SMS-код.
  4. Готово — можете выставлять счета через бота (/invoice 87019009393 1500 За кофе) или через REST API.
Совет. Команда /apikey в боте покажет ваш ключ повторно. Команда /account покажет, к какому аккаунту Kaspi привязана сессия.

Базовый URL и заголовки

Что делает сервис

Проверка API-ключа

Сам онбординг (SMS-логин в Kaspi) проходит через Telegram-бота — это внутренний процесс сервиса. Через API доступна только проверка выданного ключа:

GET/v1/auth/me

Возвращает информацию о привязанной сессии Kaspi.

curl https://pay.proverkacheka.kz/api/v1/auth/me \
  -H "X-API-Key: $API_KEY"

Создание счёта

POST/v1/invoice/create

Создаёт удалённый счёт Kaspi Pay с корзиной товаров. Клиенту приходит push-уведомление в Kaspi.kz. Сумма счёта рассчитывается автоматически как Σ(items[i].price × items[i].count).

Тело запроса

ПолеТипОписание
phoneNumber requiredstringНомер клиента. Сервис автоматически нормализует — принимаются форматы 87019009393, 77019009393, 7019009393, +7 701 900 93 93. На вход в Kaspi уходит каноничный 8XXXXXXXXXX. На невалидный формат — 400 invalid_phone.
items requiredarray1–50 позиций корзины. См. ниже.
comment optionalstringОписание счёта. По умолчанию — названия позиций через запятую.

Структура items[i]

ПолеТипОписание
name requiredstring (1–200)Название товара/услуги — показывается в чеке клиента.
price requirednumber > 0Цена за единицу в тенге.
count optionalinteger > 0Количество. По умолчанию 1.

Пример

curl -X POST https://pay.proverkacheka.kz/api/v1/invoice/create \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumber": "87019009393",
    "comment": "Заказ #42",
    "items": [
      { "name": "Капучино", "price": 1200, "count": 2 },
      { "name": "Чизкейк",   "price": 1800, "count": 1 }
    ]
  }'
{
  "paymentId": "14918505280",
  "cartId": "c8a91b...",
  "amount": 4200.0,
  "status": "RemotePaymentCreated",
  "receiptUrl": null
}

Статус и список

GET/v1/invoice/{paymentId}

Возвращает актуальный статус и (после оплаты) ссылку на чек.

curl https://pay.proverkacheka.kz/api/v1/invoice/14918505280 \
  -H "X-API-Key: $API_KEY"
{
  "paymentId": "14918505280",
  "status": "Processed",
  "amount": "4 200 ₸",
  "clientMobile": "87019009393",
  "receiptUrl": "https://receipt.kaspi.kz/..."
}

Возможные статусы

StatusЗначение
RemotePaymentCreated⏳ Ожидает оплаты клиентом
Processed✅ Оплачен
RemotePaymentRejected❌ Клиент отказался
RemotePaymentCanceled🚫 Отменён мерчантом
RemotePaymentExpired⌛ Истёк срок (~24 часа)
Refunded↩️ Полностью возвращён
PartiallyRefunded↩️ Частично возвращён

GET/v1/invoice

Список активных (не финализированных) счетов, отслеживаемых сервисом.

curl https://pay.proverkacheka.kz/api/v1/invoice \
  -H "X-API-Key: $API_KEY"

Отмена счёта

POST/v1/invoice/{paymentId}/cancel

Отменяет ожидающий счёт (статус RemotePaymentCreated). Уже оплаченные — см. возврат.

curl -X POST https://pay.proverkacheka.kz/api/v1/invoice/14918505280/cancel \
  -H "X-API-Key: $API_KEY"
{ "cancelled": true, "paymentId": "14918505280", "status": "RemotePaymentCanceled" }

Возврат

POST/v1/invoice/{paymentId}/refund

Возвращает деньги по оплаченному счёту (Processed). Поддерживается полный и частичный возврат. Если amount опущен — возвращается весь остаток AvailableReturnAmount.

Тело запроса

ПолеТипОписание
amount optionalnumber > 0Сумма возврата в тенге. Опустите для полного возврата.
# Частичный возврат
curl -X POST https://pay.proverkacheka.kz/api/v1/invoice/14918505280/refund \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": 1200}'
{
  "paymentId": "14918505280",
  "refundedAmount": 1200.0,
  "isFull": false,
  "remainingRefundable": 3000.0,
  "refundsTotal": 1
}

GET/v1/invoice/{paymentId}/refunds

История возвратов по счёту.

Вебхуки

Подпишитесь на события платежей — сервис будет POST'ить на ваш URL JSON-пейлоад каждый раз, когда меняется финальный статус. Это рекомендуемый способ интеграции вместо поллинга.

События

EventКогда срабатывает
payment.successКлиент оплатил счёт
payment.failedКлиент отказался или мерчант отменил
payment.expiredИстёк срок ожидания оплаты
payment.refundedПроизведён возврат (полный или частичный)
*Подписка на все события сразу

POST/v1/webhooks

curl -X POST https://pay.proverkacheka.kz/api/v1/webhooks \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/kaspi/webhook",
    "events": ["payment.success", "payment.refunded"],
    "secret": "my-shared-secret-min-8-chars"
  }'
{ "id": 7, "url": "https://example.com/...", "events": ["payment.success","payment.refunded"], "has_secret": true, "is_active": true }

GET/v1/webhooks · DELETE/v1/webhooks/{id}

Просмотр и удаление подписок.

Формат пейлоада

POST https://example.com/kaspi/webhook
Content-Type: application/json
X-Webhook-Event: payment.success
X-Webhook-Attempt: 1
X-Webhook-Signature: sha256=<hex-hmac>
User-Agent: kaspipayinvoice-webhooks/1.0

{
  "event": "payment.success",
  "paymentId": "14918505280",
  "type": "invoice",
  "status": "Processed",
  "amount": 4200.0,
  "clientMobile": "87019009393",
  "receiptUrl": "https://receipt.kaspi.kz/...",
  "extras": {},
  "timestamp": 1747049280
}

Проверка подписи

Заголовок X-Webhook-Signature = sha256= + HMAC-SHA256 от сырого тела запроса, ключ — ваш secret. Считайте подпись на своей стороне и сравнивайте константно (hmac.compare_digest).

import hmac, hashlib

def verify(body_bytes: bytes, header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), body_bytes, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header)
Retry-политика. На любой ответ кроме 2xx или таймаут сервис повторит доставку с экспоненциальным backoff (несколько попыток в течение суток). Возвращайте 2xx только после того, как успешно приняли событие.

Ошибки

HTTPКогда
401Отсутствует или невалиден X-API-Key.
400Неподдерживаемое событие вебхука, попытка возврата суммы больше AvailableReturnAmount, отмена уже завершённого счёта, небезопасный URL вебхука.
404Вебхук не найден.
412kaspi_session_required — сессия Kaspi отсутствует или была сброшена (например, вы залогинились в приложении Kaspi Pay на телефоне). Заново пройдите SMS-флоу.
422Pydantic-валидация тела запроса (например, пустой items, price ≤ 0).
502bad_gateway — Kaspi вернул ошибку. detail содержит {"kaspi": "...", "code": N}.
500Внутренняя ошибка сервиса — администраторы уже получили алерт.

Частые причины

Пример интеграции (Python)

import os, requests

API = "https://pay.proverkacheka.kz/api"
KEY = os.environ["KASPI_API_KEY"]
H   = {"X-API-Key": KEY, "Content-Type": "application/json"}

# 1. Выставить счёт
r = requests.post(f"{API}/v1/invoice/create", headers=H, json={
    "phoneNumber": "87019009393",
    "comment": "Заказ #42",
    "items": [
        {"name": "Капучино", "price": 1200, "count": 2},
        {"name": "Чизкейк",   "price": 1800, "count": 1},
    ],
})
r.raise_for_status()
payment_id = r.json()["paymentId"]
print("Счёт создан:", payment_id)

# 2. (Опционально) проверить статус — но лучше подписаться на вебхук
status = requests.get(f"{API}/v1/invoice/{payment_id}", headers=H).json()
print(status["status"])

# 3. Подписаться на вебхук один раз при старте бота/CRM
requests.post(f"{API}/v1/webhooks", headers=H, json={
    "url": "https://my-bot.example.com/kaspi/webhook",
    "events": ["payment.success", "payment.failed", "payment.expired", "payment.refunded"],
    "secret": "long-random-shared-secret",
})

Пример приёма вебхука (Flask)

from flask import Flask, request, abort
import hmac, hashlib, os

SECRET = os.environ["KASPI_WEBHOOK_SECRET"].encode()
app = Flask(__name__)

@app.post("/kaspi/webhook")
def webhook():
    body = request.get_data()
    sig  = request.headers.get("X-Webhook-Signature", "")
    expected = "sha256=" + hmac.new(SECRET, body, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, sig):
        abort(401)

    event = request.json
    if event["event"] == "payment.success":
        notify_customer(event["paymentId"], event["amount"])
    return "", 200

Лимиты и особенности

ПараметрЗначение
Срок действия неоплаченного счёта~24 часа (контролируется Kaspi)
Позиций в корзине1–50
Формат номера клиента10/11 цифр, любой казахстанский формат (нормализуется в 8XXXXXXXXXX)
Минимальная сумма позиции> 0 ₸
Активных счетов одновременнобез жёсткого лимита (поллим все)
Webhook retryэкспоненциальный backoff, до суток
Алгоритм подписи webhookHMAC-SHA256 над сырым телом

Краткая справка по эндпоинтам

МетодПутьОписание
GET/v1/auth/meИнформация о ключе и привязанной сессии Kaspi
POST/v1/invoice/createСоздать счёт
GET/v1/invoice/{id}Статус счёта
GET/v1/invoiceАктивные счета
POST/v1/invoice/{id}/cancelОтменить ожидающий счёт
POST/v1/invoice/{id}/refundВозврат оплаченного счёта
GET/v1/invoice/{id}/refundsИстория возвратов
POST/v1/webhooksПодписаться на события
GET/v1/webhooksСписок подписок
DELETE/v1/webhooks/{id}Удалить подписку