Documentation sections

Documentation/API

Recurring payments

Subscriptions: products, subscribe link, subscribers, and automatic charges

How subscriptions work

The model: a product (a plan with a price and period), its subscribers, and automatic charges. You create a product via API or in the dashboard and get a public subscribe link (subscribeUrl). Place it on your site or send it to a customer: on that page they enter an email and card details, the first charge is made, the card is bound - and further charges run automatically per the product period.

Card data is not part of this API: the subscriber enters the card only on the TabPay subscribe page. Subscriptions work with bank cards (SBP does not support binding).

Authorization is the same as the rest of the API: the X-Api-Key header with a shop key. The Subscription method must be enabled for the shop (enabled by the platform, then toggled in the dashboard). All money values are integers in kopecks.

POST/api/v1/recurrent/products

Creates a product (plan). The response is the product object, including subscribeUrl - the public subscribe link.

name

string, required

Name - shown to the subscriber on the subscribe page. 1 to 120 characters.

amountKopecks

integer, required

Price per period, in kopecks. From 100 (1 RUB) to 5 000 000 (50 000 RUB).

periodValue

integer, required

Period length in interval units: 6 + MONTH = every six months. 1 to 365.

interval

string, required

Period unit: DAY, MONTH, or YEAR.

trialDays

integer, optional

Trial period in days (0 or omitted - no trial): the card is bound at signup, the first charge is postponed by this number of days.

description

string, optional

Description - shown to the subscriber below the name. Up to 300 characters.

Product object

Returned by all product endpoints.

id

string

Product identifier (UUID).

name

string

Name.

description

string | null

Description or null.

amountKopecks

integer

Price per period, kopecks.

periodValue

integer

Period length in interval units.

interval

string

DAY, MONTH, or YEAR.

periodText

string

Human-readable period, always in Russian ('раз в 6 месяцев').

trialDays

integer

Trial period in days, 0 - no trial.

isActive

boolean

Whether the product is active: an inactive product cannot take new subscriptions, existing ones continue.

isTest

boolean

Product of a test shop (sandbox).

subscribersTotal

integer

Total subscribers.

subscribersActive

integer

Active subscribers.

subscribeUrl

string

Public subscribe link - place it on your site.

createdAt

string

Creation date (ISO 8601).

Create a product
curl -X POST https://tabpay.org/api/v1/recurrent/products \
  -H "X-Api-Key: tp_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "6-month subscription",
    "amountKopecks": 89900,
    "periodValue": 6,
    "interval": "MONTH",
    "trialDays": 0
  }'
Response 201
{
  "id": "0d5b6a52-1b6f-4a83-9c2e-7f39d0a41c11",
  "name": "6-month subscription",
  "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"
}

Managing products

GET/api/v1/recurrent/products

The shop's products: an object with items (product array) and total. All products are returned at once, without pagination. Query parameters:

activeOnly

boolean, optional

true - active products only.

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

A single product by id.

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

Updates a product: any creation field plus isActive (pause signups). Updating does not change the terms of existing subscribers - they keep a snapshot from signup time; only new subscribers are affected.

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

Deletes the product: the subscribe link stops working, existing subscriptions continue. Response - ok: true.

Subscribers

GET/api/v1/recurrent/subscribers

The shop's subscribers: an object with items (subscriber array) and total. Query parameters:

status

string, optional

Filter by status: WAITING_PAYMENT, ACTIVE, ERROR, or DEACTIVATED.

productId

string, optional

Filter by product (UUID).

limit

integer, optional

Page size, 1-100; default 20.

offset

integer, optional

Offset from the start of the list.

Subscriber object

id

string

Subscriber identifier (UUID).

productId

string | null

The subscription's product; null if the product was deleted.

productName

string | null

Product name at signup time.

status

string

Subscription status - see below.

amountKopecks

integer

Base period price at signup time, kopecks.

chargedKopecks

integer

What the subscriber is actually charged per period, kopecks (including the fee split).

commissionPayer

string

Who pays the fee: MERCHANT, CUSTOMER, or SPLIT (snapshot at signup time).

periodValue

integer

Period length in interval units (snapshot at signup time).

interval

string

DAY, MONTH, or YEAR.

