tgpay cryptoAPI
crypto-payapisubscriptionsrecurring

API reference: subscriptions

2 min readUpdated Aug 22, 2026

Recurring billing — an extension over Crypto Bot. You create a plan (amount + period), send users its approval link, and the platform charges them from their wallet balance every period, crediting your app balance net of fee. Conventions are on the Merchant API reference page.

The model

A plan is an immutable snapshot: the mandate a user approves is exactly this amount per this period. To change the price, create a new plan and archive the old one — existing subscribers keep renewing on the terms they approved. The first period is charged at approval.

Renewals bill automatically at each period’s end. When a renewal fails (insufficient balance, restricted account), the subscription enters grace and the platform retries hourly within the grace period (currently 48 hours); if it still can’t collect, the subscription becomes expired. Merchants read current_period_end as the access deadline.

Every lifecycle event has an opt-in webhook: subscription_activated, subscription_charged, subscription_cancelled, subscription_expired.

createSubscriptionPlan

POST /pay/api/createSubscriptionPlan — scope subscriptions.

ParameterTypeRequiredMeaning
namestringyes1–64 characters, shown to the subscriber
assetstringyesasset code
amountstringyesthe per-period charge, positive decimal string
period_daysintegeryesbilling period in days, from the platform minimum (currently 7) to 365

The result is the plan object: plan_id, name, asset, amount, amount_minor, period_days, archived, mini_app_subscribe_url — the t.me link you send users to approve — and created_at.

Errors: 404 unknown_asset, 400 invalid_amount, 409 invalid_period, 503 subs_disabled (the feature is switched off platform-side).

getSubscriptionPlans

GET /pay/api/getSubscriptionPlans — scope read, no parameters. Returns {"items": [plan, …]}, newest first, each with one extra field: active_subscribers — the count of live (active + grace) subscriptions on the plan.

archiveSubscriptionPlan

POST /pay/api/archiveSubscriptionPlan — scope subscriptions. One parameter: plan_id. Stops new approvals; existing subscriptions keep renewing on their snapshot (end them one by one with cancelSubscription). Archiving can’t be undone through the API. The result is the updated plan object with archived: true. Error: 404 plan_not_found.

getSubscriptions

GET /pay/api/getSubscriptions — scope read. Filters: plan_id, user_id, status (active / grace / cancelled / expired), plus offset / count (max 500). Returns {"items": [subscription, …]}, newest first.

The subscription object: subscription_id, plan_id, user_id (the subscriber’s Telegram ID), the snapshot terms (asset, amount, amount_minor, period_days), status, auto_renew, period_no (paid periods so far), current_period_start / current_period_end, created_at, cancelled_at, cancelled_by (user or merchant), expired_at.

cancelSubscription

POST /pay/api/cancelSubscription — scope subscriptions. One parameter: subscription_id. Stops renewals (cancelled_by: "merchant"); the paid period stays usable until current_period_end, the status flips to cancelled immediately, and the subscriber is notified. A canceled subscriber can re-approve later through the same plan link. The result is the updated subscription object.

Errors: 404 sub_not_found, 409 sub_not_active (already canceled or expired).