Оплата Kaspi по ссылке: как отправить покупателю ссылку

Обновлено 3 сентября 2026 · Справочник · Версия в Markdown
Содержание
  1. Три способа получить оплату
  2. Когда какая ссылка подходит
  3. Как получить ссылку на оплату
  4. Ссылка перестала открываться — что делать
  5. Как понять, что покупатель заплатил
  6. Что нужно знать до первого запроса
  7. Долгоживущая ссылка: печатный лист под сделку
  8. А поле kaspi_qr_link — это тоже ссылка?
  9. Как это выглядит в кабинете
  10. Вопросы и ответы

Три способа получить оплату

Счёт по номеру Оплата по ссылке или QR Печатный QR под сделку
Эндпоинт POST /invoices POST /invoices/qr POST /static-qr
Что уходит покупателю Ничего не отправляете: приходит push в Kaspi Ссылка qr_token_url или картинка qr_image_url Ссылка print_url или напечатанный лист
Нужен номер покупателя Да, 8XXXXXXXXXX Нет Нет
Сколько ждёт оплату 24 часа До qr_expires_at — окно задаёт Kaspi Пока не оплачен или не отключён
Когда выбирать Покупатель «где-то там», реагирует на push Покупатель в чате или у экрана прямо сейчас Платить будут потом: акт, коробка, договор, витрина

Одно простое правило: ссылка «сейчас» — qr_token_url, ссылка «потом» — print_url, без ссылки вовсе — счёт по номеру телефона.

Когда какая ссылка подходит

  • Магазин в Instagram или WhatsApp. Покупатель написал, договорились о сумме — отправляете qr_token_url прямо в переписку, он открывает и платит, не выходя из чата. Если разговор оборвался и покупатель вернулся через час, ссылка уже не сработает: выставьте новую.
  • Доставка. Курьер у двери — qr_token_url в чат или QR на экране телефона курьера. Если заказ оставляют у двери и оплата ожидается позже, в коробку кладётся печатный лист (print_url).
  • Чат с покупателем и переписка по сделке. Сумма согласована — ссылка уходит одним сообщением. Ссылку удобно сопровождать суммой текстом: покупатель увидит её и на странице оплаты.
  • Услуги и работы по акту. Оплату ждут после приёмки — печатный лист под сделку. Он лежит в документах и работает через неделю так же, как в день выпуска.
  • Сайт или бот без своего сервера. API-ключ — серверный секрет, в код, исполняемый в браузере, его класть нельзя. Пока сервера нет, выставляйте счёт в кабинете и отправляйте ссылку руками; когда сервер появится, тот же сценарий переносится в POST /invoices/qr без изменений для покупателя. Разбор по площадкам — «ApiPay для интернет-магазина» и «Kaspi-оплата в Telegram-боте».

Как получить ссылку на оплату

curl -X POST https://api.apipay.kz/api/v1/invoices/qr \
  -H "X-API-Key: ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5000,
    "description": "Заказ №123",
    "external_order_id": "order-123"
  }'

Ответ приходит сразу — 201 со статусом pending:

{
  "id": 1,
  "amount": "5000.00",
  "status": "pending",
  "is_qr_token": true,
  "qr_token_url": "https://qr.kaspi.kz/...",
  "qr_image_url": "https://.../storage/qr/abc.png",
  "qr_expires_at": "2026-09-03T07:03:00+00:00"
}
  • qr_token_url — это и есть ссылка на оплату. Отправьте её покупателю в мессенджер: он открывает её на телефоне, где установлено приложение Kaspi, и платит там — сканировать ничего не нужно. Открытая на компьютере ссылка к оплате не приведёт: покажите рядом qr_image_url, чтобы человек навёл на экран телефон.
  • qr_image_url — готовая картинка QR той же оплаты: показывайте её на экране, если покупатель рядом. Рисовать QR самим не нужно.
  • qr_expires_at — момент, до которого ссылку успевают открыть. Считайте остаток как qr_expires_at − now и не зашивайте длительность окна константой: её задаёт Kaspi.

То же самое из кода:

const res = await fetch('https://api.apipay.kz/api/v1/invoices/qr', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.APIPAY_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    amount: 5000,
    description: 'Заказ №123',
    external_order_id: 'order-123',
    external_order_id_idempotency: 'order-123',
  }),
})

