Тарифы и оплата
Просмотр доступных тарифов, создание и сопровождение платежа, история платежей. Платежи обрабатываются через AffiCat Pay. Подробнее о тарифах, продлении и льготном периоде — в разделе Оплата и тарифы.
Все эндпоинты этого раздела требуют авторизации (ваш API-ключ, см. Профиль и API-ключ). Эндпоинты оплаты работают без активной подписки — лапснувший аккаунт может оплатить тариф.
Каждый ответ — это HTTP 200 с Content-Type: application/json. Успех или ошибка
определяются полем status в теле, а не HTTP-кодом. Ошибка всегда приходит в виде
{"status":"error","error":"<код>"}. Поля времени — целые Unix-секунды (0, если
не задано), а не строки с датой.
Список тарифов
GET /api/tariff/list.json
Возвращает все активные тарифы в порядке, заданном администратором. Каждая карточка дополнена предпросмотром начисления (proration): сколько дней даст покупка именно этого тарифа прямо сейчас с учётом остатка текущей подписки.
{
"status": "ok",
"data": [
{
"id": 1,
"code": "kitten",
"name": "Котёнок",
"campaigns": 1,
"price_usd": 0,
"price_rub": 0,
"days": 30,
"broadcasts": false,
"broadcasts_day": 0,
"screens": false,
"crm": false,
"operators": 0,
"until": 1748692800,
"get_days": 30,
"credit_days": 0
},
{
"id": 2,
"code": "cat",
"name": "Котик",
"campaigns": 15,
"price_usd": 24,
"price_rub": 2400,
"days": 30,
"broadcasts": true,
"broadcasts_day": 1350,
"screens": true,
"crm": false,
"operators": 0,
"until": 1751284800,
"get_days": 33,
"credit_days": 3
},
{
"id": 5,
"code": "cattery",
"name": "Котомник",
"campaigns": 100,
"price_usd": 135,
"price_rub": 13500,
"days": 30,
"broadcasts": true,
"broadcasts_day": 13500,
"screens": true,
"crm": true,
"operators": 15,
"until": 1751284800,
"get_days": 31,
"credit_days": 1
}
]
}data — это массив (пустой [], если тарифов нет).
| Поле | Значение |
|---|---|
id | Числовой идентификатор тарифа. Именно его передают в tariff/buy |
code | Машинный код тарифа |
name | Название тарифа, локализованное по языку пользователя. Английское название отдаётся, только если язык — en и в тарифе заполнено английское поле; иначе возвращается русское название (русский — язык по умолчанию) |
campaigns | Лимит кампаний; -1 — без ограничения |
price_usd | Цена в долларах USD |
price_rub | Цена в рублях RUB |
days | Срок подписки в днях |
broadcasts | Доступны ли рассылки |
broadcasts_day | Дневной лимит сообщений рассылок (0, если рассылки недоступны) |
screens | Доступны ли мультиэкранные приветствия |
crm | Доступен ли CRM-чат операторов |
operators | Количество мест операторов CRM (0, если CRM недоступна) |
until | Предполагаемая дата окончания подписки, если купить тариф сейчас (Unix-время) |
get_days | Сколько всего дней даст покупка с учётом остатка текущей подписки |
credit_days | Сколько из них зачтено из остатка текущей подписки (proration) |
| Ошибка | Значение |
|---|---|
db | Ошибка базы данных |
Купить тариф
POST /api/tariff/buy.json
Создаёт платёж по тарифу. Платный тариф создаёт счёт в AffiCat Pay и возвращает URL
страницы оплаты — перенаправьте на него пользователя. Бесплатный тариф
(цена 0 в обеих валютах) активируется мгновенно, без обращения к шлюзу, и URL не
возвращается.
| Параметр | Обязательный | Описание |
|---|---|---|
tariff | ✓ | Числовой идентификатор тарифа — поле id из списка тарифов. Это число, а не машинный код |
Платный тариф — ответ содержит pay_id и url страницы оплаты:
{
"status": "ok",
"pay_id": 55,
"url": "https://core.affi.cat/pay/abc123"
}Бесплатный тариф — счёт сразу помечается оплаченным, URL не нужен:
{
"status": "ok",
"pay_id": 56,
"free": true,
"paid": true
}url — это непрозрачная ссылка на страницу оплаты, которую вернул шлюз; конкретный
хост может отличаться, не зашивайте его жёстко.
После оплаты подписка продлевается автоматически после подтверждения оплаты шлюзом. Оплата также может быть подтверждена через pay/check, когда пользователь возвращается со страницы оплаты — оба пути идемпотентны.
Накопление. Платные тарифы продлеваются от текущей даты окончания, а не от
сегодняшнего дня: при досрочном продлении или переходе остаток пересчитывается в дни
нового тарифа (см. поля get_days/credit_days). А вот бесплатный тариф ставится от
сегодняшнего дня и не накапливается, поэтому он перебил бы ещё действующий платный
период — такой переход блокируется (ошибка active, см. ниже).
| Ошибка | Значение |
|---|---|
func | Параметр tariff отсутствует, равен 0 или указывает на несуществующий/скрытый тариф |
busy | Превышен лимит создания счетов (не более 20 за 60 секунд на пользователя) |
active | Попытка взять бесплатный тариф, пока действующий платный имеет более 5 дней до окончания. Платные продления/переходы этим правилом не блокируются |
pay | Не удалось создать счёт в AffiCat Pay (зависший счёт помечается неуспешным) |
db | Ошибка базы данных |
Возобновить платёж
POST /api/pay/resume
Заново открывает страницу оплаты для собственного незавершённого (ожидающего) платежа
и возвращает её URL. Позволяет завершить брошенный платёж без создания дубликата:
шлюз сопоставляет счёт по магазину и uid, поэтому тот же pay_id всегда ведёт на ту
же форму.
| Параметр | Обязательный | Описание |
|---|---|---|
uid | ✓ | pay_id существующего ожидающего платежа, принадлежащего вам |
{
"status": "ok",
"pay_id": 55,
"url": "https://core.affi.cat/pay/abc123"
}| Ошибка | Значение |
|---|---|
func | Параметр uid отсутствует/равен 0, либо платёж относится к бесплатному тарифу, у которого формы оплаты не было |
busy | Превышен лимит создания счетов (общий с tariff/buy: 20 за 60 секунд) |
access | Платёж не найден или принадлежит другому пользователю |
status | Платёж уже не в статусе ожидания (оплачен, отменён или возвращён) — возобновлять нечего |
pay | Не удалось переоткрыть счёт в AffiCat Pay |
db | Ошибка базы данных |
Отменить платёж
POST /api/pay/cancel
Помечает собственный ожидающий платёж как неуспешный (статус 2) — действие «Отмена»
для брошенного счёта на экране оплаты. Неуспешный счёт уже нельзя превратить в
оплаченный, поэтому поздний постбэк по отменённому счёту безопасно игнорируется.
| Параметр | Обязательный | Описание |
|---|---|---|
uid | ✓ | pay_id собственного ожидающего платежа |
{
"status": "ok",
"pay_id": 55
}| Ошибка | Значение |
|---|---|
func | Параметр uid отсутствует или равен 0 |
access | Платёж не найден, принадлежит другому пользователю или уже не в статусе ожидания |
db | Ошибка базы данных |
Проверить статус платежа
GET /api/pay/check
Pull-подтверждение собственного платежа при возврате со страницы оплаты. Если платёж
уже оплачен, возвращает paid: true; иначе опрашивает AffiCat и, если счёт оплачен,
принимает его (продлевает подписку). Вызывается автоматически при возврате и
идемпотентен с push-постбэком.
| Параметр | Обязательный | Описание |
|---|---|---|
uid | ✓ | pay_id собственного платежа (шлюз добавляет его к return URL) |
{
"status": "ok",
"paid": true
}paid равно false, если шлюз всё ещё сообщает, что счёт не оплачен.
| Ошибка | Значение |
|---|---|
func | Параметр uid отсутствует или равен 0 |
access | Платёж не найден или принадлежит другому пользователю |
pay | Не удалось обратиться к AffiCat за статусом счёта |
db | Ошибка базы данных |
История платежей
GET /api/pay/list.json
Возвращает историю ваших платежей, от новых к старым, с постраничной выборкой. Внутренние данные о расчёте (поступившая сумма, валюта, метаданные) не отдаются.
| Параметр | Обязательный | Описание |
|---|---|---|
limit | Размер страницы; по умолчанию 50, максимум 200 | |
offset | Смещение от начала; значения меньше 0 приводятся к 0 |
{
"status": "ok",
"data": [
{
"id": 55,
"tariff": 2,
"usd": 24,
"rub": 2400,
"status": 1,
"created": 1746111600,
"paid": 1746111720
}
]
}data — это массив (пустой [], если платежей нет). Поле tariff — это числовой
идентификатор тарифа (не код и не название). Поля created и paid — Unix-время в
секундах; paid равно 0 для ожидающих и неоплаченных счетов.
status | Значение |
|---|---|
0 | Ожидает оплаты — счёт создан, оплата не подтверждена |
1 | Оплачен |
2 | Неуспешен или отменён — отклонён шлюзом, отменён пользователем либо брошен |
3 | Возвращён |
| Ошибка | Значение |
|---|---|
db | Ошибка базы данных |