Kupon Sistemi v3 — Final Analiz Raporu

Kupon Sistemi — Analiz Raporu

3 kupon türü, dosya etki haritası, simülasyon örnekleri ve akış diyagramları

Yüzde Sabit Tutar Bedava Gün
1

Özet

📝

Basit Anlatım (Herkes İçin)

Kupon sistemi, kullanıcılara ödeme sırasında veya profil sayfasından indirim/avantaj sağlayan bir yapıdır. Admin panelinden kupon oluşturulur, kullanıcılara dağıtılır ve belirli koşullar altında geçerli olur.

Yüzde İndirim

Toplam tutarın belirli bir yüzdesi kadar indirim yapılır. Örneğin %20 indirim kuponu, 100 TL’lik alışverişte 20 TL düşer.

Sabit Tutar İndirim

Sabit bir miktar düşülür. Örneğin 50 TL indirim kuponu, fiyat ne olursa olsun 50 TL düşer (sıfırın altına inmez).

Bedava Gün

Abonelik süresine ek gün eklenir. Örneğin 30 günlük kupon, mevcut aboneliği 30 gün uzatır. Ödeme sayfasından değil, profil sayfasından kullanılır.

🔧

Teknik Detaylar (Geliştiriciler İçin)

Tür DB Değer Uygulama Noktası Hesaplama Koşul
Yüzde percentage Checkout sayfası tutar * (discount_value / 100) max_discount_amount kontrolü
Sabit Tutar fixed_amount Checkout sayfası tutar - discount_value Sıfırın altına inmez
Bedava Gün free_days Profil sayfası ends_at + free_days gün Aktif abonelik gerekli
2

Kupon Türleri Detay

Yüzde İndirim

discount_type = ‘percentage’
percentage

Basit Anlatım

  • Kullanıcı checkout sayfasında kupon kodunu girer
  • Toplam tutarın belirlenen yüzdesi kadar indirim yapılır
  • Isteğe bağlı “maksimum indirim tutarı” limiti konabilir
  • En yaygın kupon türü; kampanyalarda, promosyonlarda kullanılır

Teknik Detay

Tablo: coupons.discount_type = 'percentage'
Hesaplama: price * (discount_value / 100)
Güvenlik: max_discount_amount ile üst limit
Metot: Coupon::apply($price)

Simülasyon Örneği

Kupon: YAZ20 — %20 İndirim
Aylık Premium Abonelik 149,99 ₺
%20 İndirim (YAZ20) -30,00 ₺
Ödenecek Tutar 119,99 ₺

Sabit Tutar İndirim

discount_type = ‘fixed_amount’
fixed_amount

Basit Anlatım

  • Belirli bir TL miktarı doğrudan toplam tutardan düşer
  • Tutar kupon değerinden küçükse, ödenecek tutar 0 TL olur (eksi değil)
  • “50 TL indirim” gibi kampanyalarda kullanılır
  • Checkout sayfasından uygulanır, ödeme akışı içinde kalır

Teknik Detay

Tablo: coupons.discount_type = 'fixed_amount'
Hesaplama: max(0, price - discount_value)
Güvenlik: Negatif tutar engeli (max(0, ...))
Metot: Coupon::apply($price)

Simülasyon Örneği

Kupon: HOSGELDIN50 — 50 TL İndirim
Aylık Premium Abonelik 149,99 ₺
50 TL İndirim (HOSGELDIN50) -50,00 ₺
Ödenecek Tutar 99,99 ₺

Bedava Gün

discount_type = ‘free_days’
free_days

Basit Anlatım

  • Abonelik süresine bedava gün ekler (para indirimi değil)
  • Profil sayfasındaki “Kupon Kullan” alanından girilir
  • Checkout sayfasında görünmez — farklı bir akıştır
  • Kullanıcının aktif aboneliği olması gerekir
  • Sadakat ödülü, telafi, hediye olarak kullanılır

Teknik Detay

Tablo: coupons.discount_type = 'free_days'
Alan: coupons.free_days (integer, nullable)
Hesaplama: subscription.ends_at->addDays(free_days)
Metot: CouponService::applyFreeDays()
Uzatma: SubscriptionService::extendByDays()

Simülasyon Örneği

Kupon: SADAKAT30 — 30 Gün Hediye
Mevcut Abonelik Bitiş 15 Mart 2026
+30 Gün (SADAKAT30) +30 gün
Yeni Bitiş Tarihi 14 Nisan 2026
Para ödemesi yapılmaz — sadece abonelik süresi uzar
3

Dosya Etki Haritası

📝

Basit Anlatım

