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

Покупатель присылает боту PDF-чек из приложения Kaspi, бот передаёт файл в Tolemflow. Только PDF, до 10 МБ. Файлы удаляются сразу после проверки.

Фото и скриншоты не принимаются: их легко подделать. Попросите покупателя отправить PDF-чек из приложения Kaspi.

Запрос — multipart/form-data: поле file и необязательные поля ниже (metadata — строкой JSON). Поля передавайте до файла.

ПолеТипОписание
fileфайлPDF-чек из приложения Kaspi
userIdстрокаID покупателя в боте (Telegram ID). Нужен для истории и защиты от повторов
purchaseIdстрокаВаш номер заказа
expectedAmountчислоСумма, которую вы ждёте, в тенге. Если в чеке другая — чек отклоняется
expectedSellerстрокаИИН/БИН (12 цифр) или название продавца. Если не передать, используется ИИН/БИН из настроек проекта
metadataобъектЛюбые ваши данные, вернутся в вебхуке
# pip install aiohttp
import aiohttp

async def check_receipt(pdf: bytes, user_id: int, order_id: str, price: int) -> dict:
    form = aiohttp.FormData()
    form.add_field("userId", str(user_id))
    form.add_field("purchaseId", order_id)
    form.add_field("expectedAmount", str(price))
    form.add_field("file", pdf, filename="receipt.pdf", content_type="application/pdf")
    async with aiohttp.ClientSession() as s:
        async with s.post("https://tolemflow.kz/api/receipts/validate",
                          headers={"X-API-Key": TOLEMFLOW_KEY}, data=form) as r:
            return await r.json()

Если бот не умеет отправлять файлы

Конструкторы ботов обычно дают публичную ссылку на присланный файл. Отправьте на тот же адрес JSON, где вместо file — поле fileUrl со ссылкой на PDF: Tolemflow сам скачает файл.

curl -X POST https://tolemflow.kz/api/receipts/validate \
  -H "X-API-Key: $TOLEMFLOW_KEY" -H "Content-Type: application/json"   -d '{"fileUrl":"<ссылка на PDF-файл>","userId":"518204771","expectedAmount":500}'

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

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

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": "❌ Неверная сумма платежа. Ожидалось: 500 ₸, получено: 300 ₸" }

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

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

Конструкторы ботов

Для Salebot и других конструкторов, которые умеют отправлять HTTP-запросы с JSON:

  • Ответ всегда с кодом 200. Добавьте к адресу ?always200=1: при отказе ответ придёт с кодом 200, success: false, причиной в message и исходным кодом в httpStatus. Многие конструкторы не читают тело ответа с кодом 4xx.
  • PDF по ссылке. Если конструктор даёт ссылку на присланный файл, передайте её в fileUrl — Tolemflow сам скачает PDF.
  • Числа строками. expectedAmount, userId и purchaseId можно передавать строками: "24900".
  • Повтор по тому же заказу. Если тот же чек пришёл повторно с теми же purchaseId и userId в течение 15 минут, проверка не спишется, а в ответе будут success: false и replayed: true. Товар второй раз выдавать не нужно: оплата уже засчитана первым ответом. Если первый ответ до вас не дошёл из-за обрыва связи, replayed: true означает, что чек принят.

Пошаговая инструкция: Salebot.

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

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. На бесплатном тарифе после 50 проверок в месяц ответ — 402, на платных проверки продолжаются сверх пакета.
  • Частота. По умолчанию до 100 запросов в минуту на ключ. Нужно больше — напишите нам.
  • Проекты. Число проектов зависит от тарифа, у каждого проекта свои ключи.

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

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