const invoice = await res.json()

// Ссылка на оплату — отправляем покупателю в чат
await sendMessage(chatId, `Оплата 5000 ₸: ${invoice.qr_token_url}`)
// invoice.qr_expires_at — до этого момента ссылку успеют открыть

Ключ X-API-Key живёт только на сервере. Ссылку покупателю отправляет ваш код, а не браузер покупателя.

Ссылка перестала открываться — что делать

Ничего чинить не нужно: истёкшая ссылка означает ровно одно — покупатель не успел, нужен новый QR-счёт. Продления нет, повторный запрос на тот же заказ создаст новую ссылку. Приложение Kaspi в этот момент показывает покупателю «Попробуйте позже» — разбор этого экрана в статье «QR показывает «Попробуйте позже»».

Если ссылку регулярно не успевают открыть — это сигнал, что сценарий не «сейчас», а «потом»: перенесите его на печатный лист или на счёт по номеру телефона.

Ссылки сосуществуют: новая не отменяет прежние, каждая созданная оплачиваема до своего истечения. Двум покупателям в очереди можно спокойно выдать по своей ссылке.

Как понять, что покупатель заплатил

Ждите вебхук со статусом paid — или, если вебхуков ещё нет, читайте GET /invoices/{id}. Настройка — «Как настроить вебхуки ApiPay».

⚠️ Событие invoice.qr_scanned — не оплата. Оно приходит, когда покупатель открыл оплату: статус счёта остаётся pending, добавляется маркер qr_substate: "scanned". Как и любое событие, оно может продублироваться при повторной доставке — дедуплицируйте по паре (invoice.id, invoice.status). После него возможны и paid, и cancelled — покупатель мог закрыть приложение, не подтвердив. Интерфейс кассы должен уметь вернуться из «Ожидается подтверждение» обратно в исходное состояние.

Отменить QR-счёт нельзя: POST /invoices/{id}/cancel отвечает 409 qr_cancel_unsupported, статус не меняется. Делать при этом ничего не нужно — ссылка гаснет сама и счёт уезжает в expired. Отмена работает у счетов по номеру телефона. Если покупатель успел оплатить счёт с неверной суммой, деньги возвращаются обычным возвратом POST /invoices/{id}/refund, а не отменой.

⚠️ В песочнице отмена ведёт себя иначе: тестовый QR-счёт отменяется как обычный — 200 и статус cancelled. Не калибруйте по этому боевую логику: в рабочем режиме придёт 409 qr_cancel_unsupported. Подробнее — «Сколько живёт QR-счёт».

Что нужно знать до первого запроса

  • Описание — до 100 символов. Это наименование позиции в чеке Kaspi.
  • Частота — до 60 QR в минуту на организацию. Превышение даёт 429 qr_rate_limit; лимит общий на организацию, не на ключ и не на кассира, и действует в том числе в песочнице. Отдельно работает суточный лимит тарифа — «Дневной лимит счетов по тарифу».
  • Организация с каталогом. И ссылку на оплату, и печатный лист такой организации выдаёт только запрос с корзиной: POST /invoices/qr и POST /static-qr с одним amount вернут 422 с error_code: catalog_requires_cart_items. Передавайте cart_items — «Счета с корзиной».
  • Песочница. В тестовом режиме реальных оплат нет; поле simulate (paid, cancelled, expired) позволяет проверить все исходы — «Песочница и рабочий режим».

Долгоживущая ссылка: печатный лист под сделку

Когда платить будут не сейчас, счёт выпускается один раз и ждёт покупателя:

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"
  }'

В ответе — print_url, восьмисимвольный short_code для ручного ввода, manual_url (куда этот код вводят) и qr_image_url — непротухающая картинка QR для печати.

print_url — тоже ссылка на оплату, только долгоживущая. Её зашивают в QR-код на бумаге, но точно так же можно отправить в мессенджер: покупатель откроет страницу с названием магазина и суммой, нажмёт «Открыть Kaspi» и заплатит. Если приложение не открылось, на той же странице есть запасной путь — покупатель вводит свой номер телефона и получает запрос на оплату push-уведомлением. Что видит покупатель на самом счёте в Kaspi — «Что видит покупатель»: сама оплата в обоих случаях проходит в приложении Kaspi.

