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.
/api/v1/recurrent/productsCreates 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).
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
}'{
"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
/api/v1/recurrent/productsThe 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.
/api/v1/recurrent/products/{id}A single product by id.
/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.
/api/v1/recurrent/products/{id}Deletes the product: the subscribe link stops working, existing subscriptions continue. Response - ok: true.
Subscribers
/api/v1/recurrent/subscribersThe 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.
curl "https://tabpay.org/api/v1/recurrent/subscribers?status=ACTIVE" \
-H "X-Api-Key: tp_your_key"{
"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
}/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).
/api/v1/recurrent/subscribers/{id}/cancelCancels the subscription: further charges stop, the status becomes DEACTIVATED. Response - the updated subscriber object.
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
/api/v1/recurrent/subscriptionsCreates 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.
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"
}'{
"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"
}/api/v1/recurrent/subscribers/{id}/rescheduleMoves 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.
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 }'