API · v1

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

Tolemflow проверяет фискальные чеки Kaspi Pay и отвечает боту, можно ли выдавать товар. Один запрос — одна проверка.

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

Зарегистрируйтесь в кабинете: сразу после регистрации вы получите API-ключ и 50 бесплатных проверок в месяц.

Базовый адресhttps://tolemflow.kz/api
АвторизацияЗаголовок X-API-Key: krv_…
ФорматJSON в UTF-8; для файлов — multipart/form-data
Ключ даёт доступ к проверкам вашего проекта. Храните его на сервере бота, не публикуйте в коде клиентских приложений и в открытых репозиториях.

Проверка по ссылке

POST/receipts/validate-url

Основной метод: покупатель присылает ссылку из чека Kaspi (её же содержит QR-код чека).

ПолеТипОписание
receiptUrlстрока, обязательноСсылка на чек, например https://receipt.kaspi.kz/web/fiscal?i=…
userIdстрокаID покупателя в боте (Telegram ID). Нужен для истории и защиты от повторов
purchaseIdстрокаВаш номер заказа
expectedAmountчислоСумма, которую вы ждёте, в тенге. Если в чеке другая — чек отклоняется
expectedSellerстрокаИИН/БИН (12 цифр) или название продавца. Если не передать, используется ИИН/БИН из настроек проекта
metadataобъектЛюбые ваши данные, вернутся в вебхуке
# pip install aiohttp
import aiohttp

async def check_receipt(receipt_url: str, user_id: int, order_id: str, price: int) -> dict:
    async with aiohttp.ClientSession() as s:
        async with s.post(
            "https://tolemflow.kz/api/receipts/validate-url",
            headers={"X-API-Key": TOLEMFLOW_KEY},
            json={"receiptUrl": receipt_url, "userId": str(user_id),
                  "purchaseId": order_id, "expectedAmount": price},
        ) as r:
            return await r.json()

Проверка по файлу

POST/receipts/validate

Для PDF или фото чека с QR-кодом: Tolemflow распознаёт QR и проверяет чек так же, как по ссылке. Форматы: PDF, JPG, PNG, до 10 МБ.

Запрос — multipart/form-data: поле file и те же поля, что выше (userId, purchaseId, expectedAmount, expectedSeller; metadata — строкой JSON). Поля передавайте до файла.

curl -X POST https://tolemflow.kz/api/receipts/validate \
  -H "X-API-Key: $TOLEMFLOW_KEY" \
  -F userId=518204771 -F expectedAmount=500 \
  -F file=@receipt.pdf

Файлы удаляются сразу после проверки.

Ответы и ошибки

Чек принят — выдавайте товар

HTTP 200
{
  "success": true, "isValid": true, "isDuplicate": false,
  "message": "Чек успешно подтвержден",
  "receiptId": "5b0c…",
  "data": { "sum": 500, "seller": "ИП …", "sellerIIN": "…",
            "receiptNumber": "QR17810724392", "dateTime": "2026-09-27 23:35:22" }
}

Чек уже использовали

HTTP 200
{ "success": false, "isDuplicate": true, "message": "…Этот чек уже был использован ранее для оплаты…" }

Чек не прошёл проверку

HTTP 400
{ "success": false, "message": "Сумма в ссылке не совпадает с суммой в чеке" }

Текст в message можно показать покупателю: он объясняет, что не так с чеком.

КодЧто случилосьЧто делать
200Проверка выполненаСмотрите success и isDuplicate
400Чек не прошёл проверку или запрос некорректенПокажите покупателю message
401Нет ключа или ключ неверныйПроверьте заголовок X-API-Key
402Закончились проверки бесплатного тарифа (error: "limit_reached")Выберите тариф в кабинете
429Слишком много запросов в минутуПовторите позже
5xxВременная ошибка на нашей стороне или у KaspiПовторите через несколько секунд

Другие методы

POST/receipts/check-duplicate

Проверяет, использовался ли чек, не засчитывая его. Тело: {"receiptIdentifier": "QR17810724392"} — номер чека. Ответ: {"success": true, "isDuplicate": false}.

GET/receipts/{id}

Возвращает проверенный чек по receiptId из ответа. Доступны только чеки вашего проекта.

Вебхуки

Укажите адрес в кабинете (Проекты → Вебхук), и Tolemflow будет отправлять результат каждой проверки POST-запросом. Удобно, если чеки проверяет один сервис, а заказы обрабатывает другой.

СобытиеКогда
receipt.acceptedЧек принят
receipt.duplicateЧек уже использовали
receipt.rejectedЧек не прошёл проверку
pingТест из кабинета
POST https://your-bot.example.com/tolemflow
X-Tolemflow-Event: receipt.accepted
X-Tolemflow-Delivery: 6f0e…
X-Tolemflow-Timestamp: 1790540000
X-Tolemflow-Signature: sha256=…

{ "id": "6f0e…", "event": "receipt.accepted", "createdAt": "2026-09-28T09:00:00Z", "projectId": "…",
  "data": { "receiptId": "…", "status": "accepted", "amount": 500, "seller": "ИП …",
            "receiptNumber": "QR…", "userId": "518204771", "purchaseId": "order-1042", "metadata": {} } }

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

Подпись — HMAC-SHA256 от строки timestamp.тело с секретом из кабинета. Проверяйте её и отклоняйте события старше 5 минут.

# Python
import hmac, hashlib, time

def verify(headers, raw_body: bytes, secret: str) -> bool:
    ts = headers["X-Tolemflow-Timestamp"]
    expected = "sha256=" + hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256).hexdigest()
    fresh = abs(time.time() - int(ts)) < 300
    return fresh and hmac.compare_digest(expected, headers.get("X-Tolemflow-Signature", ""))
// Node.js
const crypto = require("crypto");
function verify(headers, rawBody, secret) {
  const ts = headers["x-tolemflow-timestamp"];
  const expected = "sha256=" + crypto.createHmac("sha256", secret).update(ts + "." + rawBody).digest("hex");
  const got = headers["x-tolemflow-signature"] || "";
  return Math.abs(Date.now() / 1000 - Number(ts)) < 300 && got.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(got));
}

Доставка и повторы

  • Ответьте кодом 2xx в течение 10 секунд. Редиректы не выполняются.
  • При ошибке отправка повторяется через 1, 5, 30 минут, 2 и 6 часов. Журнал доставок и кнопка повтора — в кабинете.
  • Одно событие может прийти дважды: используйте id или X-Tolemflow-Delivery, чтобы не обработать его повторно.
  • Адрес должен начинаться с https://; внутренние и локальные адреса не принимаются.

Лимиты

  • Проверки по тарифу. Проверка — любой запрос к validate или validate-url. На бесплатном тарифе после 50 проверок в месяц ответ — 402, на платных проверки продолжаются сверх пакета.
  • Частота. По умолчанию до 100 запросов в минуту на ключ. Нужно больше — напишите нам.
  • Проекты. Число проектов зависит от тарифа, у каждого проекта свои ключи.

Как защититься лучше

  • Укажите ИИН/БИН продавца в настройках проекта: чек, оплаченный другому продавцу, будет отклонён.
  • Передавайте expectedAmount: чек на меньшую сумму не пройдёт.
  • Передавайте userId и purchaseId: так проще разбирать спорные случаи в кабинете.
  • Включите уведомления в Telegram, чтобы узнавать о попытках обмана сразу.
Есть вопросы по подключению? Напишите нам в Telegram.