Kupon sistemi toplam 20+ dosyayı etkiler. Veritabanı değişikliği (migration), model, servis, admin formu, admin görünümü, checkout sayfası, profil sayfası, raporlama, routing ve dil dosyaları dahildir. Aşağıdaki tabloda her dosya, hangi modülde olduğu ve ne değiştiği yer alır.

# Dosya Modül Değişiklik
1 2026_02_28_000001_update_coupons_types_and_add_free_days.php
Modules/Coupon/database/migrations/ (central + tenant)
Migration discount_type enum güncellemesi (3 tür); free_days kolonu ekleme; eski türlerin kaldırılması
2 Coupon.php
Modules/Coupon/App/Models/
Model free_days fillable; apply() metodu; isFreeDaysCoupon(); getDiscountDisplay()
3 CouponManageComponent.php
Modules/Coupon/App/Http/Livewire/
Admin free_days property; validasyon kuralları; save() güncellemesi; discount_type seçenekleri 3’e indirildi
4 coupon-manage-component.blade.php
Modules/Coupon/resources/views/livewire/
Blade 3 adet radio buton (percentage, fixed_amount, free_days); free_days input alanı; koşullu görünürlük
5 CouponService.php
Modules/Coupon/App/Services/
Service applyFreeDays() metodu; abonelik uzatma lojigi; kupon kullanım kaydı
6 SubscriptionService.php
Modules/Subscription/App/Services/
Service extendByDays($subscription, $days) metodu; ends_at tarih uzatma
7 CheckoutPage.php
Modules/Subscription/App/Http/Livewire/
Checkout couponCode, appliedCoupon, couponDiscount property’leri; applyCoupon() / removeCoupon()
8 checkout-page.blade.php
Modules/Subscription/resources/views/livewire/
Blade Kupon kodu input alanı; “Uygula” / “Kaldır” butonları; indirim satırı gösterimi
9 RedeemCouponComponent.php
Modules/Coupon/App/Http/Livewire/
Profil Profil sayfasından free_days kuponu uygulama; kupon doğrulama; abonelik kontrolü
10 redeem-coupon-component.blade.php
Modules/Coupon/resources/views/livewire/
Blade Frontend kupon giriş UI; başarı/hata mesajları; abonelik uzatma bildirimi
11 CouponReportComponent.php
Modules/Coupon/App/Http/Livewire/
Rapor Genel kupon rapor sayfası; kullanım istatistikleri; tür bazlı gruplama
12 coupon-report-component.blade.php
Modules/Coupon/resources/views/livewire/
Blade Rapor tablo görünümü; filtreler; kupon türüne göre ikonlar
13 CouponReportDetailComponent.php
Modules/Coupon/App/Http/Livewire/
Rapor Tekil kupon detay raporu; kullanıcı listesi; kullanım geçmişi
14 coupon-report-detail-component.blade.php
Modules/Coupon/resources/views/livewire/
Blade Detay rapor görünümü; kullanıcı tablosu; tarih filtreleri
15 admin.php
Modules/Coupon/routes/
Route reports ve reports.detail route’ları eklendi
16 helper.blade.php
Modules/Coupon/resources/views/
Menü Admin menüsüne “Kupon Raporları” linki eklendi
17 CouponServiceProvider.php
Modules/Coupon/App/Providers/
Provider Yeni Livewire component kayıtları (RedeemCoupon, CouponReport, CouponReportDetail)
18 tr/admin.php
Modules/Coupon/resources/lang/
Lang Türkçe çeviriler: “Bedava Gün”, “Gün Sayısı”, rapor başlıkları
19 en/admin.php
Modules/Coupon/resources/lang/
Lang İngilizce çeviriler: “Free Days”, “Day Count”, report headings
20 profile/edit.blade.php
resources/views/themes/
Profil Profil düzenleme sayfasına @livewire('redeem-coupon') bileşeni eklendi
20
Toplam Dosya
3
Modül (Coupon, Subscription, Theme)
6
Livewire Component
1
Migration
4

Simülasyonlar

📝

Basit Anlatım

Aşağıdaki örnekler, her kupon türünün farklı senaryolarda nasıl çalıştığını gösterir. Gerçek kullanımda da tam olarak bu hesaplamalar yapılır.

Yüzde — Limitli

YILBASI40 — %40 (max 100 TL)
Yıllık Abonelik 599,99 ₺
%40 İndirim -240,00 ₺
Max limit devrede -100,00 ₺
Ödeme 499,99 ₺
max_discount_amount = 100 devrede → 240 TL yerine 100 TL indirim

Sabit Tutar — Aşım Koruması

