ДокументацияВведение
Коды ошибок

Приём платежей

Платёжные ссылки

Создать оплату одним POST-запросом

Платёжная ссылка — это готовая страница оплаты Kaspi Pay, которую вы создаёте одним запросом POST /v2/payment-links и отправляете плательщику в мессенджере, письме или счёте. В ответ приходит короткий публичный URL вида https://paybot.kz/checkout/{token} и картинка QR-кода — покупатель открывает ссылку, платит в Kaspi, а вы получаете вебхук об оплате. Ни своей страницы оплаты, ни интеграции с QR вручную не требуется.

Платёжные ссылки работают поверх Hosted Checkout — публичной страницы PayBot, которая сама выдаёт свежий Kaspi QR при каждом открытии. Это делает ссылку пригодной и для онлайн-оплаты (кнопка в интернет-магазине), и для офлайна (напечатанный QR на кассе).

Как создать платёжную ссылку

Отправьте POST /v2/payment-links с суммой в тенге и описанием заказа. Эндпоинт принимает и API-ключ (X-API-Key), и JWT-токен кабинета (Authorization: Bearer) — используйте тот способ авторизации, что уже есть под рукой.

Обязательные поля тела — только amount (целое число тенге) и description (1–500 символов). Остальное опционально и имеет разумные значения по умолчанию.

bash
Скачать
curl -X POST https://api.paybot.kz/v2/payment-links \
  -H "X-API-Key: kp_live_00112233445566778899aabbccddeeff" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 5f9c1e2a-7b3d-4c8e-9a1f-2d6b8c0e4a11" \
  -d '{
    "amount": 5000,
    "description": "Заказ #1234",
    "success_url": "https://shop.example/success",
    "cancel_url": "https://shop.example/cancel",
    "expires_in_minutes": 1440,
    "allow_repeat": false,
    "email_required": false,
    "metadata": {"order_id": "1234"}
  }'
python
Скачать
import requests, uuid

resp = requests.post(
    "https://api.paybot.kz/v2/payment-links",
    headers={
        "X-API-Key": "kp_live_00112233445566778899aabbccddeeff",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "amount": 5000,
        "description": "Заказ #1234",
        "success_url": "https://shop.example/success",
        "cancel_url": "https://shop.example/cancel",
        "metadata": {"order_id": "1234"},
    },
)
link = resp.json()
print(link["url"])          # https://paybot.kz/checkout/pl_abc123
print(link["qr_image_url"]) # PNG для печати

Пример ответа 200 OK:

json
Скачать
{
  "id": 1024,
  "token": "pl_abc123",
  "url": "https://paybot.kz/checkout/pl_abc123",
  "qr_image_url": "https://api.qrserver.com/v1/create-qr-code/?size=600x600&data=https://paybot.kz/checkout/pl_abc123",
  "kaspi_qr_image_url": "https://api.qrserver.com/v1/create-qr-code/?size=600x600&data=3010...",
  "deep_link": "https://qr.kaspi.kz/pay/abc123",
  "amount": 5000,
  "description": "Заказ #1234",
  "status": "active",
  "success_url": "https://shop.example/success",
  "cancel_url": "https://shop.example/cancel",
  "expires_at": "2026-07-17T10:00:00Z",
  "qr_expires_at": "2026-07-16T10:05:00Z",
  "allow_repeat": false,
  "email_required": false,
  "metadata": {"order_id": "1234"},
  "created_at": "2026-07-16T10:00:00Z"
}

Какие поля принимает запрос

ПолеТипОбязательноНазначение
amountintegerдаСумма в тенге (₸), целое число.
descriptionstring (1–500)даОписание заказа, видно плательщику.
success_urlstring (≤2048)нетКуда вернуть покупателя после оплаты.
cancel_urlstring (≤2048)нетКуда вернуть при отмене или истечении.
expires_in_minutesinteger (5–43200)нетСрок жизни ссылки, по умолчанию 1440 (24 часа), максимум 30 дней.
allow_repeatbooleanнетРазрешить несколько успешных оплат по одной ссылке (по умолчанию false).
email_requiredbooleanнетСпросить email плательщика перед оплатой.
metadataobjectнетПроизвольный JSON — вернётся в вебхуке об оплате.

Все суммы — целые тенге; тиынов на входе и выходе нет. Поле metadata удобно для связки платежа с заказом в вашей системе: то, что вы положили сюда, придёт обратно в теле вебхука payment.completed.

Что означает поле status

Статус ссылки описывает её жизненный цикл и приходит в поле status.

СтатусЗначение
activeСсылка активна, оплата возможна.
paidСсылка оплачена (для allow_repeat: false — финальный статус).
expiredИстёк expires_at, оплата больше невозможна.
cancelledСсылка отменена вами вручную.

Не опрашивайте статус ссылки в цикле сами — для отслеживания оплаты используйте вебхуки payment.completed, а для страницы оплаты покупателя статус уже опрашивает Hosted Checkout.

Короткая публичная ссылка и QR для печати

