Planlar
Plan, bir ürünü müşterinin abone olabileceği bir şeye dönüştürür: bir fiyat, bir para birimi, opsiyonel bir deneme süresi ve motora her faturanın ne zaman üretileceğini söyleyen bir billing kuralı. Başarısızlık senaryosu da planın sorumluluğundadır — başarısız çekimin kaç kez yeniden deneneceği (maxDunningAttempts), hangi günlerde deneneceği (dunningScheduleDays) ve tahsilat kovalanırken müşterinin erişimi ne kadar koruyacağı (gracePeriodDays).
price minor-unit (kuruş) integer'dır: "price": 49900 = ₺499,00.
Endpoint'ler
Hepsi Bearer ile doğrulanır (at_live_…); listeler cursor pagination kullanır (pageSize, pageToken; productId / includeArchived ile filtre).
| Method | Path | Ne yapar |
|---|---|---|
| POST | /api/v1/subscriptions/plans | Plan oluşturur |
| GET | /api/v1/subscriptions/plans | Listeler (productId, includeArchived filtreleri) |
| GET | /api/v1/subscriptions/plans/:id | Tek planı getirir |
| PATCH | /api/v1/subscriptions/plans/:id | Günceller |
| DELETE | /api/v1/subscriptions/plans/:id | Arşivler (soft delete) |
| GET | /api/v1/subscriptions/plans/:id/translations | Çevirileri listeler |
| PATCH | /api/v1/subscriptions/plans/:id/translations/:locale | Çeviri oluşturur veya günceller |
Plan oluşturma
curl -X POST https://api-gateway.lunixi.com/api/v1/subscriptions/plans \
-H "Authorization: Bearer at_live_5f3e2b1a..." \
-H "Content-Type: application/json" \
-d '{
"productId": "prd_4b2e88",
"code": "pro-monthly",
"name": "Pro Aylık",
"price": 49900,
"currency": "TRY",
"trialPeriodDays": 7,
"billing": {
"frequency": "MONTHLY",
"interval": 1,
"byMonthDay": [15],
"timezone": "Europe/Istanbul",
"lastDayOfMonthFix": true
},
"maxDunningAttempts": 3,
"dunningScheduleDays": [1, 3, 7],
"gracePeriodDays": 7
}'Alanlar
| Alan | Tip | Not |
|---|---|---|
productId | string, zorunlu | Bu planın fiyatlandırdığı ürün. |
code | string, zorunlu | Sizin sabit kimliğiniz (örn. pro-monthly), merchant başına benzersiz. |
name | string, zorunlu | Müşteriye görünen ad (temel locale). |
description | string | Müşteriye görünen açıklama. |
price | integer, zorunlu | Minor unit. 49900 = ₺499,00. |
currency | string, zorunlu | ISO kodu, örn. TRY. |
trialPeriodDays | integer ≥ 0 | Ücretsiz deneme süresi; abonelik trial'da başlar ve otomatik dönüşür. 0/gönderilmezse deneme yok. |
billing | object, zorunlu | Billing kuralı — aşağıda. |
maxDunningAttempts | integer 0–10 | Başarısız çekimden sonra faturadan vazgeçilmeden önce kaç deneme yapılacağı. |
dunningScheduleDays | integer[] | Denemelerin çalışacağı, başarısızlıktan sonraki günler — [1, 3, 7] 1., 3. ve 7. günde dener. |
gracePeriodDays | integer ≥ 0 | Dunning sürerken aboneliğin erişimi ne kadar koruyacağı. |
metadata | object | Serbest key/value deposu. |
Billing kuralı
billing nesnesi bir tekrarlama kuralıdır — RRULE ile aynı yapı taşları:
| Alan | Tip | Anlamı |
|---|---|---|
frequency | DAILY | WEEKLY | MONTHLY | YEARLY, zorunlu | Temel ritim. |
interval | integer 1–365, zorunlu | Her N frekans biriminde bir — frequency: MONTHLY, interval: 3 üç ayda bir faturalar. |
byMonthDay | integer[] | Faturalamayı ayın belirli günlerine sabitler, örn. [15]. |
byWeekDay | string[] | Haftalık ritimler için: ["MO", "WE", "FR"]. |
timezone | string, zorunlu | Kuralın değerlendirildiği IANA saat dilimi, örn. Europe/Istanbul. "Ayın 15'inde" demek bu dilimde 15'i demektir. |
lastDayOfMonthFix | boolean, zorunlu | true iken 31'ine sabitlenmiş bir döngü, kısa aylarda ayı atlamak yerine ayın son gününde faturalar. |
count | integer ≥ 1 | Toplam tekrar sayısı; süresiz abonelik için göndermeyin (null). |
Hazır tarifler:
{ "frequency": "MONTHLY", "interval": 1, "timezone": "Europe/Istanbul", "lastDayOfMonthFix": true } // klasik aylık
{ "frequency": "MONTHLY", "interval": 3, "byMonthDay": [1], "timezone": "Europe/Istanbul", "lastDayOfMonthFix": true } // üç ayda bir, ayın 1'inde
{ "frequency": "WEEKLY", "interval": 1, "byWeekDay": ["MO"], "timezone": "Europe/Istanbul", "lastDayOfMonthFix": false } // her pazartesi
{ "frequency": "YEARLY", "interval": 1, "timezone": "Europe/Istanbul", "lastDayOfMonthFix": true, "count": 3 } // 3 yıllık çekim, sonra biterGüncelleme & arşivleme
PATCH /api/v1/subscriptions/plans/:id; name, description, price, trialPeriodDays, billing, dunning alanları ve metadata'yı (artı audit için reason) günceller. Bir fiyat güncellemesinin mevcut abonelere ulaşıp ulaşmayacağı ve ne zaman ulaşacağı ürün/abonelik fiyat politikasınca belirlenir (LOCKED / FOLLOW_PLAN, IMMEDIATE / NEXT_PERIOD) — bkz. Ürünler.
DELETE /api/v1/subscriptions/plans/:id planı arşivler: artık abone olunamaz ve public katalogdan çıkar; ancak üzerindeki mevcut abonelikler normal faturalanmaya devam eder.
curl -X DELETE https://api-gateway.lunixi.com/api/v1/subscriptions/plans/pln_9f3a1c \
-H "Authorization: Bearer at_live_5f3e2b1a..." \
-H "Content-Type: application/json" \
-d '{ "reason": "pro-monthly-v2 ile değiştirildi" }'Çeviriler & vitrin metinleri
Plan name / description alanları tıpkı ürünlerdeki gibi yerelleşir — PATCH …/plans/:id/translations/:locale ve { "name": …, "description": … }; locale geçilen her yerde (public catalog, portal) otomatik sunulur.
Pricing sayfanızda planın altındaki pazarlama maddeleri — "500 işlem / ay", "Öncelikli destek" — planın vitrin özellikleridir: sıralı, locale bazlı görüntüleme metinleri; merchant panelinden yönetilir ve Public Catalog API'de planla birlikte döner. Bunlar yalnızca sunumdur; zorlanabilir kotalar Özellikler & entitlement tarafında yaşar.
Yanıt
{
"id": "pln_9f3a1c",
"productId": "prd_4b2e88",
"code": "pro-monthly",
"name": "Pro Aylık",
"price": 49900,
"currency": "TRY",
"trialPeriodDays": 7,
"billing": {
"frequency": "MONTHLY",
"interval": 1,
"byMonthDay": [15],
"timezone": "Europe/Istanbul",
"lastDayOfMonthFix": true
},
"maxDunningAttempts": 3,
"dunningScheduleDays": [1, 3, 7],
"gracePeriodDays": 7,
"isActive": true,
"createdAt": "2026-07-06T09:31:00Z"
}Plan değişikliği
Mevcut bir aboneyi başka plana taşımak planın değil aboneliğin işlemidir: POST /api/v1/subscriptions/subscriptions/:id/change-plan, behavior: "IMMEDIATE" (hemen geçir ve mahsuplaş) veya "NEXT_PERIOD" (dönem sınırına planla) ile. Upgrade, downgrade ve ürettikleri event'ler Abonelikler sayfasında anlatılır.
Hatalar
| Durum | Anlamı | Ne yapmalı |
|---|---|---|
400 | Doğrulama hatası (negatif price, 1–365 dışında interval, 10'dan büyük maxDunningAttempts, boş dunningScheduleDays) | İşaretlenen alanları düzeltin. |
401 | Eksik veya geçersiz API key | Authorization: Bearer at_live_… gönderin. |
404 | productId veya plan bulunamadı | Önce ürünü oluşturun; id'yi kontrol edin. |
409 | Mükerrer plan code'u | Kodlar merchant başına benzersizdir. |
Webhook'lar
| Event | Ne zaman |
|---|---|
plan.created | Plan oluşturuldu. |
plan.updated | Alanlar, fiyat veya çeviriler değişti. |
plan.archived | Plan DELETE ile arşivlendi. |
Sonraki adımlar
- Abonelikler — müşteri abone etme, iptal, duraklatma, plan değişikliği
- Ürünler — fiyat-değişikliği politikası ve katalog çevirileri
- Pricing & Portal SDK — bu planları kendi pricing sayfanızda gösterin
- Faturalar — billing kuralının her dönem ürettiği şey