# Приём по QR на офлайн-точке

> Кассир показывает динамический QR на экране, клиент сканирует. Окно сканирования ограничено — время берите из поля expiresAt. Когда удобнее QR, когда счёт на телефон и как разделить несколько точек.

## Коротко

В магазине, мастерской или кофейне порядок простой: кассир вводит сумму, на экране появляется QR, клиент сканирует его приложением Kaspi, после подтверждения кассир видит на экране «оплачено». QR создаётся заново под каждый платёж — это динамический QR, и окно сканирования у него ограничено. Задать это время самому нельзя, его нужно читать из поля `expiresAt`.

## Сценарий

На кассе очередь. Клиент должен заплатить 4 500 ₸. Терминала нет либо нужен дополнительный способ оплаты помимо него.

Кассир вводит сумму с планшета или компьютера, на экране появляется QR, клиент достаёт телефон и сканирует, видит сумму в приложении Kaspi и подтверждает. Через несколько секунд на экране кассира появляется «Оплачено». Деньги приходят напрямую на Kaspi-счёт магазина.

## Схема работы по шагам

1. **Кассир вводит сумму** — в кабинете, в собственной кассовой программе или через Telegram-бота.
2. **Создаётся счёт.** `POST /api/v1/invoices`, `kind: "qr"` (по умолчанию). В ответе приходят `qrUrl`, `qrImageUrl`, `deepLink`, `payUrl` и `expiresAt`.
3. **QR показывается на экране** — планшет, монитор, чековый принтер, что удобнее.
4. **Клиент сканирует** приложением Kaspi, видит сумму, подтверждает.
5. **Статус обновляется.** Приходит вебхук `invoice.paid`, либо ваша кассовая страница опрашивает статус. На практике это занимает несколько секунд после подтверждения.
6. **Кассир видит подтверждение** и отдаёт товар.

## Какие методы API нужны

| Что делает | Метод |
|---|---|
| Создать QR-счёт | `POST /api/v1/invoices`, `kind: "qr"` |
| Счёт на телефон | `POST /api/v1/invoices`, `kind: "phone"`, `customer.phone` |
| Запросить статус | `GET /api/v1/invoices/{id}` |
| Клиент передумал | `POST /api/v1/invoices/{id}/cancel` |
| Товар вернули | `POST /api/v1/invoices/{id}/refund` |
| Узнать об оплате | Вебхук `invoice.paid` |

На кассе важно узнать статус быстро, поэтому лучше вести вебхук и опрос одновременно: вебхук как основной канал, а экран кассира раз в несколько секунд запрашивает `GET /invoices/{id}`. Подробнее: [Вебхук или опрос статуса](/kb/ru/polling-vs-webhook).

## Окно сканирования ограничено

Это самая частая проблема на кассе. QR живёт не вечно — у него есть окно сканирования, которое задаёт Kaspi. Когда окно заканчивается, при сканировании клиент видит сообщение «попробуйте позже».

Что делать:

- **Берите время из поля `expiresAt`.** Не зашивайте константу в код — окно определяется на стороне Kaspi.
- **Показывайте обратный отсчёт на экране.** И кассир, и клиент должны видеть, сколько осталось.
- **Обновляйте QR по истечении окна.** Старый счёт закрываете через `cancel` и создаёте новый. Клиент сканирует заново.
- **Не печатайте картинку QR заранее.** Динамический QR создаётся под каждый платёж.

Если клиент не успел отсканировать: [QR показывает «попробуйте позже»](/kb/ru/qr-expired).

## Когда QR, а когда счёт на телефон

| Ситуация | Что выбрать |
|---|---|
| Клиент стоит перед кассой | QR — быстро, номер телефона не нужен |
| Клиент не видит экран (окошко, коридор, склад) | Счёт на телефон |
| Камера телефона не работает, экран бликует | Счёт на телефон |
| Заказ сделали заранее по телефону | Счёт на телефон |
| У клиента нет приложения Kaspi | QR или ссылка `payUrl` |
| В сумме есть тиыны | QR (у счёта на телефон нужны целые тенге) |
| Описание длинное | QR — 100 символов, счёт на телефон — 60 |

При отправке счёта на телефон `customer.phone` должен быть в формате `7XXXXXXXXXX`. Полная разница: [QR-счёт или счёт по телефону](/kb/ru/qr-vs-phone).

## Есть ли вариант без кода

Есть, три:

- **Счёт из кабинета.** Заходите в [кабинет](https://qut.kz/app), в разделе **Счета** создаёте счёт, на экране появляется QR. Кассир вполне может работать так с планшета.
- **Telegram-бот.** Командой `/invoice` создаёте счёт, `/today` показывает итоги дня, `/last` — последние счета. Ставить на кассу компьютер не нужно, всё работает с телефона.
- **Ссылка на оплату.** С фиксированной или открытой суммой. Её QR можно распечатать и положить на кассе, но это постоянная ссылка — сумму вводит клиент.

Для полной автоматизации (встраивания в кассовую программу) нужен API.

## Если точек несколько

Заведите **отдельный API-ключ на каждую точку**. Причины:

- в отчётности видно, с какой точки пришёл платёж;
- если один ключ утечёт, вы удалите только его и не тронете остальные;
- ключ можно привязать к конкретному кассиру — тогда он не увидит счета других кассиров (на чужой счёт вернётся 404).

Месячный лимит остаётся общим для организации и по точкам не делится — при выборе тарифа считайте суммарный объём всех точек. Подробнее: [Раздельная отчётность по точкам](/kb/ru/multi-point-reporting).

В Kaspi можно подключить и несколько кассиров, каждый — отдельное подключение: [Можно ли подключить несколько кассиров](/kb/ru/two-cashiers).

## Особые замечания

- **Не входите в приложение Kaspi Pay с номера кассира.** Kaspi разрешает одному кассиру только одно активное устройство — при входе привязка оборвётся и создание счетов остановится.
- **Номер кассира виден клиенту** в уведомлении о счёте. Это нормальная работа Kaspi, поэтому лучше, чтобы это был не ваш личный номер.
- **Нужен интернет.** Если связь на точке пропала, счёт не создастся. На кассе стоит держать запасной мобильный интернет.
- **Помните про суточную защиту.** Это не бизнес-лимит, а предохранитель от интеграции, ушедшей в цикл, но при ошибке в кассовой программе вы упрётесь именно в него.
- **Поздние оплаты случаются.** Если деньги придут по просроченному счёту, событие `invoice.paid` придёт с признаком `late: true`. Тогда выдайте товар или верните деньги.
- **Сначала проверьте в песочнице.** С ключом `qp_test_…` реальный Kaspi не вызывается, оплату вы симулируете сами.

## Вопросы и ответы

**Можно один раз напечатать QR и наклеить на кассе?** Динамический — нет, он создаётся под каждый платёж. Если нужна постоянная наклейка, используйте QR ссылки на оплату, но тогда сумму вводит клиент.

**Клиент отсканировал, а у кассира всё ещё «не оплачено».** Подтверждение занимает несколько секунд. Если прошло несколько минут, сначала проверьте, что вы не в тестовом режиме: [Оплата не приходит покупателю](/kb/ru/payment-not-arriving).

**Когда приходят деньги?** Напрямую на Kaspi-счёт магазина, в момент оплаты. У нас они не задерживаются.

**Можно ли использовать двух кассиров на одной точке?** Да, каждый кассир — отдельное подключение. Если привязать ключ к кассиру, отчётность тоже разделится.

**Что делать, если пропал интернет?** Создать счёт не получится. Лучше заранее подготовить резервный канал связи.