VIP200 — 200 TL İndirim
Aylık Paket 149,99 ₺
Kupon Değeri -200,00 ₺
Sıfır koruması max(0, -50.01)
Ödeme 0,00 ₺
Kupon fiyattan büyük → max(0, ...) sayesinde negatif ödeme olmaz

Bedava Gün — Süre Uzatma

HEDIYE7 — 7 Gün Bedava
Mevcut Bitiş 28 Şubat 2026
+7 gün 7 gün
Yeni Bitiş 7 Mart 2026
Ödeme yok — abonelik ends_at alanı 7 gün ileri taşınır
5

Checkout Akışı (Yüzde & Sabit Tutar)

📝

Basit Anlatım

  1. 1 Kullanıcı abonelik planı seçer ve ödeme sayfasına gelir
  2. 2 “Kupon Kodunuz” alanına kodu yazar ve “Uygula” butonuna tıklar
  3. 3 Sistem kuponu kontrol eder (geçerli mi, süresi dolmuş mu, kullanım limiti aşılmış mı)
  4. 4 Geçerliyse indirim tutarı hesaplanır ve ekranda gösterilir
  5. 5 Kullanıcı indirimlı tutar üzerinden ödeme yapar
  6. 6 Ödeme başarılıysa kupon “kullanıldı” olarak işaretlenir
🔧

Teknik Akış

Kullanıcı kupon kodunu girer
CheckoutPage::$couponCode ← wire:model
“Uygula” butonuna tıklar
wire:click="applyCoupon"
Kupon doğrulanır
Coupon::where('code', $code)->first() → status, date, limit kontrolü
free_days ise reddedilir
if ($coupon->isFreeDaysCoupon()) → error (checkout'ta kullanılamaz)
İndirim hesaplanır
$coupon->apply($price)$couponDiscount
UI güncellenir
$appliedCoupon, $couponDiscount Livewire ile render
Ödeme tamamlanır
coupon_usages tablosuna kayıt; used_count++

Checkout Sayfası — Kupon Entegrasyonu

Kupon Kodunuz
YAZ20
Plan Tutarı 149,99 ₺
Kupon İndirimi (YAZ20) -30,00 ₺
Toplam 119,99 ₺
6

Bedava Gün (free_days) Akışı

📝

Basit Anlatım

Bedava gün kuponu, ödeme sayfasından farklı çalışır. Kullanıcı profil sayfasındaki “Kupon Kullan” alanına kodunu girer. Para ödemesi yoktur; mevcut abonelik süresi belirtilen gün kadar uzatılır.

  1. 1 Kullanıcı profiline gider ve “Kupon Kullan” bölümünü bulur
  2. 2 Kupon kodunu girer ve “Kullan” butonuna tıklar
  3. 3 Sistem kontrol eder: kupon geçerli mi + kullanıcının aktif aboneliği var mı
  4. 4 Her şey uygunsa abonelik bitiş tarihi X gün ileri taşınır
  5. 5 Başarı mesajı: “Aboneliğiniz X gün uzatıldı!”
🔧

Teknik Akış

Profil sayfası açılır
@livewire('redeem-coupon') — profile/edit.blade.php
Kupon kodu girilir
RedeemCouponComponent::$couponCode ← wire:model
Kupon doğrulanır
Coupon::where('code', $code)->isFreeDaysCoupon() kontrolü
Aktif abonelik kontrolü
$user->activeSubscription() → yoksa hata mesajı
CouponService::applyFreeDays()
Kuponu kullanıcıya uygula, kullanım kaydı oluştur
SubscriptionService::extendByDays()
$subscription->ends_at->addDays($coupon->free_days)
Başarı bildirimi
Flash message: “Aboneliğiniz {X} gün uzatıldı!”

Checkout vs Profil — Kupon Uygulama Farkı

Özellik Checkout (Yüzde / Sabit) Profil (Bedava Gün)
Uygulama Yeri Ödeme sayfası Profil sayfası
Para İndirimi Evet — fiyattan düşülür Hayır — para işlemi yok
Süre Uzatma Hayır Evet — ends_at uzatılır
Abonelik Gerekli mi? Hayır (yeni alım için) Evet — aktif abonelik şart
Livewire Component CheckoutPage RedeemCouponComponent
Kullanım Amacı Kampanya, promosyon, indirim Sadakat ödülü, telafi, hediye

Profil Sayfası — Kupon Kullan Bileşeni

Kupon Kullan
Kupon Kodunuz
SADAKAT30
Aboneliğiniz 30 gün uzatıldı! Yeni bitiş: 14 Nisan 2026
28 Şubat 2026 • Muzibu.com.tr v3