Документация API
REST API для автоматической проверки и валидации чеков Kaspi. Загружайте PDF-чеки, проверяйте подлинность через QR-код и базу Kaspi.
Чеки обрабатываются менее чем за 1 секунду. Скорость обработки зависит от времени ответа платёжной системы. Рекомендуемый timeout для запросов: 10 секунд.
Показать содержимое
Быстрый старт
Получите API-ключ и отправьте первый запрос за 2 минуты.
1. Получите API-ключ
Запустите Telegram бот — вы получите 10 бесплатных проверок и API-ключ автоматически.
2. Отправьте чек на проверку
# Отправка чека через URL
curl -X POST https://api.proverkacheka.kz/upload \
-H "Content-Type: application/json" \
-d '{
"api_key": "ваш-api-ключ",
"file": "https://example.com/receipt.pdf",
"user_id": "123456789",
"price": 5000,
"iin": "123456789012"
}'
Откройте любой чек Kaspi вашей организации — в строке "ИИН/БИН продавца" указан ваш 12-значный идентификатор. Передайте его в параметре iin. Это надёжнее, чем ip_name, т.к. ИИН уникален.
3. Получите результат
{
"message": "Чек валиден и добавлен в базу данных.",
"check_number": "QR13973837513",
"amount": 1000.50,
"company_name": "ИП АЛИБЕКОВ",
"payment_method": "Kaspi Gold"
}
Аутентификация
Все запросы к /upload требуют API-ключ (UUID), который передаётся в теле запроса в поле api_key.
API-ключ привязан к вашему аккаунту с балансом кредитов. Вы можете получить ключ через Telegram бот или запросить у администратора.
Храните API-ключ в секрете. Не передавайте его в URL-параметрах и не размещайте в клиентском коде (JavaScript в браузере). Используйте серверную интеграцию.
Лимиты и ограничения
| Ограничение | Значение |
|---|---|
| Rate limit | 100 запросов/мин на API-ключ |
| Макс. размер файла | 5 МБ |
| Макс. размер запроса | 10 МБ |
| Формат файла | Только PDF |
| Срок действия кредитов | 30 дней с момента пополнения |
Загрузка и проверка чека
Загрузить PDF-чек Kaspi для валидации. Поддерживает отправку файла через URL, base64 или multipart form.
Параметры
| Параметр | Тип | Описание | |
|---|---|---|---|
| api_key required | string | required | UUID API-ключ клиента |
| file required | string / file | required | URL на PDF, base64-строка или бинарный файл (multipart) |
| user_id required | string | required | Идентификатор пользователя (например, Telegram ID) |
| price | number | optional | Минимальная сумма оплаты в тенге (default: 1000) |
| ip_name required* | string | required* | Наименование продавца (ИП/ТОО). *Не обязателен, если указан iin |
| iin recommended | string | recommended | ИИН/БИН продавца (12 цифр). Уникален для каждого продавца, исключает подмену |
| use_balance recommended | boolean | recommended | Рекомендуется true для большинства интеграций. Аккумулирует частичные оплаты до целевой суммы. Без этого недоплата приводит к полному отказу; с включённым — недоплата уходит на per-user баланс, и можно сказать пользователю, сколько ещё доплатить (default: false — для обратной совместимости) |
| max_age | integer | optional | Макс. возраст чека в днях (default: 14) |
| max_overpay | number | optional | Макс. допустимая переплата сверх price в тенге. По умолчанию не задано — без этого параметра принимается любая сумма ≥ price |
Старые названия параметров (club_price, date_limit, up_limit) по-прежнему принимаются. Новые названия имеют приоритет.
Примеры запроса
# Отправка чека через URL на PDF
curl -X POST https://api.proverkacheka.kz/upload \
-H "Content-Type: application/json" \
-d '{
"api_key": "550e8400-e29b-41d4-a716-446655440000",
"file": "https://example.com/receipt.pdf",
"user_id": "123456789",
"price": 5000,
"ip_name": "ИП АЛИБЕКОВ",
"iin": "123456789012"
}'
# Отправка PDF файлом напрямую
curl -X POST https://api.proverkacheka.kz/upload \
-F "api_key=550e8400-e29b-41d4-a716-446655440000" \
-F "file=@/path/to/receipt.pdf" \
-F "user_id=123456789" \
-F "price=5000" \
-F "ip_name=ИП АЛИБЕКОВ" \
-F "iin=123456789012"
# Проверка с валидацией ИИН продавца (ip_name не нужен)
curl -X POST https://api.proverkacheka.kz/upload \
-H "Content-Type: application/json" \
-d '{
"api_key": "550e8400-e29b-41d4-a716-446655440000",
"file": "https://example.com/receipt.pdf",
"user_id": "123456789",
"price": 5000,
"iin": "123456789012"
}'
Успешный ответ
// 200 OK
{
"message": "Чек валиден и добавлен в базу данных.",
"check_number": "QR13973837513",
"amount": 1000.50,
"company_name": "ИП АЛИБЕКОВ",
"payment_method": "Kaspi Gold",
"balance": null,
"due": null
}
Ответ при дубликате
// 200 OK — чек уже был обработан ранее
{
"message": "Чек уже обработан ранее.",
"check_number": "QR13973837513",
"amount": 1000.50,
"company_name": "ИП АЛИБЕКОВ",
"previous_user_id": "123456789",
"payment_method": "Kaspi Gold"
}
Ответ в режиме накопления
// 200 OK — use_balance: true, сумма < price
{
"message": "Баланс пополнен",
"check_number": "QR13973837513",
"amount": 500.00,
"company_name": "ИП АЛИБЕКОВ",
"balance": 500.00,
"due": 500.00,
"payment_method": "Kaspi Gold"
}
Ответ при отклонении (недоплата / переплата)
// 200 OK — сумма чека ниже price (чек не сохранён, можно повторить)
{
"message": "Сумма чека должна быть не меньше 5000 тенге.",
"check_number": null,
"amount": 3500.00,
"company_name": "ИП АЛИБЕКОВ",
"payment_method": "Kaspi Gold",
"balance": null,
"due": null
}
// 200 OK — сумма превышает price + max_overpay (чек не сохранён, можно повторить)
{
"message": "Сумма чека превышает допустимый предел.",
"check_number": null,
"amount": 8200.00,
"company_name": "ИП АЛИБЕКОВ",
"payment_method": "Kaspi Gold",
"balance": null,
"due": null
}
Транзиентная ошибка Kaspi (нужен ретрай)
// 200 OK — Kaspi API временно недоступен (HTTP 5xx, таймаут или сетевая ошибка).
// Кредиты не списаны, чек не зарегистрирован — ретрай тем же PDF безопасен.
// Канонический сигнал — поле retry_after (а не текст message).
{
"message": "Failed to fetch receipt data from Kaspi.",
"check_number": null,
"amount": 220.00,
"company_name": "ИП АЛИБЕКОВ",
"payment_method": "Kaspi Gold",
"balance": null,
"due": null,
"retry_after": 5
}
Ошибки
| Код | Сообщение | Причина |
|---|---|---|
| 400 | Missing API key. | Не передан api_key |
| 400 | Invalid file type. Only PDF files are allowed. | Файл не PDF |
| 400 | Файл слишком большой. | Файл > 5 МБ |
| 401 | Invalid API key. | Неверный ключ |
| 402 | Insufficient credits. | Кредиты закончились |
| 408 | Timeout при скачивании файла. | URL не отвечает 10с |
| 413 | Request too large | Запрос > 10 МБ |
| 429 | Rate limit exceeded | > 100 запросов/мин |
При ошибке валидации чека (неверная сумма, не тот продавец, устаревший чек) API возвращает 200 с описанием в поле message. Проверяйте текст message для определения результата.
Проверка состояния сервиса и доступности базы данных.
curl https://api.proverkacheka.kz/health
// 200 OK
{
"status": "healthy",
"service": "proverkacheka-api"
}
Система кредитов
Каждый успешный запрос на проверку чека расходует 1 кредит. Кредиты действительны 30 дней с момента последнего пополнения.
Как это работает
- При пополнении кредитов обновляется дата подписки
- Через 30 дней после последнего пополнения кредиты автоматически сбрасываются до 0
- При недостаточном количестве кредитов возвращается ошибка
402 - Дубликаты чеков не расходуют кредиты
Новые пользователи получают 10 бесплатных проверок через Telegram бот. Для пополнения кредитов свяжитесь с поддержкой.
Накопление баланса РЕКОМЕНДУЕТСЯ
Режим накопления позволяет принимать частичные оплаты. Включается параметром use_balance: true в запросе /upload.
В большинстве прод-ботов use_balance стоит выставлять в true. Без него любая недоплата (например, 200 ₸ за тариф 500 ₸) превращается в жёсткий отказ; с включённым — вы видите balance и due в ответе и можете попросить пользователя доплатить разницу. Оставлять false имеет смысл только для одноразовой покупки с фиксированной ценой, где частичная оплата бессмысленна.
Логика работы
- Каждый чек добавляет свою сумму к балансу пользователя
- Пока сумма баланса <
price, ответ содержит текущийbalanceи оставшуюся суммуdue - Когда сумма баланса ≥
price, оплата считается завершённой - Баланс привязан к конкретному
user_idиapi_key
Пример сценария
// price = 10000
// Чек #1 — 6000 тенге
{ "balance": 6000, "due": 4000 }
// Чек #2 — 4000 тенге, оплата завершена
{ "balance": 10000, "due": 0 }
ИИН/БИН валидация
Самый надёжный способ валидации. Используйте ИИН/БИН вместо имени продавца (ip_name) — это гарантирует точную идентификацию. Имена ИП/ТОО могут совпадать у разных продавцов, и чек другой организации с таким же названием пройдёт проверку по ip_name. ИИН/БИН уникален для каждого продавца, поэтому подмена исключена.
Как использовать
- Передайте параметр
iin(12 цифр) в запросе - Параметр
ip_nameстановится необязательным - Система извлекает ИИН/БИН продавца из данных Kaspi и сравнивает с переданным
- Имя продавца автоматически берётся из ответа Kaspi API
Откройте любой чек Kaspi вашей организации — в нём будет строка "ИИН/БИН продавца" с 12-значным номером. Это и есть ваш ИИН/БИН, который нужно передать в параметре iin.
Лучшие практики для Telegram-ботов
Рекомендации по обработке платежных чеков в Telegram-ботах, основанные на реальном опыте интеграций.
Состояние ожидания чека
После отправки пользователю ссылки на оплату Kaspi, установите флаг/состояние «ожидание чека» для этого пользователя:
- Держите состояние активным до подтверждения оплаты или отмены — пользователь может оплатить спустя часы
- Обрабатывайте PDF в любой момент, пока состояние активно, а не только сразу после отправки ссылки
- После успешной валидации: сбросьте состояние и прекратите приём PDF для этого платежа
Управление ссылками на оплату
Сохраняйте message_id сообщения со ссылкой на оплату Kaspi:
- После успешной оплаты: удалите или отредактируйте сообщение со ссылкой, чтобы пользователь не кликнул повторно
- Перед отправкой ссылки: проверяйте, что товар/услуга ещё доступны
- Пользователь может нажать старую ссылку через дни — валидируйте актуальность предложения на сервере
- Если предложение истекло: покажите дружелюбное сообщение (это избавит от ручных возвратов)
Обработка PDF вне контекста
Пользователи отправляют PDF на любом экране бота — не игнорируйте их:
- Реализуйте catch-all обработчик PDF, который маршрутизирует по состоянию аккаунта
- Приоритет: ожидание оплаты → платёжный чек; активный аккаунт → обычная проверка
- Всегда отвечайте на PDF — никогда не «проглатывайте» документ молча
Готовый рецепт: ретрай + накопление баланса (Python)
Минимальная обёртка вокруг /upload с правильной обработкой транзиентных ошибок Kaspi и включённым use_balance. Ретрай срабатывает по полю retry_after в ответе — это устойчивее, чем сравнивать строку message.
import asyncio, httpx
async def validate_receipt(pdf_bytes, user_id, price, iin, api_key, notify):
"""
notify(text): async callback для статус-сообщений между ретраями
("проверяем чек, подождите несколько секунд…")
Возвращает JSON-ответ /upload (последняя попытка, если все были транзиентными).
"""
data = {
"api_key": api_key,
"user_id": str(user_id),
"iin": iin,
"price": str(price),
"use_balance": "true", # рекомендуется для большинства интеграций
}
files = {"file": ("receipt.pdf", pdf_bytes, "application/pdf")}
async with httpx.AsyncClient(timeout=15) as client:
for attempt in range(3):
r = await client.post(
"https://api.proverkacheka.kz/upload",
data=data, files=files,
)
body = r.json()
if "retry_after" not in body:
return body # окончательный результат — успех или перманентный отказ
if attempt < 2:
await notify("⏳ Проверяем чек, подождите несколько секунд…")
await asyncio.sleep(body["retry_after"])
return body # три транзиентные подряд — отдаём как есть
Коды ошибок
| Код | Описание |
|---|---|
| 200 | Успешный запрос (проверяйте message для результата валидации) |
| 400 | Некорректный запрос — отсутствуют параметры или неверный формат |
| 401 | Неавторизован — неверный API-ключ |
| 402 | Недостаточно кредитов |
| 408 | Таймаут загрузки файла по URL |
| 413 | Файл или запрос слишком большой |
| 429 | Превышен лимит запросов (100/мин) |
| 500 | Внутренняя ошибка сервера |
Сообщения валидации (200 OK)
Следующие сообщения возвращаются с кодом 200 и означают проблему с самим чеком, а не с запросом:
| message | Значение |
|---|---|
| Чек уже обработан ранее. | Дубликат — этот чек уже использовался |
| Чек не принадлежит {ip_name}. | Продавец в чеке не совпадает с указанным |
| Сумма чека не совпадает с данными из Kaspi. | Данные в PDF не соответствуют Kaspi API |
| Сумма чека должна быть не меньше {N} тенге. | Сумма ниже price — чек не сохранён, можно повторить с другим price |
| Сумма чека превышает допустимый предел. | Сумма выше price + max_overpay — чек не сохранён, можно повторить с другим max_overpay |
| Чек слишком старый. | Превышен max_age |
| ИИН/БИН не совпадает. | ИИН продавца в чеке не совпадает с указанным |
| Не удалось извлечь номер чека из PDF. | PDF не содержит читаемого чека |
Все отклонённые чеки возвращают поле amount в ответе. В базу данных сохраняются только два результата: успешная проверка («Чек валиден...») и дубликат («Чек уже обработан ранее.»). Все остальные отклонения не сохраняют чек — его можно повторно отправить с исправленными параметрами. max_overpay не имеет значения по умолчанию: без него верхняя граница суммы не ограничена.
Транзиентные ошибки Kaspi (ретрай безопасен)
Фискальное API Kaspi обычно отвечает за 1–3 секунды, но изредка кратковременно «5xx-ит» или таймаутит. На HTTP 5xx (быстрая ошибка — самый частый случай флапа) сервер сам делает один повторный запрос через 1 секунду — большинство таких флапов вы не видите. На медленных ошибках (таймаут, обрыв соединения) сервер не ретраит — там вторая попытка точно так же зависнет. Если и повтор не помог (или это медленная ошибка), /upload возвращает 200 OK с одним из сообщений ниже и дополнительным полем retry_after: 5. Кредиты не списаны, чек не зарегистрирован — тот же PDF можно отправить ещё раз через несколько секунд.
| message | Когда возникает |
|---|---|
| Failed to fetch receipt data from Kaspi. | Kaspi API ответил HTTP 5xx |
| Kaspi API не отвечает. Попробуйте позже. | Таймаут запроса к Kaspi (10с) |
| Нет связи с Kaspi API. Попробуйте позже. | Сетевая ошибка до Kaspi |
| Ошибка при получении данных по QR-ссылке. | Иная неожиданная ошибка |
Не показывайте пользователю эти сообщения как финальную ошибку. Рекомендуется до 3 попыток с интервалом 5 секунд. Канонический сигнал — наличие поля retry_after в ответе (не парсинг строки message). Между попытками покажите статус («проверяем чек, подождите несколько секунд…») — без этого 5-секундная пауза выглядит как зависший бот, и пользователь начинает слать дубли.
Быстрая шпаргалка: что вернулось → что делать
| Ответ | Действие |
|---|---|
| «Чек валиден и добавлен в базу данных.» | Засчитать оплату |
«Баланс пополнен» (с due > 0) | Принять частичную оплату, сказать пользователю, сколько ещё доплатить |
Любое сообщение + retry_after | Транзиентная ошибка — подождать 5 сек, ретрай (до 3 раз). Кредиты не списаны |
| «Чек уже обработан ранее.» | Чек уже использован — попросить новый |
| «ИИН/БИН не совпадает.», «Чек слишком старый.», «Не удалось извлечь номер чека из PDF.», «Сумма чека не совпадает с данными из Kaspi.» | Перманентный отказ — показать ошибку пользователю |
Встраиваемый виджет BETA
Встраиваемый виджет находится в стадии бета-тестирования. Перед установкой свяжитесь с @sanzhar в Telegram для поддержки и помощи с интеграцией.
Добавьте проверку чеков на ваш сайт одной строкой HTML. Виджет использует HMAC-подписанные токены — параметры проверки (цена, продавец, срок) зашиты в токен и не могут быть изменены пользователем.
<div data-proverkacheka-widget
data-api-key="ВАШ_API_KEY"
data-token="СГЕНЕРИРОВАННЫЙ_ТОКЕН"
data-user-id="order-123"></div>
<script src="https://api.proverkacheka.kz/widget.js"></script>
Атрибуты
| Атрибут | Обязателен | Описание |
|---|---|---|
data-api-key | Да | Ваш API ключ |
data-token | Да | HMAC-подписанный токен с параметрами проверки |
data-user-id | Нет | Идентификатор пользователя/заказа (по умолчанию "widget-user") |
Генерация токена
Токен генерируется на вашем сервере с использованием вашего API ключа как секрета HMAC. Формат: base64url(JSON).hmac_sha256_hex
Параметры токена (JSON)
| Поле | Тип | Описание |
|---|---|---|
price | number | Минимальная сумма чека (тенге) |
ip_name | string | Название продавца |
iin | string | ИИН/БИН продавца (12 цифр) |
max_age | number | Максимальный возраст чека в днях |
exp | number | Unix timestamp истечения токена |
Python
import hmac, hashlib, base64, json, time
def generate_token(params, api_key):
payload = base64.urlsafe_b64encode(
json.dumps(params).encode()
).rstrip(b'=').decode()
signature = hmac.new(
api_key.encode(), payload.encode(), hashlib.sha256
).hexdigest()
return f"{payload}.{signature}"
token = generate_token({
"price": 5000,
"iin": "123456789012",
"max_age": 7,
"exp": int(time.time()) + 3600 # 1 час
}, "ВАШ_API_KEY")
Node.js
const crypto = require('crypto');
function generateToken(params, apiKey) {
const payload = Buffer.from(JSON.stringify(params))
.toString('base64url');
const signature = crypto
.createHmac('sha256', apiKey)
.update(payload)
.digest('hex');
return `${payload}.${signature}`;
}
const token = generateToken({
price: 5000,
iin: '123456789012',
max_age: 7,
exp: Math.floor(Date.now() / 1000) + 3600
}, 'ВАШ_API_KEY');
PHP
function generateToken(array $params, string $apiKey): string {
$payload = rtrim(strtr(base64_encode(
json_encode($params)
), '+/', '-_'), '=');
$signature = hash_hmac('sha256', $payload, $apiKey);
return "{$payload}.{$signature}";
}
$token = generateToken([
'price' => 5000,
'iin' => '123456789012',
'max_age' => 7,
'exp' => time() + 3600,
], 'ВАШ_API_KEY');
Kommo CRM виджет
Виджет для автоматизации приёма оплаты через Kaspi в Kommo CRM. Проверка чеков, валидация суммы и продавца, автоматическое продвижение сделок по воронке — всё без участия менеджера.
Публичный виджет в маркетплейсе Kommo пока недоступен. На данный момент виджет устанавливается приватно — мы настроим интеграцию под ваш аккаунт Kommo.
Возможности
- Проверка чеков Kaspi прямо из карточки сделки
- Автоматическая валидация суммы, продавца и срока давности
- Результат проверки сохраняется в примечаниях сделки
- Автоматизация приёма оплаты — настройте воронки в Kommo, чтобы сделки автоматически двигались по этапам после подтверждения оплаты
Заказать установку
Для подключения виджета к вашему Kommo аккаунту свяжитесь с нами:
Заказать установку → @sanzharНапишите в Telegram — обсудим детали и настроим виджет под ваш аккаунт.