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

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

**TL;DR.** Интернет-магазин принимает оплату Kaspi без Магазина на Kaspi.kz через ApiPay — [API поверх Kaspi Pay](/kaspi-api) вашего бизнеса. Сервер магазина выставляет покупателю счёт по номеру телефона (`POST /invoices`, покупателю приходит push в Kaspi) или отдаёт ссылку на оплату `payment_url` (`POST /invoices/qr` со `static: true`) либо QR-счёт для оплаты прямо сейчас (`POST /invoices/qr`), а об оплате узнаёт опросом `GET /invoices/{id}` или вебхуком: для старта хватит опроса, вебхук — по желанию. Нужны Kaspi Pay вашего бизнеса и отдельный номер под роль «Кассир», деньги идут напрямую на ваш Kaspi-счёт. Готового плагина под Tilda и WordPress нет: код соберёт разработчик по [документации](/docs) или ваш ИИ-агент по [apipay.kz/for-ai](/for-ai).

## Как устроена оплата Kaspi на сайте магазина?

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

Покупатель оформляет заказ на сайте, ваш бэкенд создаёт счёт через ApiPay, покупатель оплачивает его в приложении Kaspi. Как встроить приём Kaspi на сайт по шагам — на странице [интеграции Kaspi Pay](/kaspi-pay-integration); готовый виджет с кнопкой и QR и полный код бэкенда — в статье «[Как принять оплату Kaspi на сайте: виджет или свой код](/guides/kaspi-oplata-na-sayte)».

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

## Что из ApiPay нужно интернет-магазину?

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

| Компонент | Зачем магазину |
|---|---|
| [Счёт по номеру](/invoice-by-phone) | Основной сценарий: push покупателю, счёт живёт 24 часа |
| QR-счёт | Когда покупатель платит сейчас: `POST /invoices/qr` возвращает картинку QR для экрана и `qr_token_url` — ссылку Kaspi на этот QR для покупателя, который на связи; действует до `qr_expires_at` |
| Ссылка на оплату | Когда покупатель заплатит позже: поле `payment_url` (`POST /invoices/qr` со `static: true`), счёт создаётся, только когда покупатель нажал «Оплатить в Kaspi». Если режим ссылок выключен — `403 static_qr_disabled`, тогда отправляют `print_url` статического QR |
| Статический QR | Лист под сделку: `print_url` и готовый PNG работают, пока лист не оплачен и не отключён — вкладывается в заказ, отправляется письмом, печатается на квитанции |
| Опрос статуса и вебхук | Автоматическое подтверждение заказа. Для старта хватит опроса `GET /invoices/{id}` с сервера; вебхук — по желанию, когда будет постоянный адрес |
| Песочница | Отладка интеграции без реальных денег; переход в прод — тумблер «Рабочий режим» |
| Подписки (авто-выставление) | Для повторяющихся заказов; см. грабли — это не автосписание |
| Кабинет apipay.kz | Ручные счета и возвраты, пока интеграция в работе |

## Как подключить оплату Kaspi к интернет-магазину по шагам?

Шесть шагов:

1. **Зарегистрируйтесь на apipay.kz** (вход по WhatsApp-OTP).
2. **Отладьте своё решение по [документации](/docs) в режиме «Песочница»**: создание счёта из корзины и проверка статуса — опросом или вебхуком. Если у вас нет разработчика — дайте вашему ИИ ссылку [apipay.kz/for-ai](/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-запросами по [документации](/docs).
- **Номер покупателя должен быть в Kaspi.** Если покупатель ввёл номер с опечаткой, счёт может уйти чужому человеку или никому: валидируйте номер на форме и показывайте покупателю, куда ушёл счёт.
- **Ключи при переключении режима не меняются.** Организация, API-ключ и вебхук-секрет остаются те же — конфиг перебивать не нужно ([Песочница и рабочий режим](/guides/pesochnitsa-i-rabochiy-rezhim)).

## Как разработчику собрать checkout?

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

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

Магазину доступны четыре способа, и выбор между ними — это вопрос «когда покупатель заплатит».

| Способ | Запрос | Что доставляете покупателю | Когда |
|---|---|---|---|
| Счёт по номеру | `POST /invoices` | Ничего: Kaspi сам шлёт push на номер | Есть телефон, оплата в течение суток (счёт живёт 24 часа) |
| QR-счёт | `POST /invoices/qr` | `qr_image_url` — картинку QR или `qr_token_url` — ссылку Kaspi на этот QR (кнопка на странице «Спасибо», сообщение в чат) | Покупатель платит сейчас: он на сайте или в переписке |
| Ссылка на оплату | `POST /invoices/qr` со `static: true` | `payment_url` — в чат или кнопкой; если режим ссылок выключен (`403 static_qr_disabled`) — `print_url` статического QR | Покупатель заплатит позже: подумает, получит ссылку в чате |
| Статический QR | `POST /static-qr` | `print_url` — адрес листа, который работает, пока лист не оплачен и не отключён, и готовый PNG для печати | Оплата «когда-нибудь потом»: вложить в заказ, приложить к акту |

Счёт по номеру (`POST /invoices`) — когда у вас есть телефон клиента и ок «push в Kaspi» (доставка, менеджер оформляет заказ): Kaspi шлёт push, клиент платит в приложении, счёт живёт 24 часа. Ссылки на оплату у такого счёта нет — доставляет его сам Kaspi; ссылку на оплату `payment_url` даёт запрос со `static: true`.

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

⚠️ **Счёт создавайте в момент нажатия кнопки, а не при отрисовке страницы.** Пока покупатель читает страницу, окно успевает истечь, и заранее вшитая ссылка приведёт его на экран «Попробуйте позже». Рабочая схема: кнопка «Оплатить в Kaspi» ведёт на ваш серверный обработчик, тот создаёт QR-счёт и редиректит покупателя на свежий `qr_token_url`. Передавайте в `external_order_id_idempotency` идентификатор заказа: пока ссылка жива, повторное нажатие вернёт `409 duplicate_idempotency_key` с `invoice_id` уже созданного счёта — переиспользуйте его; когда счёт истечёт, тот же ключ выдаст новую ссылку.

Окно на скан у QR короткое и задаёт его Kaspi — **берите момент из `qr_expires_at`, константу в код не зашивайте**. Оно же ограничивает и ссылку: `qr_token_url` рассчитана на покупателя, который платит прямо сейчас. Если оплата откладывается — ссылка на оплату `payment_url`, счёт по номеру (24 часа) или статический QR ([`POST /static-qr`](/guides/pechatnyy-qr-dlya-oplaty-po-sdelke), `print_url` работает, пока лист не оплачен и не отключён). У ссылки и листа счёт создаётся, только когда покупатель нажал «Оплатить в Kaspi». Как выбрать — «[Какой QR выбрать](/guides/kakoy-qr-vybrat-qr-schet-ili-staticheskiy)». Остальное про QR — окно, лимиты, срок жизни картинки, сосуществование нескольких QR — в статье [QR-счёт: TTL и лимиты](/guides/qr-schet-ttl-i-limity) и в разборе [оплаты по ссылке](/guides/oplata-po-ssylke-kaspi).

### Идемпотентный 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/сутки на организацию**, а за массовым перебором номеров может последовать деактивация ключа. Дёргайте точечно, перед созданием счёта.

### Как узнать об оплате: опрос или вебхук?

Для старта хватит опроса: сервер магазина запрашивает `GET /invoices/{id}` по счетам без `paid` и смотрит статус. Закрытые счета (`expired`, `cancelled`, `error`) проверяйте ещё 24 часа — они могут смениться на `paid`. Вебхук — по желанию: ApiPay сам присылает POST на ваш адрес при смене статуса. Итоговые статусы в ответе опроса и в вебхуке одни и те же. Опрос вдобавок показывает промежуточные — это не отказ, счёт не пересоздавайте:

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

Если подключили вебхук, обработчик обязан: проверить подпись `X-Webhook-Signature: sha256=<hex>` **по сырому телу** (raw body), а не по перепарсенному JSON; ответить `200` быстро (**до 5 с**), а обработку отдать в очередь; **дедуплицировать** по `(invoice.id, invoice.status)`, не отбрасывая `pending` после `error` и `error` после такого `pending` (это новые переходы, а не дубли); реагировать на **последний** статус (`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 требует подтверждения покупателя или оплата шла мимо ваших счетов — есть вторая механика, ссылка «Возврат ApiPay» `POST /qr-refunds/links`: покупатель открывает её и сканирует возвратный 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 заказа); при опросе — сверка закрытых счетов ещё 24 часа, при вебхуке — дедуп и HMAC.
- Снятие резерва склада по `expired`/`cancelled`; обработка `cancelled → paid` как «деньги получены».
- Уважать `429`/`Retry-After`; даты в ответах — UTC (переводите в `Asia/Almaty` для витрины).
- Если используете вебхук — проверить, что боевой `webhook_url` доступен снаружи и подпись сходится.

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

**Нужен ли Kaspi-магазин или регистрация в Kaspi Merchant?**
Нет. Нужны только Kaspi Pay вашего бизнеса (ИП, ТОО и другие формы) и отдельный номер под роль «Кассир».

**Нужно ли что-то отдельно оформлять под ApiPay — это официальный API Kaspi?**
Под ApiPay вы ничего отдельно не оформляете: ApiPay работает поверх уже подключённого у вас Kaspi Pay — в нём вы только добавляете сотрудника со штатной ролью «Кассир». Деньги идут напрямую на ваш Kaspi-счёт. ApiPay — независимый сервис, а не официальная интеграция Kaspi; права кассира описаны в [справке Kaspi](https://guide.kaspi.kz/partner/ru/profile/user/cashier/q3450).

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

**Есть ли плагин Kaspi для Tilda или WordPress?**
Готового плагина нет. Форме Tilda или WordPress нужен обработчик на сервере, который вызовет API и проверит статус оплаты, — это минимальный бэкенд (или low-code-связка). Ваш ИИ соберёт его по [apipay.kz/for-ai](/for-ai); фронт-часть можно взять готовой — [виджет](/guides/kaspi-oplata-na-sayte).

**Что с чеками ОФД?**
Если у вас подключена Kaspi ОФД, счета создаются с корзиной (`cart_items`) и чек формируется по позициям каталога — см. [статью про 422 и корзину](/guides/scheta-s-korzinoy-cart-items-ofd).

---

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