tabpayДокументация
Разделы документации

Документация/API

Рекуррентные платежи

Подписки: продукты, ссылка оформления, подписчики и автосписания

Как устроены подписки

Модель: продукт (тариф с ценой и периодом), его подписчики и автоматические списания. Вы создаёте продукт по API или в кабинете и получаете публичную ссылку оформления (subscribeUrl). Разместите её у себя на сайте или отправьте клиенту: на этой странице он вводит email и данные карты, проходит первое списание, карта привязывается - дальше списания идут автоматически по периоду продукта.

Карточные данные в этом API не участвуют: карту подписчик вводит только на странице оформления TabPay. Подписки работают по банковским картам (СБП не поддерживает привязку).

Авторизация - как во всём API: заголовок X-Api-Key с ключом магазина. Раздел «Подписка» должен быть включён магазину (включается платформой, дальше тумблером в кабинете). Деньги везде - целым числом в копейках.

POST/api/v1/recurrent/products

Создаёт продукт (тариф). В ответе - объект продукта, включая subscribeUrl - публичную ссылку оформления.

name

string, обязательный

Название - показывается подписчику на странице оформления. От 1 до 120 символов.

amountKopecks

integer, обязательный

Стоимость за период, в копейках. От 100 (1 ₽) до 5 000 000 (50 000 ₽).

periodValue

integer, обязательный

Длина периода в единицах interval: 6 + MONTH = раз в полгода. От 1 до 365.

interval

string, обязательный

Единица периода: DAY, MONTH или YEAR.

trialDays

integer, необязательный

Пробный период в днях (0 или не передан - без пробного): карта привязывается при оформлении, первое списание откладывается на это число дней.

description

string, необязательный

Описание - показывается подписчику под названием. До 300 символов.

Объект продукта

Возвращается всеми ручками продуктов.

id

string

Идентификатор продукта (UUID).

name

string

Название.

description

string | null

Описание или null.

amountKopecks

integer

Стоимость за период, копейки.

periodValue

integer

Длина периода в единицах interval.

interval

string

DAY, MONTH или YEAR.

periodText

string

Период человекочитаемо: «раз в месяц», «раз в 6 месяцев».

trialDays

integer

Пробный период в днях, 0 - без пробного.

isActive

boolean

Активен ли продукт: по неактивному нельзя оформить новую подписку, действующие продолжаются.

isTest

boolean

Продукт тестового магазина (песочница).

subscribersTotal

integer

Всего оформленных подписчиков.

subscribersActive

integer

Из них активных.

subscribeUrl

string

Публичная ссылка оформления - разместите её у себя.

createdAt

string

Дата создания (ISO 8601).

Создание продукта
curl -X POST https://tabpay.org/api/v1/recurrent/products \
  -H "X-Api-Key: tp_ваш_ключ" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Подписка на 6 месяцев",
    "amountKopecks": 89900,
    "periodValue": 6,
    "interval": "MONTH",
    "trialDays": 0
  }'
Ответ 201
{
  "id": "0d5b6a52-1b6f-4a83-9c2e-7f39d0a41c11",
  "name": "Подписка на 6 месяцев",
  "description": null,
  "amountKopecks": 89900,
  "periodValue": 6,
  "interval": "MONTH",
  "periodText": "раз в 6 месяцев",
  "trialDays": 0,
  "isActive": true,
  "isTest": false,
  "subscribersTotal": 0,
  "subscribersActive": 0,
  "subscribeUrl": "https://tabpay.org/subscribe/0d5b6a52-1b6f-4a83-9c2e-7f39d0a41c11",
  "createdAt": "2026-09-03T10:00:00.000Z"
}

Управление продуктами

GET/api/v1/recurrent/products

Список продуктов магазина: объект с полями items (массив продуктов) и total. Возвращаются все продукты сразу, без пагинации. Query-параметры:

activeOnly

boolean, необязательный

true - только активные продукты.