Поле url в ответе — это и есть короткая ссылка на страницу оплаты: https://paybot.kz/checkout/{token}. Её можно слать в WhatsApp, Telegram, SMS или вставлять кнопкой на сайт — открыв её, покупатель попадает на брендированную страницу оплаты.

Поле qr_image_url возвращает PNG QR-кода, который кодирует ту же постоянную ссылку paybot.kz/checkout/{token}. Этот QR статичен: его можно один раз напечатать и наклеить на кассу или витрину, а страница внутри при каждом открытии выдаёт свежий одноразовый Kaspi QR. Поле kaspi_qr_image_url — это, наоборот, текущий динамический Kaspi QR (одноразовый), а deep_link открывает приложение Kaspi напрямую на телефоне.

Для печатной наклейки на кассу берите qr_image_url (постоянный), а не kaspi_qr_image_url (протухнет через ~5 минут).

Как разрешить несколько оплат по одной ссылке

Установите allow_repeat: true, чтобы одну ссылку можно было оплатить много раз — это сценарий «ссылка-донат» или «оплата на витрине», когда по одному URL платят разные люди. При этом ссылка не переходит в финальный paid после первой оплаты, а остаётся active до истечения expires_at.

Для таких ссылок на странице оплаты важно передавать идентификатор конкретного цикла оплаты — подробнее в разделе Hosted Checkout, где описан параметр op.

Как изменить или продлить ссылку

PATCH /v2/payment-links/{token} меняет description, success_url, cancel_url, expires_at и allow_repeat. Продление expires_at из состояния expired снова делает ссылку active.

bash
Скачать
curl -X PATCH https://api.paybot.kz/v2/payment-links/pl_abc123 \
  -H "X-API-Key: kp_live_00112233445566778899aabbccddeeff" \
  -H "Content-Type: application/json" \
  -d '{"expires_at": "2026-07-20T10:00:00Z", "description": "Заказ #1234 (продлён)"}'

Редактирование запрещено, если ссылка уже в статусе paid или cancelled и при этом allow_repeat: false — в ответ придёт 409 payment_link_immutable. Заранее блокируйте кнопку редактирования по текущему status, чтобы не ловить эту ошибку.

Чтобы выдать свежий Kaspi QR, не меняя саму ссылку, используйте POST /v2/payment-links/{token}/refresh-qr — он работает только при status == "active", иначе вернёт 409 payment_link_not_active.

Как отменить платёжную ссылку

POST /v2/payment-links/{token}/cancel переводит ссылку в статус cancelled — после этого оплатить её нельзя.

bash
Скачать
curl -X POST https://api.paybot.kz/v2/payment-links/pl_abc123/cancel \
  -H "X-API-Key: kp_live_00112233445566778899aabbccddeeff"

Попытка отменить уже оплаченную ссылку вернёт 409 payment_link_already_paid. Как и с редактированием, дизейблите действие по status заранее.

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

GET /v2/payment-links возвращает ссылки с курсорной пагинацией. Параметры запроса: cursor, limit (1–100, по умолчанию 25) и status. Ответ — конверт {data, next_cursor, has_more}; признак «есть ещё страница» — это has_more, а cursor передавайте как непрозрачную строку, не разбирая её.

bash
Скачать
curl "https://api.paybot.kz/v2/payment-links?limit=25&status=active" \
  -H "X-API-Key: kp_live_00112233445566778899aabbccddeeff"

Элементы списка намеренно не содержат metadata и данных QR — чтобы получить qr_image_url и metadata конкретной ссылки, запрашивайте её отдельно через GET /v2/payment-links/{token}.

FAQ

Нужен ли договор эквайринга, чтобы принимать оплату по ссылке?

Нет. PayBot работает поверх вашего личного или бизнес-аккаунта Kaspi Pay через Kaspi API — отдельный договор эквайринга с банком не требуется. Достаточно подключить Kaspi-аккаунт в кабинете; деньги приходят на ваш счёт Kaspi.

Чем платёжная ссылка отличается от QR через API?

Платёжная ссылка — это готовая брендированная страница оплаты с постоянным URL, которую не нужно программировать: вы просто отдаёте ссылку покупателю. Прямой вызов QR или счёта через API даёт вам сырой qr_token и deep_link, которые вы сами рисуете и показываете в своём интерфейсе. Ссылка удобнее для ручной отправки и печати, прямой API — для встраивания в собственный POS или чекаут.

Идемпотентен ли повторный запрос на создание ссылки?

Да. Для POST /v2/payment-links заголовок Idempotency-Key опционален — если вы его не передадите, сервер сам подставит ключ вида pl_auto_. Но чтобы двойной клик по кнопке не создал две ссылки, передавайте свой ключ (обычно UUID v4) — один на одно намерение пользователя. Подробнее в разделе Идемпотентность.

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

По умолчанию 24 часа (expires_in_minutes: 1440). Минимум — 5 минут, максимум — 30 дней (43200 минут). Точное время истечения приходит в поле expires_at (UTC) — ориентируйтесь на него, а не на константу.