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

# Подписки ApiPay: есть ли автосписание с покупателя?

**TL;DR.** Автосписания нет: оплата по номеру в Kaspi всегда подтверждается самим покупателем — сервис не может списать деньги без его подтверждения (списание без подтверждения существует только для карт в классическом эквайринге). Подписка ApiPay — это **авто-выставление**: по расписанию (например, каждое 1-е число) система сама создаёт обычный счёт Kaspi, покупатель получает push и нажимает «Оплатить». Не оплатил — система сама перевыставляет счёт (по умолчанию до 3 попыток раз в 24 часа), затем даёт льготный grace-период (по умолчанию 3 дня). Если и он истёк — подписка переходит в `expired` навсегда: реактивации нет, создаётся новая подписка.

## Как работает подписка

Цикл выглядит так:

1. Вы создаёте подписку: номер телефона покупателя + период + сумма.
2. В расчётную дату система сама создаёт **обычный счёт Kaspi** — покупателю приходит push в приложение Kaspi.
3. Покупатель нажимает «Оплатить» — деньги, как всегда, идут напрямую на ваш Kaspi-счёт. Вам приходит вебхук `subscription.payment_succeeded`.
4. Дата следующего выставления сдвигается на период — и так по кругу.

## Создание подписки через API

```bash
curl -X POST "https://api.apipay.kz/api/v1/subscriptions" \
  -H "X-API-Key: ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "87001234567",
    "amount": 15000,
    "billing_period": "monthly",
    "billing_day": 1,
    "description": "Абонемент, тариф Стандарт"
  }'
```

Параметры и границы: `billing_period` — `daily | weekly | biweekly | monthly | quarterly | yearly`; `amount` — от 100 до 1 000 000 ₸ и **только целые тенге** (дробную сумму создание подписки примет, но каждое списание уйдёт в `error` с `amount_must_be_whole_tenge`); `billing_day` — 1–28 (чтобы дата существовала в любом месяце); `max_retry_attempts` — 1–10 (по умолчанию 3); `retry_interval_hours` — 1–168 (по умолчанию 24); `grace_period_days` — 1–30 (по умолчанию 3); `bill_immediately` — выставить первый счёт сразу при создании.

**Важно:** ответ `201` на `POST /subscriptions` означает «подписка создана», а не «покупателю уже ушёл счёт». Если вы ждёте немедленный push покупателю — передайте `bill_immediately: true`. Управление: `POST /subscriptions/{id}/pause | resume | cancel`, счета подписки — `GET /subscriptions/{id}/invoices`.

Подпискам нужна верифицированная организация: без неё API отвечает `400 Subscriptions require a verified organization`.

## Что происходит, когда покупатель не платит?

1. **Счёт не оплачен** (истёк через 24 часа или отменён) → вам приходит `subscription.payment_failed` с причиной (`Invoice expired` / `Invoice cancelled`) и номером попытки.
2. **Система сама перевыставляет счёт** — по умолчанию до 3 попыток. `retry_interval_hours` (по умолчанию 24 ч) — номинальный интервал: фактически повтор может прийти раньше, поэтому не стройте дедуп и напоминания клиенту строго по 24-часовой сетке. Вручную ничего пересоздавать не нужно (и не надо: получите два параллельных счёта).
3. **Попытки исчерпаны** → начинается **grace-период** (`subscription.grace_period_started`, по умолчанию 3 дня): доступ покупателю вы пока не отключаете, а любая его оплата немедленно возвращает подписку в норму.
4. **Grace истёк** → `subscription.expired`: биллинг по этой подписке остановлен **навсегда**.

После `expired` реактивации не существует — ни кнопки, ни метода API. Покупатель вернулся через месяц? Создайте **новую** подписку.

Отдельная причина тишины — ваш собственный тариф ApiPay. Если тариф не оплачен (`403 tariff_inactive`) или включено ограничение по дневному лимиту (`429 tariff_limit_reached`), автосписание пропускает цикл молча: счёт покупателю не выставляется, дата следующего списания не сдвигается, счётчик неудачных попыток не растёт, вебхука об этом нет. После оплаты тарифа или снятия ограничения подписки догоняют пропущенные периоды — по одному за прогон. См. [Лимит счетов по тарифу](/guides/limit-schetov-po-tarifu).

Пауза устроена мягче: `pause` останавливает выставление, `resume` продолжает **от текущего момента** — пропущенные периоды не доначисляются, покупателю не прилетит «счёт за три месяца тишины». `cancel` — безвозвратен, как и `expired`.

## События subscription.* для интеграции

Вебхуки подписок приходят на тот же URL, что и счета (настройка — «[Настройка вебхуков ApiPay](/guides/nastroyka-webhookov-apipay)»):

| Событие | Когда | Доп. поля (в корне payload) |
|---|---|---|
| `subscription.created` | Подписка создана | — |
| `subscription.payment_succeeded` | Счёт подписки оплачен | `invoice_id`, `amount`, `paid_at` |
| `subscription.payment_failed` | Счёт истёк/отменён | `invoice_id`, `amount`, `reason`, `attempt_number` |
| `subscription.grace_period_started` | Ретраи исчерпаны | `grace_period_days`, `expires_at` |
| `subscription.expired` | Grace истёк, биллинг остановлен | — |
| `subscription.paused` / `resumed` / `cancelled` | Соответствующие действия | — |

Три инженерных нюанса (трек D):

- **Дедупликация обязательна:** у событий подписок нет защиты от дублей — дедуплицируйте по `(event, subscription.id, invoice_id)`.
- **Ретраев в логах не ищите:** события `subscription.*` не попадают в webhook-логи кабинета и не имеют ручного перезапуска — отвечайте `200` быстро и обрабатывайте асинхронно.
- **Счёт подписки в статусе `error`** — это тоже неуспешная попытка: приходит `subscription.payment_failed`, в payload добавляется `error_code`. Если ошибка на стороне сервиса (например, оборвалась Kaspi-сессия), попытка не засчитывается и период сохраняется — следующая попытка будет позже. Если причина в плательщике (`client_not_found` — у номера нет Kaspi), идут обычные ретраи и затем grace.

## Вопросы и ответы

**Почему нельзя сделать настоящее автосписание?**
Оплата по номеру телефона в Kaspi всегда подтверждается самим покупателем: списание без подтверждения доступно только в карточном эквайринге с токенизацией карты. Клиентам это честно формулируется так: «счёт будет приходить автоматически, оплата в один клик».

**Можно ли изменить сумму действующей подписки?**
Да, через `PUT /subscriptions/{id}` — изменения применяются к будущим счетам.

**Подписка умерла (`expired`) — я потеряю историю?**
Нет: подписка и все её счета остаются в кабинете и API. Остановлен только будущий биллинг — для продолжения создайте новую подписку.

Смотрите также: [Как создать счёт Kaspi по номеру](/guides/kak-sozdat-schet-kaspi-po-nomeru) · [Настройка вебхуков ApiPay](/guides/nastroyka-webhookov-apipay) · Тарифы и комиссия ApiPay · [Рекуррентные платежи Kaspi](/recurring-payments-kaspi) · пиллар «[Как принимать оплату Kaspi через API](/kaspi-api)».

---

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