GET/api/v1/recurrent/products/{id}

Один продукт по id.

PATCH/api/v1/recurrent/products/{id}

Правка продукта: любые поля создания плюс isActive (пауза оформления). Правка не меняет условия уже оформленных подписчиков - у них снимок на момент оформления, влияет только на новых.

DELETE/api/v1/recurrent/products/{id}

Удаляет продукт: ссылка оформления перестаёт работать, уже оформленные подписки продолжаются. Ответ - ok: true.

Подписчики

GET/api/v1/recurrent/subscribers

Список подписчиков магазина: объект с полями items (массив подписчиков) и total. Query-параметры:

status

string, необязательный

Фильтр по статусу: WAITING_PAYMENT, ACTIVE, ERROR или DEACTIVATED.

productId

string, необязательный

Фильтр по продукту (UUID).

limit

integer, необязательный

Размер страницы, 1-100; по умолчанию 20.

offset

integer, необязательный

Смещение от начала списка.

Объект подписчика

id

string

Идентификатор подписчика (UUID).

productId

string | null

Продукт подписки; null, если продукт удалён.

productName

string | null

Название продукта на момент оформления.

status

string

Статус подписки - см. ниже.

amountKopecks

integer

Базовая стоимость периода на момент оформления, копейки.

chargedKopecks

integer

Сколько реально списывается с подписчика за период, копейки (с учётом сплита комиссии).

commissionPayer

string

Кто платит комиссию: MERCHANT, CUSTOMER или SPLIT (снимок на момент оформления).

periodValue

integer

Длина периода в единицах interval (снимок на момент оформления).

interval

string

DAY, MONTH или YEAR.

periodText

string

Период человекочитаемо.

isTrial

boolean

Идёт ли пробный период.

payerEmail

string

Email подписчика.

payerPhone

string | null

Телефон подписчика или null.

cardMask

string | null

Маска привязанной карты (первые 6 и последние 4 цифры) или null до активации.

nextPayAt

string | null

Дата следующего списания; null у неактивных.

activatedAt

string | null

Когда подписка активировалась (прошло первое списание или привязалась карта в триале).

deactivatedAt

string | null

Когда подписка отключилась; null у действующих.

deactivationReason

string | null

Причина отключения или null.

isTest

boolean

Подписка тестового магазина (песочница).

createdAt

string

Когда подписчик начал оформление (ISO 8601).

Статусы подписки

  • WAITING_PAYMENT - оформление начато, ждём результат первого платежа (3DS, обработка банка).
  • ACTIVE - подписка действует, списания идут по расписанию.
  • ERROR - очередное списание не прошло - провайдер попробует ещё раз, при исчерпании попыток подписка отключится.
  • DEACTIVATED - подписка отключена: отменена вами, подписчиком или после неудачных списаний.
Активные подписчики
curl "https://tabpay.org/api/v1/recurrent/subscribers?status=ACTIVE" \
  -H "X-Api-Key: tp_ваш_ключ"
Ответ 200
{
  "items": [
    {
      "id": "7f0a1a4e-52aa-4a10-8f3d-2b8d0c9f66b1",
      "productId": "0d5b6a52-1b6f-4a83-9c2e-7f39d0a41c11",
      "productName": "Подписка на 6 месяцев",
      "status": "ACTIVE",
      "amountKopecks": 89900,
      "chargedKopecks": 89900,
      "commissionPayer": "MERCHANT",
      "periodValue": 6,
      "interval": "MONTH",
      "periodText": "раз в 6 месяцев",
      "isTrial": false,
      "payerEmail": "user@example.com",
      "payerPhone": null,
      "cardMask": "553691******1279",
      "nextPayAt": "2027-03-03T10:00:00.000Z",
      "activatedAt": "2026-09-03T10:00:00.000Z",
      "deactivatedAt": null,
      "deactivationReason": null,
      "isTest": false,
      "createdAt": "2026-09-03T09:58:12.000Z"
    }
  ],
  "total": 1
}
GET/api/v1/recurrent/subscribers/{id}

