Коротко
Подписка у нас — это выставление счёта по расписанию. В назначенный день система создаёт клиенту новый счёт, а клиент сам подтверждает его в Kaspi. Деньги со счёта клиента не уходят сами. Так устроено и технически, и юридически: оплата по Kaspi QR требует подтверждения покупателем каждый раз, а мы работаем через роль кассира — доступа к счёту покупателя у нас нет и быть не может.
Поэтому при проектировании подписочного бизнеса главный вопрос звучит иначе: как сделать так, чтобы клиенту было удобно платить каждый месяц, и что делать с теми, кто не заплатил.
Что автоматизируется, а что нет
| Что | Автоматически? |
|---|---|
| Выставление счёта | Да, по расписанию |
| Доставка счёта клиенту | Да, при счёте по телефону приходит push в Kaspi |
| Подтверждение оплаты | Нет. Подтверждает клиент |
| Повторная отправка, если не оплачено | Да, по лестнице повторов |
| Открытие и закрытие доступа | На вашей стороне, по вебхуку |
Этот принцип стоит объяснить и клиенту: «каждый месяц в Kaspi придёт счёт, нужно подтвердить». Зато не будет жалоб на неожиданный платёж — в этом смысле схема даже удобнее.
Схема работы по шагам
| Шаг | Кто | Что происходит |
|---|---|---|
| 1 | Вы | Создаёте клиенту подписку: сумма, интервал, дата старта |
| 2 | Qut Pay | В нужный момент выставляет счёт |
| 3 | Клиент | Подтверждает в Kaspi |
| 4 | Qut Pay | Шлёт на ваш адрес событие invoice.paid |
| 5 | Ваш сервер | Продлевает доступ на следующий период |
| 6 | Если не оплачено | Счёт выставляется снова по лестнице повторов |
| 7 | Когда лестница кончилась | Запуск отбрасывается, расписание идёт дальше |
Интервал и расписание
Интервалы: day, week, month. К ним добавляется кратность — поле every. Например month + every: 3 означает раз в квартал.
Подписка запоминает, через какого кассира она создана. Если кассир меняется, это нужно учесть.
Полный список полей и методов: API подписок.
Лестница повторов
Если клиент не подтвердил счёт сразу, система выставит его заново. Сколько раз и с какими паузами — задаёт поле retryDelaysMin, в минутах.
Значение по умолчанию: [15, 60, 360] — через 15 минут, затем через час, затем через шесть часов. Максимум 5 значений.
Когда лестница заканчивается, этот запуск отбрасывается, но подписка не умирает — расписание продолжается со следующего периода. В подписке хранятся failedRuns, lastError и lastRunStatus, по ним видно, что произошло.
Как подобрать лестницу:
| Бизнес | Рекомендация | Почему |
|---|---|---|
| Спортзал, курс | [60, 720, 1440] | Клиент не торопится, дёргать его каждые 15 минут незачем |
| SaaS, сервис | [15, 60, 360] | Значение по умолчанию, его хватает |
| Доставка еды | [10, 30, 60] | Вопрос должен решиться в течение дня |
Слишком частые повторы раздражают: клиенту в Kaspi прилетает счёт за счётом.
Политика пропусков
Бывает, что запуск не отработал вовремя — подписка была на паузе, оборвалась привязка, был технический перерыв. Что делать в таком случае, решает misfirePolicy:
| Значение | Что происходит |
|---|---|
run_once (по умолчанию) | Пропущенный запуск выполняется один раз |
skip | Пропущенный запуск отбрасывается, ждём следующего |
misfireAfterMin — с какой задержки запуск считается пропущенным. По умолчанию 1440 минут, то есть сутки.
Что выбрать: для месячного абонемента правильнее run_once (клиент всё равно должен оплатить этот месяц). Для ежедневной доставки — skip: выставлять счёт за вчерашний обед бессмысленно.
Пауза, возобновление и catchUp
POST /api/v1/subscriptions/{id}/pause— временно остановить. Клиент уехал в отпуск, заболел.POST /api/v1/subscriptions/{id}/resume— возобновить.POST /api/v1/subscriptions/{id}/resumeс телом{ "catchUp": true }— возобновить и сразу отправить пропущенный запуск.
С catchUp будьте осторожны: на долго стоявшей подписке он может отправить клиенту несколько счетов подряд. Если пауза была длинной, возобновляйте без catchUp, а за пропущенный период выставьте один счёт вручную.
Напоминание клиенту заранее
Это самая полезная привычка в подписочном бизнесе, и делаете её целиком вы. За день-два до выставления счёта отправьте клиенту сообщение:
«Завтра в Kaspi придёт счёт за абонемент, 12 000 ₸. Подтвердите — доступ не прервётся.»
Что это даёт:
- Клиент готов, счёт не приходит «из ниоткуда»
- Оплата чаще происходит ещё до первого повтора
- Если человек хочет остановиться, он скажет заранее — и вы не выставите счёт впустую
Отправляйте через WhatsApp, SMS или собственное приложение. Подключённый Telegram-бот заодно покажет вам события по подпискам.
Отчётность
Через вебхуки приходят события subscription.created, subscription.status, а по каждому счёту — обычные invoice.created, invoice.paid, invoice.expired.
За чем стоит следить:
| Показатель | Откуда берётся |
|---|---|
| Доля оплативших с первого раза | Соотношение invoice.paid и invoice.created |
| Кто дошёл до повторов | Отмечайте у себя, на каком по счёту запуске оплатили |
| Кто не заплатил совсем | Подписки с растущим failedRuns |
| Выручка за месяц | Раздел «Счета» в кабинете, выгрузка CSV |
Передать выгрузку бухгалтеру: Экспорт CSV и отчётность.
Есть ли вариант без кода
Отчасти. Подписку можно создать вручную в разделе Подписки кабинета — программист для этого не нужен. А вот чтобы доступ открывался по вебхуку сам, сервер понадобится.
Если клиентов немного (20-30 человек), можно обойтись и без вебхуков: смотрите оплаты в кабинете и ведёте доступ руками. При фиксированной сумме подойдёт и обычная ссылка на оплату — клиент открывает её раз в месяц.
На что обратить внимание
- Подписка — это расписание выставления счетов, а не автоматическое удержание средств. Пишите так же и в маркетинге, иначе клиент почувствует себя обманутым.
- Изменилась сумма — обновите подписку. Иначе уйдёт счёт со старой суммой.
- Посчитайте месячный лимит. 500 подписчиков × 1 счёт в месяц + повторы должны укладываться в тариф: Какой тариф выбрать.
- Если оборвалась привязка кассира, запуски не пройдут. Подключите Telegram-бота, узнаете сразу.
- Счета не выставляются — разбор причин здесь: Подписка не выставляет счета.
Вопросы и ответы
Можно брать деньги, не спрашивая клиента каждый месяц? Нет. В этой схеме это невозможно — клиент подтверждает каждый платёж в приложении Kaspi.
Когда закрывать доступ, если клиент не подтвердил? Решаете вы. Частая практика: 1-3 дня «льготного периода» после того, как кончилась лестница повторов, потом закрытие.
Продаю годовой абонемент — нужна ли подписка? Нет. Если платёж раз в год, просто выставьте один счёт.
Что делать, если клиент хочет отменить? Поставьте подписку на паузу или остановите совсем. В Kaspi ничего отключать не нужно — достаточно, чтобы с нашей стороны счета перестали выставляться.
Как это выглядит конкретно для зала или онлайн-школы? Для этих сфер есть отдельные статьи: Спортзал и фитнес, Онлайн-школа и платформа курсов.