Как принимать оплату Kaspi интернет-магазину — без Kaspi-магазина?

Обновлено 6 июля 2026 · Решение проблем · Версия в Markdown
Содержание
  1. Как это работает у вас
  2. Компоненты ApiPay для магазина
  3. Пошаговый сетап
  4. Грабли именно магазинов
  5. Для разработчиков: собрать checkout
  6. Частые вопросы

Как это работает у вас

Frontend (Tilda / ваш сайт) → Backend (API магазина) → ApiPay API → Backend магазина получает вебхук об успешной оплате → заказ переводится в «Оплачен».

Деньги идут напрямую на ваш Kaspi-счёт, ApiPay к ним доступа не имеет; тариф — фиксированная подписка, не процент с оборота.

Компоненты ApiPay для магазина

Магазину доступен весь Kaspi API:

Компонент Зачем магазину
Счёт по номеру Основной сценарий: push покупателю, счёт живёт 24 часа
QR-счёт Когда нужна ссылка или картинка на экране: у счёта по номеру ссылки на оплату нет — покупатель платит из push в своём Kaspi
Вебхук Автоматическое подтверждение заказа; поллинг статуса — запасной вариант
Песочница Отладка интеграции без реальных денег; переход в прод — тумблер «Рабочий режим»
Подписки (авто-выставление) Для повторяющихся заказов; см. грабли — это не автосписание
Кабинет apipay.kz Ручные счета и возвраты, пока интеграция в работе

Пошаговый сетап

Шесть шагов:

  1. Зарегистрируйтесь на apipay.kz (вход по WhatsApp-OTP).
  2. Отладьте своё решение по документации apipay.kz/docs в режиме «Песочница»: создание счёта из корзины, обработка вебхука. Если у вас нет разработчика — скиньте вашему ИИ ссылку apipay.kz/for-ai и документацию: он соберёт интеграцию под ваш сайт (удобно собирать в Lovable).
  3. Подключите номер кассира (отдельная SIM — требования).
  4. Включите «Рабочий режим»что при этом меняется.
  5. Проверьте боевой сквозной сценарий: заказ → счёт → оплата → вебхук → статус заказа.
  6. Выберите тариф по дневному объёму счетов — фиксированная подписка, не процент (Тарифы и комиссия).

Грабли именно магазинов

  • «Всё настроили, а оплаты не приходят» — не выключена песочница. Sandbox-счёт создаётся с is_sandbox: true и kaspi_invoice_id: "SANDBOX-…", в Kaspi он не уходит и оплатить его нельзя. Лечится кнопкой «Включить рабочий режим».
  • Подписки ≠ автосписание. Автосписания нет: система сама создаёт обычный счёт в next_billing_at, клиент получает push и подтверждает оплату вручную. Если нужен свой график — это те же обычные счета POST /invoices, поставленные на ваш крон.
  • Плагина под Tilda/WordPress нет. Интеграция собирается REST-запросами по документации apipay.kz/docs.
  • Номер покупателя должен быть в Kaspi. Если покупатель ввёл номер с опечаткой, счёт может уйти чужому человеку или никому: валидируйте номер на форме и показывайте покупателю, куда ушёл счёт.
  • Ключи при переключении режима не меняются. Организация, API-ключ и вебхук-секрет остаются те же — конфиг перебивать не нужно (Песочница и рабочий режим).

Для разработчиков: собрать checkout

Хост API — https://api.apipay.kz/api/v1, заголовок X-API-Key (ключ держите только на сервере, никогда в браузере).

Способ оплаты: счёт по номеру или QR

Счёт по номеру (POST /invoices) — когда у вас есть телефон клиента и ок «push в Kaspi» (доставка, менеджер оформляет заказ): Kaspi шлёт push, клиент платит в приложении, счёт живёт 24 часа, ссылки на оплату у него нет. QR (POST /invoices/qr) — оплата «здесь и сейчас» на экране или ссылкой: телефон не нужен, в ответе приходят qr_image_url, qr_token_url и qr_expires_at.

Окно на скан у QR короткое и задаёт его Kaspi — берите момент из qr_expires_at, константу в код не зашивайте. Остальное про QR — окно, лимиты, срок жизни картинки, сосуществование нескольких QR — в статье QR-счёт: TTL и лимиты.

Идемпотентный checkout

Повторный клик «Оплатить» или двойной сабмит не должны плодить счета. Защита — поле external_order_id_idempotency = ID заказа:

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