periodText

string

Human-readable period, always in Russian ('раз в 6 месяцев').

isTrial

boolean

Whether the trial period is in progress.

payerEmail

string

Subscriber email.

payerPhone

string | null

Subscriber phone or null.

cardMask

string | null

Bound card mask (first 6 and last 4 digits) or null before activation.

nextPayAt

string | null

Next charge date; null for inactive subscriptions.

activatedAt

string | null

When the subscription activated (first charge succeeded, or the card was bound during a trial).

deactivatedAt

string | null

When the subscription was deactivated; null while active.

deactivationReason

string | null

Deactivation reason or null.

isTest

boolean

Subscription of a test shop (sandbox).

createdAt

string

When the subscriber started signup (ISO 8601).

Subscription statuses

  • WAITING_PAYMENT - signup started, waiting for the first payment result (3DS, bank processing).
  • ACTIVE - the subscription is active, charges run on schedule.
  • ERROR - a scheduled charge failed - the provider will retry; when retries are exhausted, the subscription deactivates.
  • DEACTIVATED - the subscription is off: cancelled by you, by the subscriber, or after failed charges.
Active subscribers
curl "https://tabpay.org/api/v1/recurrent/subscribers?status=ACTIVE" \
  -H "X-Api-Key: tp_your_key"
Response 200
{
  "items": [
    {
      "id": "7f0a1a4e-52aa-4a10-8f3d-2b8d0c9f66b1",
      "productId": "0d5b6a52-1b6f-4a83-9c2e-7f39d0a41c11",
      "productName": "6-month subscription",
      "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}

A single subscriber by id, with their charge history - the latest 50, newest first (charges: id, status, amountKopecks, chargedKopecks, paidAt, createdAt).

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

Cancels the subscription: further charges stop, the status becomes DEACTIVATED. Response - the updated subscriber object.

Cancel a subscription
curl -X POST \
  https://tabpay.org/api/v1/recurrent/subscribers/7f0a1a4e-52aa-4a10-8f3d-2b8d0c9f66b1/cancel \
  -H "X-Api-Key: tp_your_key"

Subscription for a specific customer

POST/api/v1/recurrent/subscriptions

Creates a subscription via API for a specific customer: a subscriber draft with fixed contacts and amount. The response is the subscriber object plus payUrl: a personal payment link with the email already filled in - the customer only enters the card.

Hand payUrl to the customer (checkout redirect, email, bot) and poll the subscriber by id (GET /subscribers/) until the status is ACTIVE. The draft itself never charges or activates on its own.

productId

string, required

Product (plan), UUID.

payerEmail

string, required

Customer email - fixed on the payment page.

payerPhone

string, optional

Customer phone in 7XXXXXXXXXX format.

telegramId

string, optional

Customer Telegram ID (for bots): stored with the subscriber and returned in charge payment objects and webhooks (the telegramId field); the subscriber object itself does not include it.

The response is the subscriber object (see above) plus the payUrl field. The draft freezes the amount, fee, and period: editing the product does not affect them, and the payment page shows exactly these values. The trial period and test mode are taken from the product at payment time. The draft does not appear in the GET /subscribers list until the customer starts paying - check it by id. The link never expires; an unneeded draft can be cancelled via the cancel endpoint. Repeated calls create new drafts. If the amount including the customer's fee exceeds 50 000 RUB, creation returns a 409.

Create a subscription
curl -X POST https://tabpay.org/api/v1/recurrent/subscriptions \
  -H "X-Api-Key: tp_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "productId": "0d5b6a52-1b6f-4a83-9c2e-7f39d0a41c11",
    "payerEmail": "user@example.com"
  }'
Response 201 (abridged)
{
  "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

Moves the next charge forward by days (skip a payment). Only for an active subscription and only forward: the provider does not allow a date earlier than the one already scheduled. The response is the updated subscriber object with the new nextPayAt.

days

integer, required

How many days to move the next charge forward, 1-365.

Skip a payment
curl -X POST \
  https://tabpay.org/api/v1/recurrent/subscribers/7f0a1a4e-52aa-4a10-8f3d-2b8d0c9f66b1/reschedule \
  -H "X-Api-Key: tp_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "days": 30 }'