Кому это нужно
- Ремонт и услуги — лист вкладывается в акт выполненных работ.
- Доставка — лист кладётся в коробку с заказом.
- Договор или квитанция — QR печатается прямо на документе.
- Витрина, прилавок, столик — лист стоит рядом с товаром.
Общее у всех сценариев одно: платить будут не сейчас и не при вас.
Что видит покупатель
[ бумажный лист ] [ телефон ] [ Kaspi ]
Наведите камеру Магазин «Пример» Оплата
███ ███ ███ → 45 000 ₸ → 45 000 ₸
███ ▄▄▄ ███ Ремонт машины [Оплатить]
45 000 ₸ [Открыть Kaspi]
- Наводит обычную камеру на QR — ту, которой фотографируют.
- Открывается страница с названием вашего магазина и суммой.
- Нажимает «Открыть Kaspi» и платит в приложении как обычно.
- Вам приходит вебхук счёта, покупателю — подтверждение.
Если приложение Kaspi не открылось, на той же странице есть запасной путь: покупатель вводит свой номер телефона и получает пуш-запрос на оплату. Создаётся обычный счёт по номеру (is_qr_token: false) с тем же external_order_id; повторная отправка того же номера второго счёта не создаёт.
Почему «наведите камеру», а не «отсканируйте в Kaspi»
Встроенный сканер в приложении Kaspi не откроет адрес листа как платёж — он принимает только ссылки самого Kaspi. Покупатель, которому сказали «сканируйте в Kaspi», упрётся в тупик.
Правильная формулировка ровно одна: «Наведите камеру телефона на этот код». Она напечатана на самом листе — не пересказывайте её своими словами.
Как сделать
Коды создаются через API — POST /api/v1/static-qr. Тело запроса такое же, как у счёта:
curl -X POST https://api.apipay.kz/api/v1/static-qr \
-H "X-API-Key: ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{
"amount": 45000,
"description": "Ремонт стиральной машины",
"external_order_id": "deal_1024"
}'
В ответе — картинка QR, короткий код и адрес, куда этот код вводят:
{
"id": 77,
"token": "9f1c…",
"short_code": "K7MP2XQ4",
"print_url": "https://qr.apipay.kz/9f1c…",
"manual_url": "https://qr.apipay.kz",
"qr_image_url": "https://…/storage/static-qr/….png",
"amount": "45000.00",
"status": "active",
"paid": false,
"scan_count": 0
}
Сумму листа берите целой в тенге: покупатель может выбрать оплату по номеру телефона, а такой счёт принимает только целые тенге — при дробной сумме оплата по номеру не пройдёт. Оплата сканированием QR дробную сумму принимает.
Организация с каталогом печатный лист сделать может, но обязана передать cart_items вместо amount — как при создании QR-счёта; запрос одной суммой вернёт 422 с error_code: catalog_requires_cart_items. description — до 100 символов, это ограничение Kaspi на имя позиции.
⚠️ Описание листа задаётся один раз — у уже выпущенного листа изменить его нельзя. Это важно из-за запасного пути: оплата по номеру телефона уходит обычным счётом, а у такого счёта описание с 5 сентября 2026 не длиннее 60 символов (организациям, зарегистрированным с 26 августа 2026, — уже сейчас). Оплата сканированием QR не затрагивается — там прежний лимит 100. Поэтому слишком длинное описание отбивается прямо при выпуске листа — 422 description_too_long: лист, у которого оплата по номеру не сработала бы, просто не создастся. У уже напечатанного листа с длинным описанием путь один — отключить его (DELETE /api/v1/static-qr/{id}) и напечатать новый.
⚠️ Если каталог у вас пока выключен, а Kaspi Касса есть — печатать листы одной суммой сейчас можно, но в момент включения каталога уже напечатанные листы перестанут работать, а переиздать их нельзя. Порядок перехода и что сказать нам заранее — в статье Переход на каталог товаров.
⚠️ Ссылка листа (print_url) и её token — это и есть доступ к оплате: они зашиты в QR-код. Значит, открыть страницу оплаты этой сделки сможет любой, у кого есть лист или его фотография. Печатайте лист под конкретную сделку и не выкладывайте его туда, где он не нужен; в логи и переписку кладите id и external_order_id, а не токен. Если лист ушёл не тому — отключите его (DELETE /api/v1/static-qr/{id}) и напечатайте новый.
Если разработчика нет — напишите в поддержку из кабинета, раздел «QR для печати»: расскажете, где и как вам удобно размещать код, и мы настроим печать под ваш случай.
Как разместить код на своём бланке
Если вы верстаете свой ценник, договор или наклейку, соблюдайте шесть правил — иначе камера покупателя код не возьмёт:
- Не меньше 3 см по стороне. Мелкий код не считывается с расстояния вытянутой руки, а сканируют именно так.
- Оставьте поля вокруг. Белая рамка шириной примерно в четыре квадратика самого кода.
- Только чёрный на белом. Без цветного фона, фотографий и градиентов под кодом; цвета не инвертировать.
- Подпишите код. Рядом обязательно «Наведите камеру телефона» — без этой строки покупатель полезет в приложение Kaspi.
- Напечатайте короткий код и адрес рядом. Если камера не возьмёт — мятая бумага, блик, старый телефон — покупатель введёт код руками на qr.apipay.kz. Печатайте рядом с кодом и сам адрес: без него покупатель видит код, но не знает, куда его вводить.
- Не растягивайте и не перекрывайте. Код должен остаться квадратным; печать или подпись поверх делают его нечитаемым.
Один лист — одна сделка
По умолчанию лист одноразовый: после оплаты он закрывается, и повторный скан показывает покупателю «Оплачено». На новую сделку печатается новый лист.
Если сделка отменилась или сумма изменилась — отключите лист (DELETE /api/v1/static-qr/{id}) и напечатайте новый. Уже созданные по листу счета при этом не отменяются.
Частые вопросы
Сколько живёт напечатанный лист?
Месяцами. Срок годности задаётся полем expires_at при создании листа (дата в будущем); без него лист живёт, пока его не оплатят или не отключат.
Что если камера совсем не берёт код?
Покупатель открывает qr.apipay.kz в браузере телефона и вводит напечатанный на листе код из восьми символов — попадает на ту же страницу оплаты. Регистр, дефисы и пробелы в коде значения не имеют.
Что если кассир отключился?
Лист напечатается и без подключённого кассира — их печатают заранее. Но при скане счёт не создастся, поэтому кассира нужно подключить до того, как лист попадёт покупателю. ⚠️ Если у организации несколько активных кассиров и нет основного, создание листа отобьётся сразу: 422 connection_ambiguous — передайте kaspi_connection_id явно. Чужой или неактивный kaspi_connection_id тоже даёт 422, а не 404.
Как я узнаю, что по листу заплатили?
Обычным вебхуком счёта (invoice.status_changed) — отдельного события у листа нет.
Работает ли лист без интернета у покупателя?
Нет: камера открывает страницу оплаты в браузере, а дальше нужен Kaspi. Интернет покупателю необходим.