> Источник: https://apipay.kz/guides/apipay-dlya-internet-magazina · Обновлено: 2026-07-06 · apipay.kz
> ApiPay — независимый сервис приёма платежей поверх вашего Kaspi Pay.

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

**TL;DR.** Да: для приёма Kaspi-оплат на своём сайте отдельный **Магазин на Kaspi.kz не нужен** — ApiPay даёт REST API поверх функционала Kaspi Pay (счёт по номеру и вебхук). Достаточно приложения Kaspi Pay вашего ИП/ТОО и номера кассира. Схема: покупатель оформляет заказ на сайте → ваш бэкенд создаёт счёт через ApiPay по номеру телефона покупателя → покупателю приходит push в Kaspi → оплатил → вебхук вашему бэкенду → заказ подтверждён. Готовых плагинов под Tilda/WordPress нет — интеграция собирается REST-запросами по документации apipay.kz/docs. Как встроить приём Kaspi на сайт — на странице [интеграции Kaspi Pay](/kaspi-pay-integration).

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

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

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

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

Магазину доступен весь [Kaspi API](/kaspi-api):

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

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

Шесть шагов:

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

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

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

## Для разработчиков: собрать 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 и лимиты](/guides/qr-schet-ttl-i-limity).

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

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

```bash
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: настройка и проверка подписи](/guides/nastroyka-webhookov-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](/guides/vozvraty-kaspi-cherez-api). Если Kaspi отказал или оплата шла мимо ваших счетов — есть вторая механика, `POST /qr-refunds`: покупатель сканирует возвратный QR тем же Kaspi, которым платил ([Возврат по QR через API](/guides/vozvrat-po-qr-cherez-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 и корзину](/guides/scheta-s-korzinoy-cart-items-ofd).

---

ApiPay — независимый сервис и не аффилирован с АО «Kaspi Bank». Kaspi и Kaspi Pay — товарные знаки их правообладателя.
База знаний: https://apipay.kz/guides
