📚 Subscription Sistemi

ULTIMATE KILAVUZ

Tüm Bilgiler Tek Sayfada - Master Plan + Settings + Kullanıcı Durumları + Device Hierarchy

📅 2025-12-05 🎯 Basit & Net & Minimal ✅ Production Ready 🚀 Complete Guide

📑 İçindekiler

1️⃣ ULTIMATE Master Plan

🎯 Stratejik Kararlar (DEĞIŞMEZ)

✅ Kabul Edilen Kararlar

  • ✅ Trial otomatik başlar (friction azalt)
  • ✅ 7 gün (plan cycle'dan gelir)
  • ✅ is_trial checkbox (slug değil)
  • ✅ has_used_trial kontrolü (tek kullanım)
  • ✅ 30 saniye preview (hardcode)
  • ✅ Request-level fresh check (cache yok)
  • ✅ Event-based system (Observer pattern)
  • ✅ Hibrit sistem (Lazy + Cron)

🔧 Teknik Mimari

  • 📦 SubscriptionService (core logic)
  • 🔔 Event System (SubscriptionExpired vb.)
  • ⏱️ Cron Job (expire check, daily)
  • 🎯 Request-level check (stale önleme)
  • 🗄️ Database: 18 field (unified)
  • 🔐 SettingsManagement (tenant-aware)

📋 Settings Yaklaşımı

❌ Reddedilen: tenants.data JSON

  • • Duplicate çözüm
  • • SettingsManagement zaten var
  • • Tenant-aware değil

✅ Kabul: SettingsManagement

  • • Bu iş için tasarlanmış
  • • 3-layer system
  • • Tenant-aware otomatik
  • • Admin UI hazır

💡 3-Layer System

  • 1️⃣ settings_groups (CENTRAL DB) → Grup tanımı
  • 2️⃣ settings (CENTRAL DB) → Setting tanımı + default_value
  • 3️⃣ settings_values (TENANT DB) → Tenant'a özel değer

2️⃣ Settings (SADECE 2 AYAR - Minimal Yaklaşım)

1

auth_subscription

Ücretli Üyelik Sistemi (Ana Anahtar - Trial Dahil)

Setting ID

211

Type

select

Values

0 / 1

Muzibu Status

1 (AKTİF)

📋 Ne Yapar?

  • 1 (Açık): Subscription modülü aktif → Trial otomatik başlar, Premium kontrolleri çalışır, abonelik sistemi devrede
  • 0 (Kapalı): Subscription modülü tamamen kapalı → Herkes sınırsız kullanır (free model)

💡 Önemli Not:

Bu ayar 1 ise → Trial sistemi de otomatik aktif! Ayrı trial_enabled ayarı YOK!

2

auth_device_limit

Cihaz Limit Kontrolü (Global Fallback)

Setting ID

212

Type

number

Default

1

Önerilen

1-3 arası

📋 Ne Yapar?

  • 📱 Global Fallback: User ve Plan'da device_limit yoksa bu değer kullanılır (son çare)
  • 🔢 3-Layer Hierarşi: user.device_limitplan.device_limitauth_device_limit (setting)

💡 Detaylı Bilgi:

Detaylı hiyerarşi için Device Limit Hierarchy bölümüne bak

❌ Çıkarılan Ayarlar (v3'te 8 adet önerilmişti)

Minimal yaklaşım gereği sadece 2 ayar yeterli. Diğerleri gereksiz veya başka modüllerin sorumluluğunda:

  • subscription_trial_enabled → auth_subscription açıksa trial otomatik aktif
  • subscription_trial_auto_start → Zaten hardcode (daima otomatik)
  • subscription_payment_gateway → Payment modülü ilgilenir
  • subscription_payment_test_mode → Payment modülü ilgilenir
  • subscription_grace_period_days → Şimdilik gerek yok
  • subscription_preview_duration_seconds → 30 saniye hardcode

3️⃣ Hardcode Değerler (Settings'e GİRMEYEN)

🎵

30 Saniye Preview Duration

Abonelik yoksa veya biterse müzik 30 saniye çalışır (Guest & Expired kullanıcılar)

const PREVIEW_DURATION = 30; // saniye

✅ Neden Hardcode?

Bu değer değişmeyecek, ayar olarak yönetmeye gerek yok. Kullanıcı: "muzibu 30 saniye kuralı kalıcı değiştirmeye gerek yok. hardcode olsun"

⏱️

7 Gün Trial Duration

Trial süresi → Trial plan'ın billing_cycles JSON'ından alınır (DRY prensibi)

$trialPlan = SubscriptionPlan::where('is_trial', true)->first();
$days = $trialPlan->billing_cycles['7-gunluk']['duration_days'];

💡 DRY Prensibi (Don't Repeat Yourself):

Plan zaten bu bilgiyi tutuyor, ayrı bir setting ile duplicate etmeye gerek yok!

🚀

Trial Otomatik Başlatma

Kayıt sonrası otomatik trial subscription oluşturulur (Friction azalt → Conversion artır)

// Kullanıcı kayıt olduğunda (RegisterController)
if (setting('auth_subscription')) {
  SubscriptionService::createTrialForUser($user);
}

✅ ULTIMATE PLAN Kararı - Friction Azalt:

Kullanıcı seçim yapmasın, form doldurmasın, onay vermesin → Direkt trial ver! Böylece kullanıcı hemen premium deneyimi yaşar ve conversion artar.

4️⃣ Kullanıcı Durumları (4 Durum)

👤

GUEST (Misafir)

Kayıt olmamış, siteyi gezinen kullanıcı

Dinleme:

30 saniye

Özellikler:

Playlist ❌ | Favori ❌

CTA:

"Sınırsız dinlemek için üye ol!"

🆓

TRIAL (Deneme Üyesi)

Yeni kayıt olmuş, 7 günlük deneme süresi aktif

Dinleme:

Sınırsız (7 gün)

Özellikler:

Playlist ✅ | Favori ✅

CTA:

"X gün kaldı, Premium'a geç!"

👑

PREMIUM (Ücretli Üye)

Ödeme yapmış, aktif premium aboneliği var

Dinleme:

Sınırsız (Ömür boyu)

Özellikler:

TÜM Özellikler ✅

CTA:

"Premium üyesiniz, keyifle dinleyin!"

EXPIRED (Süresi Bitmiş)

Trial veya Premium süresi dolmuş, ödeme yapılmamış

Dinleme:

30 saniye

Özellikler:

Playlist ❌ | Favori ❌

CTA:

"Aboneliğiniz sona erdi! HEMEN YENİLE!"

📊 Hızlı Referans Tablosu

Durum Dinleme Süre Playlist CTA
👤 GUEST 30 saniye - Üye ol
🆓 TRIAL Sınırsız 7 gün Premium'a geç
👑 PREMIUM Sınırsız Ömür boyu Keyifle dinle
⏰ EXPIRED 30 saniye - HEMEN YENİLE!

🔄 Kullanıcı Akışı (Flow)

GUEST
Site geziniyor, 30 saniye dinliyor
GUEST
TRIAL
Kayıt ol → 7 gün trial (otomatik)
TRIAL
PREMIUM
Ödeme yap → Premium oldu
TRIAL
EXPIRED
7 gün bitti, ödeme yapılmadı
PREMIUM
EXPIRED
Ödeme kesildi/iptal edildi
EXPIRED
PREMIUM
Yeniden ödeme yap → Premium

5️⃣ Device Limit Hierarchy (3-Layer Fallback)

🎯 Nasıl Çalışır?

1️⃣ user.device_limit
En yüksek öncelik (VIP, Test, Ban kullanıcıları için override)
2️⃣ plan.device_limit
Plan'ın default değeri (Normal kullanıcılar için)
3️⃣ auth_device_limit
Global fallback (Son çare, setting)

💡 Mantık:

Üstten alta inerken ilk NULL OLMAYAN değer kullanılır. NULL ise bir sonraki katmana geç.

💻 Kod İmplementasyonu

public function getDeviceLimit(User $user): int
{
  // 1. User override (özel durumlar - VIP/Test/Ban)
  if ($user->device_limit !== null) {
    return $user->device_limit;
  }

  // 2. Plan default (normal akış - çoğu kullanıcı buradan)
  $sub = $user->activeSubscription();
  if ($sub && $sub->plan->device_limit) {
    return $sub->plan->device_limit;
  }

  // 3. Global fallback (son çare - setting)
  return setting('auth_device_limit', 1);
}

⚠️ Önemli:

users.device_limit field'i zaten database'de mevcut, yeni migration gerekmez!

📝 Örnek Senaryolar

✅ Normal Kullanıcı (En Yaygın)

user.device_limit: NULL

plan.device_limit: 3 ⬅️

auth_device_limit: 1 (ignored)

SONUÇ: 3 cihaz

👑 VIP Kullanıcı

user.device_limit: 5 ⬅️

plan.device_limit: 3 (ignored)

auth_device_limit: 1 (ignored)

SONUÇ: 5 cihaz

📱 Aboneliği Olmayan

user.device_limit: NULL

plan.device_limit: NULL

auth_device_limit: 1 ⬅️

SONUÇ: 1 cihaz

🚫 Problematic User (Ban)

user.device_limit: 1 (BAN) ⬅️

plan.device_limit: 5 (ignored)

auth_device_limit: 1 (ignored)

SONUÇ: 1 cihaz (kısıtlı)

🧪 Test Kullanıcı

user.device_limit: 999 (TEST) ⬅️

plan.device_limit: 3 (ignored)

auth_device_limit: 1 (ignored)

SONUÇ: 999 cihaz

💎 Corporate Kullanıcı

user.device_limit: NULL

plan.device_limit: 10 ⬅️

auth_device_limit: 1 (ignored)

SONUÇ: 10 cihaz

⚡ Hızlı Özet (Tüm Sistem Tek Bakışta)

📋 ULTIMATE Master Plan

  • ✅ Trial otomatik başlar
  • ✅ 7 gün (plan cycle'dan)
  • ✅ is_trial checkbox
  • ✅ has_used_trial kontrolü
  • ✅ 30 saniye preview
  • ✅ Request-level fresh check
  • ✅ Event system
  • ✅ SettingsManagement (3-layer)

⚙️ Settings (2 Adet)

  • 1️⃣ auth_subscription (0/1)
  •    → Ana anahtar (trial dahil)
  • 2️⃣ auth_device_limit (number)
  •    → Global fallback
  • ❌ 6 ayar çıkarıldı (gereksiz)

🔧 Hardcode (3 Adet)

  • 1️⃣ 30 saniye - Preview süresi
  • 2️⃣ 7 gün - Trial süresi (plan'dan)
  • 3️⃣ Otomatik - Trial başlatma
  • ✅ DRY prensibi + Basitlik

👥 Kullanıcı (4 Durum)

  • 👤 GUEST - 30 saniye
  • 🆓 TRIAL - 7 gün sınırsız
  • 👑 PREMIUM - Ömür boyu
  • EXPIRED - 30 saniye

📱 Device Hierarchy (3-Layer)

1️⃣ user.device_limit

Öncelikli (VIP/Test/Ban)

2️⃣ plan.device_limit

Normal akış (çoğu user)

3️⃣ auth_device_limit

Fallback (son çare)

🚀 6-Step Implementation Plan

1

Trial Planı Oluştur (Admin Panel)

is_trial=true, 7 günlük cycle, price=0

2

Subscription Service Güncelle

createTrialForUser(), getDeviceLimit(), checkAccess() metodları

3

Cache-Free Check Ekle (Stream Endpoint)

Her request'te fresh check, stale data yok

4

Event System Kur

SubscriptionExpired, TrialEnding events + listeners

5

Cron Job Kur

Günlük expire check, status update

6

Test & QA

4 durum test, device limit test, expire test