Один подписчик по id, дополнительно с историей его списаний - последние 50, новые сверху (charges: id, status, amountKopecks, chargedKopecks, paidAt, createdAt).

POST/api/v1/recurrent/subscribers/{id}/cancel

Отменяет подписку: дальнейшие списания прекращаются, статус становится DEACTIVATED. Ответ - обновлённый объект подписчика.

Отмена подписки
curl -X POST \
  https://tabpay.org/api/v1/recurrent/subscribers/7f0a1a4e-52aa-4a10-8f3d-2b8d0c9f66b1/cancel \
  -H "X-Api-Key: tp_ваш_ключ"

Подписка под клиента

POST/api/v1/recurrent/subscriptions

Создаёт подписку по API под конкретного клиента: черновик подписчика с зафиксированными контактами и суммой. В ответе - объект подписчика плюс payUrl: персональная ссылка оплаты, где email уже заполнен, клиент вводит только карту.

Отдайте payUrl клиенту (редирект после оформления заказа, письмо, бот) и опрашивайте подписчика по id (GET /subscribers/) до статуса ACTIVE. Черновик сам по себе ничего не списывает и не активируется.

productId

string, обязательный

Продукт (тариф), UUID.

payerEmail

string, обязательный

Email клиента - фиксируется на странице оплаты.

payerPhone

string, необязательный

Телефон клиента в формате 7XXXXXXXXXX.

telegramId

string, необязательный

Телеграм-ID клиента (для ботов): сохраняется у подписчика и возвращается в объектах и вебхуках платежей-списаний (поле telegramId); в самом объекте подписчика поля нет.

Ответ - объект подписчика (см. выше) плюс поле payUrl. В черновике заморожены сумма, комиссия и период: правка продукта на них не влияет, и страница оплаты показывает именно их. Пробный период и тестовый режим берутся от продукта на момент оплаты. Черновик не появляется в списке GET /subscribers, пока клиент не начал оплату, - проверяйте его по id. Ссылка бессрочна; ненужный черновик отменяется ручкой cancel. Повторный вызов создаёт новый черновик. Если сумма с комиссией покупателя превышает 50 000 ₽, создание вернёт 409.

Создание подписки
curl -X POST https://tabpay.org/api/v1/recurrent/subscriptions \
  -H "X-Api-Key: tp_ваш_ключ" \
  -H "Content-Type: application/json" \
  -d '{
    "productId": "0d5b6a52-1b6f-4a83-9c2e-7f39d0a41c11",
    "payerEmail": "user@example.com"
  }'
Ответ 201 (сокращён)
{
  "id": "7f0a1a4e-52aa-4a10-8f3d-2b8d0c9f66b1",
  "status": "WAITING_PAYMENT",
  "payerEmail": "user@example.com",
  "amountKopecks": 89900,
  "chargedKopecks": 89900,
  "payUrl": "https://tabpay.org/subscribe/0d5b6a52-1b6f-4a83-9c2e-7f39d0a41c11?s=7f0a1a4e-52aa-4a10-8f3d-2b8d0c9f66b1"
}
POST/api/v1/recurrent/subscribers/{id}/reschedule

Переносит следующее списание вперёд на days дней (пропуск платежа). Только для активной подписки и только вперёд: дату раньше уже назначенной провайдер не разрешает. Ответ - обновлённый объект подписчика с новым nextPayAt.

days

integer, обязательный

На сколько дней сдвинуть следующее списание, 1-365.

Пропуск платежа
curl -X POST \
  https://tabpay.org/api/v1/recurrent/subscribers/7f0a1a4e-52aa-4a10-8f3d-2b8d0c9f66b1/reschedule \
  -H "X-Api-Key: tp_ваш_ключ" \
  -H "Content-Type: application/json" \
  -d '{ "days": 30 }'