Лист привязан к одной сделке: после оплаты повторное открытие показывает «Оплачено». Сумма изменилась или сделка отменилась — отключите лист (DELETE /api/v1/static-qr/{id}) и выпустите новый; описание у выпущенного листа не меняется. Ссылка листа и её токен — это и есть доступ к оплате: не выкладывайте лист туда, где он не нужен. Подробности печати и вёрстки — «Печатный QR для оплаты по счёту или сделке».

У обычного счёта по номеру телефона в карточке есть поле kaspi_qr_link — ссылка на оплату этого счёта по QR. Она вычисляется из идентификатора, который Kaspi присваивает счёту, поэтому появляется не сразу: пока счёт в processing, поле null, и в песочнице оно null всегда.

Строить на нём сценарий «отправить покупателю ссылку» не стоит: для этого есть qr_token_url — он приходит сразу в ответе на создание. Про сам счёт по номеру — «Как создать счёт по номеру».

Как это выглядит в кабинете

Разработчик для ссылки не обязателен. В кабинете: Счета → Создать счёт → переключатель «Ссылка или QR-код». Номер покупателя вводить не нужно — достаточно суммы и описания.

После создания под QR-кодом видна сама ссылка, а рядом две кнопки: «Открыть в Kaspi» — проверить, как это выглядит у покупателя, и «Скопировать ссылку» — вставить её в WhatsApp или Telegram.

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

Можно ли отправить ссылку на оплату Kaspi в WhatsApp?

Да. Создайте QR-счёт (POST /invoices/qr) и отправьте покупателю qr_token_url из ответа — на телефоне покупателя она открывает оплату в приложении Kaspi. В кабинете тот же результат даёт кнопка «Скопировать ссылку». Одно условие: покупатель должен открыть ссылку в отведённое окно, поэтому отправляйте её, когда человек на связи.

Сколько живёт ссылка на оплату?

qr_token_url действует до qr_expires_at из ответа — длительность этого окна задаёт Kaspi, поэтому берите поле, а не константу в коде. Продлить нельзя: нужен новый QR-счёт. Ссылка печатного листа (print_url) живёт, пока лист не оплачен, не отключён и не наступил заданный вами expires_at.

Чем оплата по ссылке отличается от печатного QR?

Сроком жизни и сценарием. qr_token_url — для «платим прямо сейчас»: покупатель в чате или у экрана. print_url — для «заплатят потом»: акт, коробка с заказом, договор, витрина. Технически обе ссылки ведут покупателя к одной и той же оплате в приложении Kaspi.

Нужен ли номер телефона покупателя?

Нет. Ни для qr_token_url, ни для print_url номер не нужен — в этом их смысл. Номер требуется только счёту по номеру телефона (POST /invoices), где покупателю приходит push.

Как понять, что по ссылке заплатили?

По вебхуку со статусом paid или запросом GET /invoices/{id}. Событие invoice.qr_scanned означает только, что покупатель открыл оплату: статус остаётся pending, и после скана возможна отмена. Дожидайтесь paid.

Можно ли отменить ссылку, если покупатель передумал?

У QR-счёта отмены нет — POST /invoices/{id}/cancel вернёт 409 qr_cancel_unsupported. Делать ничего не нужно: ссылка перестанет работать сама. Печатный лист отключается запросом DELETE /api/v1/static-qr/{id}.

Интеграция с ИИ

Не настраивайте вручную — поручите ИИ

Скопируйте готовый промпт и вставьте своему ИИ-ассистенту — он настроит интеграцию за вас: получит доступы, создаст тестовый счёт в песочнице и подключит вебхуки. Техническую часть делает ИИ, а не вы.

Остались вопросы — напишите нам в WhatsApp: +7 700 307 65 12. Отвечаем быстро, без звонков.

Написать в WhatsApp

Для разработчика. Полная спецификация API — apipay.kz/docs. Эта статья в Markdown — /guides/oplata-po-ssylke-kaspi.md. Справочник фактов для ИИ-агента — apipay.kz/llms.txt.