vellTRDocs

Subscriptions

Recurring billing on saved cards. Create, pause, resume, retry, cancel, and trigger immediate charges.

12 endpoints
POST/v1/subscriptionsOptional

Create a recurring subscription. cardToken is optional — it falls back to the customer's default saved card. Accepts an optional Idempotency-Key header.

Request Parameters

NameTypeRequiredDescription
storeIdstringRequiredStore the subscription belongs to
customerIdstringRequiredCustomer being billed
amountMinorintegerRequiredPer-cycle amount in kuruş
currencystringRequiredAlways "TRY"
intervalCountintegerRequiredNumber of interval units per cycle
intervalUnitstringRequiredday|week|month|year
cardTokenstringOptionalSaved card token (defaults to the customer default card)
trialEndAtstringOptionalISO 8601 — start trialing until this date
generateInvoicesbooleanOptionalGenerate an invoice each renewal
descriptionstringOptionalSubscription description
JSONRequest Example
{
  "storeId": "sto_5a6b7c8d",
  "customerId": "cus_a1b2c3d4e5f6",
  "amountMinor": 50000,
  "currency": "TRY",
  "intervalCount": 1,
  "intervalUnit": "month"
}
JSONResponse Example
{
  "id": "sub_5e6f70819a2b",
  "merchantId": "mrc_8a1b2c3d4e5f",
  "storeId": "sto_5a6b7c8d",
  "customerId": "cus_a1b2c3d4e5f6",
  "publicHash": "kQ7rS1tV5wY8zaB3xK9mN2",
  "status": "active",
  "amountMinor": 50000,
  "currency": "TRY",
  "intervalCount": 1,
  "intervalUnit": "month",
  "cycleNumber": 0,
  "nextChargeAt": "2026-05-13T10:00:00Z",
  "cardLast4": "4321",
  "cardBrand": "visa",
  "createdAt": "2026-04-13T10:00:00Z"
}
GET/v1/subscriptionsOptional

List subscriptions with keyset pagination. Filters: storeId, customerId, status, from, to.

Request Parameters

NameTypeRequiredDescription
storeIdstringOptionalFilter by store
customerIdstringOptionalFilter by customer
statusstringOptionaltrialing|active|past_due|paused|cancelled|expired
limitintegerOptionalPage size
cursorstringOptionalOpaque keyset cursor
JSONResponse Example
{
  "items": [
    {
      "id": "sub_5e6f70819a2b",
      "storeId": "sto_5a6b7c8d",
      "status": "active",
      "amountMinor": 50000,
      "currency": "TRY",
      "intervalCount": 1,
      "intervalUnit": "month",
      "nextChargeAt": "2026-05-13T10:00:00Z",
      "createdAt": "2026-04-13T10:00:00Z"
    }
  ],
  "nextCursor": "eyJjcmVhdGVkQXQiOiIyMDI2LTA0LTEzVDEwOjAwOjAwWiJ9"
}
GET/v1/subscriptions/{id}Optional

Retrieve a subscription by id.

JSONResponse Example
{
  "id": "sub_5e6f70819a2b",
  "merchantId": "mrc_8a1b2c3d4e5f",
  "storeId": "sto_5a6b7c8d",
  "customerId": "cus_a1b2c3d4e5f6",
  "status": "active",
  "amountMinor": 50000,
  "currency": "TRY",
  "intervalCount": 1,
  "intervalUnit": "month",
  "cycleNumber": 1,
  "nextChargeAt": "2026-05-13T10:00:00Z",
  "cardLast4": "4321",
  "cardBrand": "visa",
  "createdAt": "2026-04-13T10:00:00Z"
}
GET/v1/subscriptions/{id}/chargesOptional

Per-cycle charge history for a subscription.

JSONResponse Example
{
  "items": [
    {
      "cycleNumber": 1,
      "paymentId": "pay_1a2b3c4d5e6f",
      "status": "captured",
      "amountMinor": 50000,
      "chargedAt": "2026-04-13T10:00:02Z"
    }
  ]
}
POST/v1/subscriptions/{id}/cancelOptional

Cancel immediately (atPeriodEnd=false) or at the end of the current period (atPeriodEnd=true).

Request Parameters

NameTypeRequiredDescription
atPeriodEndbooleanRequiredCancel now (false) or at period end (true)
reasonstringOptionalCancellation reason
JSONRequest Example
{
  "atPeriodEnd": true,
  "reason": "Customer requested"
}
JSONResponse Example
{
  "id": "sub_5e6f70819a2b",
  "status": "active",
  "cancelAtPeriodEnd": true
}
POST/v1/subscriptions/{id}/pauseOptional

Pause an active or trialing subscription. The reconciler ignores paused rows.

JSONRequest Example
{}
JSONResponse Example
{
  "id": "sub_5e6f70819a2b",
  "status": "paused"
}
POST/v1/subscriptions/{id}/resumeOptional

Resume a paused subscription; the next tick attempts an immediate charge.

JSONRequest Example
{}
JSONResponse Example
{
  "id": "sub_5e6f70819a2b",
  "status": "active"
}
POST/v1/subscriptions/{id}/retryOptional

For a past_due subscription, bump nextChargeAt to now so the reconciler retries on the next tick.

JSONRequest Example
{}
JSONResponse Example
{
  "id": "sub_5e6f70819a2b",
  "status": "past_due",
  "nextChargeAt": "2026-04-13T12:00:00Z"
}
POST/v1/subscriptions/{id}/charge-nowOptional

Trigger an immediate renewal charge rather than waiting for nextChargeAt. Returns a queueing receipt; poll GET /v1/subscriptions/{id} until the status flips out of charging.

JSONRequest Example
{}
JSONResponse Example
{
  "status": "queuing",
  "subscriptionId": "sub_5e6f70819a2b",
  "expectedAt": "2026-04-13T10:01:00Z",
  "checkAt": "/v1/subscriptions/sub_5e6f70819a2b"
}
GET/v1/public/subscriptions/{hash}Optional

Buyer-facing read via the public portal link (the publicHash is the bearer).

JSONResponse Example
{
  "publicHash": "kQ7rS1tV5wY8zaB3xK9mN2",
  "merchantName": "Acme Store",
  "status": "active",
  "amountMinor": 50000,
  "currency": "TRY",
  "intervalCount": 1,
  "intervalUnit": "month",
  "cardLast4": "4321",
  "cardBrand": "visa",
  "nextChargeAt": "2026-05-13T10:00:00Z"
}
POST/v1/public/subscriptions/{hash}/cancelOptional

Buyer-side cancel from the portal.

Request Parameters

NameTypeRequiredDescription
atPeriodEndbooleanOptionalCancel at period end (default true)
JSONRequest Example
{
  "atPeriodEnd": true
}
JSONResponse Example
{
  "publicHash": "kQ7rS1tV5wY8zaB3xK9mN2",
  "status": "active",
  "cancelAtPeriodEnd": true
}
POST/v1/public/subscriptions/{hash}/update-card-sessionOptional

Buyer clicks "Update card": mints a card_update_only checkout session and returns its URL.

JSONRequest Example
{}
JSONResponse Example
{
  "sessionId": "2a7b8c9d-0e1f-3f1c-9a2e-6b4d4e8a9c1f",
  "checkoutUrl": "https://pay.kvell.group/s/2a7b8c9d-0e1f-3f1c-9a2e-6b4d4e8a9c1f",
  "expiresAt": "2026-04-13T11:00:00Z"
}

Category Summary

Total Endpoints

12

Base Domain

api.pay.kvell.group