> Источник: 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 Business (счёт по номеру и вебхук). Достаточно приложения Kaspi Pay вашего ИП/ТОО и номера кассира. Схема: покупатель оформляет заказ на сайте → ваш бэкенд создаёт счёт через ApiPay по номеру телефона покупателя → покупателю приходит push в Kaspi → оплатил → вебхук вашему бэкенду → заказ подтверждён. Готовых плагинов под Tilda/WordPress нет — интеграцию по документации apipay.kz/docs за вас соберёт ваш ИИ-помощник (Claude, Cursor, GPT): это штатный путь, а не обходной. Как встроить приём Kaspi на сайт — на странице [интеграции Kaspi Pay](/kaspi-pay-integration).

## Почему магазины приходят к ApiPay

Часто малому и среднему бизнесу нужен REST-приём Kaspi, а собственной интеграции ещё нет. ApiPay — независимый сервис поверх вашего Kaspi Pay: даёт REST API (счёт по номеру и вебхук) через штатную роль «Кассир», без отдельного Магазина на Kaspi.kz и без оборотных требований.

Разблокировка простая: если у магазина уже есть Kaspi Pay, счета можно выставлять через REST API ApiPay — для этого нужен только номер кассира, отдельный Магазин на Kaspi.kz не требуется.

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

Итоговая схема:

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

По-человечески: покупатель вводит номер телефона при оформлении → получает счёт push'ем в своём Kaspi → оплатил → ApiPay шлёт вебхук → вы закрываете сделку. Деньги идут напрямую на ваш Kaspi-счёт, ApiPay к ним доступа не имеет; тариф — фиксированная подписка, не процент с оборота.

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

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

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

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

Инструкция из 4 шагов, которую поддержка отправляет каждому магазину, — плюс два практических шага:

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

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

- **«Всё настроили, а оплаты не приходят»** — причина №1 у новых магазинов: песочница не выключена. Счета в тестовом режиме в Kaspi не передаются; покупатель на ссылке видит «Пожалуйста, повторите позднее». Решается одной кнопкой «Включить рабочий режим».
- **Подписки ≠ автосписание.** Магазины нередко ждут автосписаний, как в карточных эквайрингах. Оплата по номеру так не работает, и в этом суть модели: автосписания нет — счёт просто выставляется автоматически, а клиент получает push и сам нажимает «Оплатить». Если нужен свой график, это те же обычные счета, настроенные по крону на вашей стороне. Поняв это, часть магазинов отказывается от подписок и заметно упрощает интеграцию.
- **Плагина под Tilda/WordPress нет** — и это осознанная позиция: REST-запросы по /docs собирает ваш ИИ за вечер. Не ждите «модуль из каталога».
- **Номер покупателя должен быть в Kaspi.** Если покупатель ввёл номер с опечаткой, счёт может уйти чужому человеку или никому: валидируйте номер на форме и показывайте покупателю, куда ушёл счёт.
- **Переход в прод перегенерирует ключи.** Тестовые организации и ключи удаляются при включении рабочего режима — перебейте ключ и вебхук-секрет в конфиге сайта.

## Мини-кейс: магазин на конструкторе сайтов

Типичный путь магазина на конструкторе сайтов (например, Tilda), у которого ещё нет собственной интеграции с Kaspi, выглядит так. Сначала магазин регистрируется на apipay.kz и отлаживает решение по документации apipay.kz/docs в режиме «Песочница». Готового плагина под конструктор нет, поэтому интеграцию собирают REST-запросами — как правило, с помощью ИИ-помощника. Затем подключают номер кассира и включают «Рабочий режим», получив несколько дней на живые тесты. За пару-тройку дней интеграция обычно выходит на рабочий режим, а магазин подбирает подходящий тариф по объёму счетов.

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

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

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

Два способа, выбор — под ваш UX:

| | Счёт по номеру (`POST /invoices`) | QR (`POST /invoices/qr`) |
|---|---|---|
| Как платит клиент | Kaspi шлёт **push** на номер, клиент платит в приложении | На странице показываем **QR-картинку/ссылку**, клиент сканирует |
| Нужен телефон | да (`phone_number`) | нет |
| Ответ | `201` со `status: "processing"` | `201` сразу `status: "pending"` + QR-поля |
| pending-вебхук | да (`processing → pending`) | **нет** (статус уже в синхронном ответе) |
| `description` | до 500 символов | **до 100** (наименование позиции в QR-чеке) |
| Жизнь счёта | 24 часа | **минуты** (TTL ~5 минут) |
| Спец-лимит | общий 200/min | **60/min на организацию** |
| Особое событие | — | `invoice.qr_scanned` |
| Несколько QR | — | **сосуществуют**: новый QR не гасит старый |

Счёт по номеру — когда есть телефон клиента и ок «push в Kaspi» (доставка, менеджер оформляет). QR — оплата «здесь и сейчас» на экране. Ответ QR несёт `qr_image_url` (PNG 600×600), `qr_token_url` и `qr_expires_at`. Почему 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/min + 10 000/день, массовый перебор ведёт к блокировке ключа; дёргайте точечно, перед созданием счёта.

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

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

Вебхук приходит как `POST {ваш webhook}` с заголовком `X-Webhook-Signature: sha256=<hex>`. **Проверяйте подпись по сырому телу** (raw body), не по перепарсенному JSON:

```js
import crypto from 'crypto'
function verify(rawBody, header, secret) {
  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex')
  const got = Buffer.from(header || '')
  const exp = Buffer.from(expected)
  if (got.length !== exp.length) return false
  return crypto.timingSafeEqual(exp, got)
}
// secret = process.env.APIPAY_WEBHOOK_SECRET
```

Три правила обработчика: отвечать `200` быстро (**до 5 с**), обработку — в очередь; **дедуп** по `(invoice.id, invoice.status)` (повторы доставки возможны); реагировать на **последний** статус (`cancelled → paid` = деньги получены). Полный разбор доставки, ретраев и circuit breaker — в статье [Вебхуки ApiPay: настройка и проверка подписи](/guides/nastroyka-webhookov-apipay); здесь не дублируем. Если вебхук не пришёл (пауза breaker'а, сеть) — страховка через поллинг `GET /invoices/{id}`.

### QR-UX: сканирование, ожидание, таймауты

Событие `invoice.qr_scanned` (в payload `qr_substate: "scanned"`) означает, что клиент отсканировал QR и на экране оплаты; `status` при этом остаётся `pending`. Реакция UI: убрать QR, показать «Ожидается оплата». Важно: это **транзиентно**: возможен `scanned → cancelled` (клиент свернул приложение) — UI обязан откатить «Ожидается» и предложить новый QR. `expired` по QR приходит только когда Kaspi отдал терминал, а не по локальному таймеру. QR сосуществуют — реагируйте на `paid`/`cancelled`/`expired` по **каждому** `invoice.id`.

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

`POST /invoices/{id}/refund` — полный (по умолчанию) или частичный (`amount` либо позиционный `return_items[]`). Результат приходит вебхуком `invoice.refunded` (`completed`/`failed`+`error_code`). Статуса `refunded` у счёта нет: полный возврат оставляет `paid` + `is_fully_refunded=true`. Причины отказов и окно возврата — [Возвраты Kaspi через API](/guides/vozvraty-kaspi-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` для витрины).
- Что меняется при переходе — [Песочница и рабочий режим](/guides/pesochnitsa-i-rabochiy-rezhim): тестовые ключи и вебхук-секрет перевыпускаются, перебейте их в конфиге.

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

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

**Законно ли работать через ApiPay, если у нас нет собственной интеграции с 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