Повтор с тем же ключом → 409 duplicate_idempotency_key с телом { invoice_id, status }: покажите существующий счёт, не создавайте второй. external_order_id — метка для матчинга в вебхуке (по ней магазин находит заказ). Не проверяйте номер на каждый pageview через POST /clients/check — лимиты 60/мин + 10 000/сутки на ключ и 200/мин + 20 000/сутки на организацию, а за массовым перебором номеров может последовать деактивация ключа. Дёргайте точечно, перед созданием счёта.

Обработка вебхуков: статус → действие магазина

Статус в вебхуке Действие магазина
pending Счёт создан в Kaspi (только счёт по номеру) — ждём оплату
paid Пометить оплаченным, выдать/отгрузить. Может прийти после cancelled/expired — всё равно «деньги получены»
cancelled Снять резерв, вернуть заказ в «ожидает оплаты»
expired Снять резерв, предложить оплатить заново
error (+ error_code) Показать «оплата не прошла», предложить заново (новый счёт)
partially_refunded Отразить частичный возврат

Обработчик обязан: проверить подпись X-Webhook-Signature: sha256=<hex> по сырому телу (raw body), а не по перепарсенному JSON; ответить 200 быстро (до 5 с), а обработку отдать в очередь; дедуплицировать по (invoice.id, invoice.status); реагировать на последний статус (cancelled → paid = деньги получены). Код проверки подписи, разбор доставки, ретраев и circuit breaker — в статье Вебхуки ApiPay: настройка и проверка подписи. Если вебхук не пришёл — страховка через поллинг GET /invoices/{id}.

Адресом вебхука ставьте постоянный домен своего сервиса, а не шортенер и не временную заглушку.

QR-UX: сканирование и ожидание

Событие invoice.qr_scanned означает, что клиент отсканировал QR и на экране оплаты, — уберите QR и покажите «Ожидается оплата». Состояние транзиентно: возможен переход в cancelled (клиент свернул приложение), тогда UI откатывает «Ожидается» и предлагает новый QR. Реагируйте на paid/cancelled/expired по каждому invoice.id.

Возвраты при отмене заказа

POST /invoices/{id}/refund — полный (по умолчанию) или частичный (amount либо позиционный return_items[]). Результат приходит вебхуком invoice.refunded. Причины отказов и окно возврата — Возвраты Kaspi через API. Если Kaspi отказал или оплата шла мимо ваших счетов — есть вторая механика, POST /qr-refunds: покупатель сканирует возвратный QR тем же Kaspi, которым платил (Возврат по QR через API).

Чек-лист: sandbox → прод

  • Прогнать весь жизненный цикл в песочнице: POST /invoices/{id}/simulate-status (paid/cancelled/expired/error/qr_scanned), проверить доставку через GET /webhook-logs?invoice_id=…; магические номера lookup — 87770000001 (есть Kaspi) / 87770000002 (нет).
  • Идемпотентность checkout (external_order_id_idempotency = ID заказа), дедуп и HMAC вебхуков.
  • Снятие резерва склада по expired/cancelled; обработка cancelled → paid как «деньги получены».
  • Уважать 429/Retry-After; даты в ответах — UTC (переводите в Asia/Almaty для витрины).
  • Проверить, что боевой webhook_url доступен снаружи и подпись сходится.

Частые вопросы

Нужен ли Kaspi-магазин или регистрация в Kaspi Merchant?

Нет. Нужны только Kaspi Pay вашего ИП/ТОО и отдельный номер под роль «Кассир».

Нужна ли собственная интеграция с Kaspi API или отдельный договор?

Нет. ApiPay — независимый сервис поверх вашего Kaspi Pay: он работает через штатную роль «Кассир», деньги идут напрямую на ваш счёт. Это не официальная интеграция Kaspi.

Сколько идёт подтверждение оплаты?

Доставка статуса обычно занимает секунды, в отдельных случаях — до 10 минут. Стройте UX «подтверждение придёт на почту/WhatsApp», а не «ждите на странице».

Можно без бэкенда, прямо из Tilda?

Форме Tilda нужен обработчик, который вызовет API и примет вебхук, — это минимальный бэкенд (или low-code-связка). Ваш ИИ соберёт его по apipay.kz/for-ai.

Что с чеками ОФД?

Если у вас подключена Kaspi ОФД, счета создаются с корзиной (cart_items) и чек формируется по позициям каталога — см. статью про 422 и корзину.

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

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

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

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

Написать в WhatsApp

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