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

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

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

## Коротко

| Вопрос | Ответ |
|---|---|
| Автосписание с покупателя | Нет: оплату по номеру покупатель всегда подтверждает сам (push → «Оплатить») |
| Что делает подписка | Автоматически выставляет счёт по расписанию и сама ретраит неоплату |
| Периоды | daily, weekly, biweekly, monthly, quarterly, yearly; день списания `billing_day` 1–28 |
| Сумма | 100 — 1 000 000 ₸ |
| Ретраи неоплаты | По умолчанию 3 попытки с интервалом 24 ч (настраивается: 1–10 попыток, 1–168 ч) |
| Grace-период | По умолчанию 3 дня (настраивается 1–30); любая оплата снимает grace |
| После `expired` | Реактивации нет — создавайте новую подписку |
| События | `subscription.created / payment_succeeded / payment_failed / grace_period_started / expired / paused / resumed / cancelled` |

## Как на самом деле работает подписка (и почему это удобно покупателю)

Аналогия для трека «на пальцах»: подписка ApiPay — это не «рука в кармане покупателя», а **пунктуальный бухгалтер**, который каждый месяц сам выписывает счёт и вежливо напоминает, если его не оплатили.

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

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 ₸; `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`.

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

Здесь подписка отрабатывает за вас всю рутину «дожима»:

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

После `expired` реактивации не существует — ни кнопки, ни метода API. Покупатель вернулся через месяц? Создайте **новую** подписку. Это осознанное правило: «воскрешение» старой подписки означало бы споры о пропущенных периодах и неожиданные счета.

Пауза устроена мягче: `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` (например, `client_not_found` — у номера нет Kaspi), это **не** считается провалом оплаты: `payment_failed` не придёт, ретрая не будет, период будет пропущен. Отлавливайте такие случаи по `invoice.status_changed` со статусом `error` для счетов подписки.

## Частые ошибки

- **Обещать клиентам «автосписание как у Netflix».** Не обещайте: покупатель подтверждает каждый платёж сам. Честная формулировка — «счёт будет приходить автоматически, оплата в один клик».
- **Пересоздавать счёт вручную после `payment_failed`.** Система сама ретраит по расписанию — ручной счёт даст дубль.
- **Ждать `payment_failed` при счёте в статусе `error`.** Не придёт (известное ограничение) — мониторьте `error`-счета подписок отдельно.
- **Пытаться реактивировать `expired`-подписку.** Невозможно by design — создайте новую.
- **Ставить `billing_day: 29–31`.** API не примет: допустимы 1–28, чтобы дата существовала в феврале.
- **Тестировать подписки в песочнице без организации.** Подпискам нужна верифицированная организация — API ответит `400 Subscriptions require a verified organization`.

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

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

**Чем подписка отличается от разового счёта?**
Разовый счёт вы создаёте сами каждый раз. Подписка создаёт такие же счета автоматически по расписанию, сама ретраит неоплату, ведёт grace-период и шлёт события `subscription.*`.

**Покупатель оплатил в grace-периоде — что дальше?**
Подписка возвращается в нормальный цикл: grace снимается, следующий счёт придёт по обычному расписанию.

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

**Как поставить подписку на паузу на время отпуска клиента?**
`POST /subscriptions/{id}/pause`, затем `resume` — выставление продолжится от текущей даты, пропущенные периоды не доначисляются.

**Подписка умерла (`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
