nodebb-plugin-pdf-secure 1.2.27 → 1.2.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/library.js +2 -1
- package/package.json +1 -1
- package/static/viewer-app.js +14 -6
- package/static/viewer.html +92 -12
- package/PRD (2).md +0 -844
- package/PRD.md +0 -776
package/PRD (2).md
DELETED
|
@@ -1,844 +0,0 @@
|
|
|
1
|
-
# PRD: IEU Forum Çok Katmanlı Premium Abonelik Sistemi
|
|
2
|
-
|
|
3
|
-
## 1. Bağlam (Context)
|
|
4
|
-
|
|
5
|
-
### Amaç
|
|
6
|
-
|
|
7
|
-
Sistemi 3 kademeli abonelik planına (Lite, Premium, VIP), aylık + yıllık ödeme seçeneklerine, plan yükseltme mekanizmasına, ve gelişmiş admin paneline dönüştürmek.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## 2. Abonelik Planları
|
|
12
|
-
|
|
13
|
-
### 2.1 Plan Tanımları
|
|
14
|
-
|
|
15
|
-
| Plan | Aylık | Yıllık (8 ay bedava) | NodeBB Grubu | Seviye |
|
|
16
|
-
| ------------------------ | ----- | -------------------- | ------------ | ------ |
|
|
17
|
-
| **Lite** | 119₺ | 476₺ | `lite` | 1 |
|
|
18
|
-
| **Premium** (En Popüler) | 139₺ | 556₺ | `premium` | 2 |
|
|
19
|
-
| **VIP** (Elit) | 159₺ | 636₺ | `vip` | 3 |
|
|
20
|
-
|
|
21
|
-
### 2.2 Plan Özellikleri
|
|
22
|
-
|
|
23
|
-
**Lite (Seviye 1)**
|
|
24
|
-
|
|
25
|
-
- Tüm çalışma sorularına sınırsız erişim
|
|
26
|
-
- En güncel ders notları arşivi
|
|
27
|
-
|
|
28
|
-
**Premium (Seviye 2) — Lite + ekstralar**
|
|
29
|
-
|
|
30
|
-
- Gelişmiş PDF önizleme ve araçları
|
|
31
|
-
- Akıllı CV Oluşturucu
|
|
32
|
-
- Hedef odaklı GPA Hesaplayıcı
|
|
33
|
-
- Sıfır Reklam (reklamsız arayüz)
|
|
34
|
-
- Niki Wallet: %30 indirimli kahve hediye
|
|
35
|
-
- Sosyal Analitik: Profil ve konu görüntüleyenleri görme
|
|
36
|
-
|
|
37
|
-
**VIP (Seviye 3) — Premium + ekstralar**
|
|
38
|
-
|
|
39
|
-
- Prestij: Profilde özel VIP Badge
|
|
40
|
-
- Öncülük: Yeni özelliklere erken erişim
|
|
41
|
-
|
|
42
|
-
### 2.3 Ödeme Periyotları
|
|
43
|
-
|
|
44
|
-
- **Aylık**: Standart fiyat, 30 günlük süre
|
|
45
|
-
- **Yıllık**: 8 ay bedava (4 aylık ödemeyle 12 ay kullanım), 365 günlük süre
|
|
46
|
-
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
## 3. İş Kuralları
|
|
50
|
-
|
|
51
|
-
### 3.1 Plan Yükseltme (Upgrade)
|
|
52
|
-
|
|
53
|
-
- Kullanıcı sadece **üst plana** geçebilir (Lite → Premium, Lite → VIP, Premium → VIP)
|
|
54
|
-
- **Prorated fark ücreti**: Kalan günlerin fiyat farkı hesaplanır
|
|
55
|
-
- Formül: `fark = (yeniPlanFiyat - eskiPlanFiyat) / toplamGün * kalanGün`
|
|
56
|
-
- Örnek: Lite'tan Premium'a, 15 gün kala: `(139-119)/30*15 = 10₺`
|
|
57
|
-
- Yükseltme sonrası bitiş tarihi değişmez, sadece plan seviyesi ve grup değişir
|
|
58
|
-
- Yıllık abonelikte de aynı prorated mantık geçerli
|
|
59
|
-
|
|
60
|
-
### 3.2 Downgrade
|
|
61
|
-
|
|
62
|
-
- **Desteklenmiyor**. Kullanıcı alt plana geçemez
|
|
63
|
-
- Alt plan isteyen kullanıcı mevcut aboneliği iptal edip süre bittikten sonra yeni plan satın almalı
|
|
64
|
-
|
|
65
|
-
### 3.3 Abonelik Süresi Dolduğunda
|
|
66
|
-
|
|
67
|
-
- Mevcut cron job (10dk) kontrol eder
|
|
68
|
-
- Kullanıcı ilgili NodeBB grubundan çıkarılır
|
|
69
|
-
- Subscription status "expired" olarak işaretlenir
|
|
70
|
-
|
|
71
|
-
### 3.4 Yenileme
|
|
72
|
-
|
|
73
|
-
- **Otomatik yenileme varsayılan olarak açık** gelir (checkbox tikli)
|
|
74
|
-
- Kullanıcı istemezse satın alma sırasında tiki kaldırarak kapatabilir
|
|
75
|
-
- Otomatik yenileme tercihi subscription kaydında `autoRenew: true/false` olarak saklanır
|
|
76
|
-
- Abonelik süresi dolmadan önce (ör. 1 gün kala) cron job otomatik yenileme yapılacak abonelikleri tespit eder
|
|
77
|
-
- Otomatik yenileme açık olan kullanıcılar için aynı plan + period ile yeni ödeme talebi oluşturulur (PayTR tekrarlayan ödeme veya kayıtlı kart ile)
|
|
78
|
-
- Otomatik yenileme kapalıysa: kullanıcı manuel olarak tekrar ödeme yaparak süre uzatır
|
|
79
|
-
- Aynı plan ile uzatma: mevcut bitiş tarihine süre eklenir
|
|
80
|
-
|
|
81
|
-
### 3.5 Kullanıcı Abonelik İptali — IP Kısıtlamalı Endpoint
|
|
82
|
-
|
|
83
|
-
NodeBB tarafında **herhangi bir plugin yazılmaz** ve geçici grup mekanizması kullanılmaz. Bunun yerine ödeme servisinde **sadece NodeBB sunucusunun IP adresinden gelen istekleri kabul eden** bir endpoint bulunur. NodeBB tarafında navigasyon menüsüne eklenen bir link ile kullanıcı bu endpoint'e yönlendirilir.
|
|
84
|
-
|
|
85
|
-
#### Mekanizma
|
|
86
|
-
|
|
87
|
-
- Ödeme servisinde `POST /pay/api/cancel-subscription` endpoint'i oluşturulur
|
|
88
|
-
- Bu endpoint **sadece** izin verilen IP adresinden gelen istekleri kabul eder (NodeBB sunucusunun IP'si)
|
|
89
|
-
- İzin verilen IP adresi admin panelden **Ayarlar** sayfasından değiştirilebilir (veritabanında `Setting` modelinde saklanır)
|
|
90
|
-
- Varsayılan değer `ALLOWED_CANCEL_IP` environment değişkeninden okunur; admin panelden güncelleme yapıldığında veritabanındaki değer önceliklidir
|
|
91
|
-
- NodeBB tarafında navigasyon menüsüne "Aboneliği İptal Et" linki eklenir; bu link kullanıcıyı ödeme servisindeki iptal sayfasına yönlendirir
|
|
92
|
-
- Kullanıcı iptal sayfasında onay vererek aboneliğinin otomatik yenilenmesini kapatır
|
|
93
|
-
|
|
94
|
-
#### İptal Akışı
|
|
95
|
-
|
|
96
|
-
```
|
|
97
|
-
1. Kullanıcı NodeBB'de navigasyon menüsünden "Aboneliği İptal Et" linkine tıklar
|
|
98
|
-
→ /pay/cancel?uid={uid} sayfası açılır (ödeme servisi)
|
|
99
|
-
2. Sayfa, kullanıcının aktif abonelik bilgilerini gösterir
|
|
100
|
-
3. Kullanıcı "Otomatik Yenilemeyi İptal Et" butonuna tıklar
|
|
101
|
-
4. Frontend, POST /pay/api/cancel-subscription isteği gönderir (uid parametresiyle)
|
|
102
|
-
5. Endpoint IP kontrolü yapar:
|
|
103
|
-
- İstek NodeBB sunucu IP'sinden gelmiyorsa → 403 Forbidden
|
|
104
|
-
- İstek doğru IP'den geliyorsa → devam et
|
|
105
|
-
6. Aktif abonelik bulunur:
|
|
106
|
-
- autoRenew = false olarak güncellenir
|
|
107
|
-
- cancelRequestedAt = now kaydedilir
|
|
108
|
-
7. Kullanıcıya onay sayfası gösterilir:
|
|
109
|
-
"Otomatik yenileme iptal edildi. Aboneliğiniz {bitiş tarihi} tarihine kadar aktif kalacaktır."
|
|
110
|
-
8. Abonelik mevcut dönem sonuna kadar aktif kalır
|
|
111
|
-
9. Dönem dolduğunda mevcut cron job (10 dk) normal şekilde plan grubundan çıkarır ve expired işaretler
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
#### Neden Bu Yaklaşım Güvenli?
|
|
115
|
-
|
|
116
|
-
- Endpoint **sadece** NodeBB sunucusunun IP adresinden gelen istekleri kabul eder
|
|
117
|
-
- Kullanıcı NodeBB'ye giriş yapmadan bu sayfaya erişemez (NodeBB'nin kendi auth sistemi link'i gösterir)
|
|
118
|
-
- Dış dünyadan (farklı IP'lerden) gelen istekler reddedilir
|
|
119
|
-
- Cron job veya geçici grup mekanizmasına gerek yoktur — istek anında işlenir
|
|
120
|
-
- Cross-service auth, HMAC, OTP gibi ek mekanizmalara ihtiyaç yok
|
|
121
|
-
|
|
122
|
-
#### Kullanıcıya Bilgilendirme
|
|
123
|
-
|
|
124
|
-
- İptal sayfasında şu bilgiler gösterilir:
|
|
125
|
-
> "Otomatik yenilemeyi iptal ettiğinizde mevcut abonelik süreniz sonuna kadar erişiminiz devam edecektir. Süre sonunda aboneliğiniz yenilenmeyecektir."
|
|
126
|
-
- İptal işlendikten sonra onay mesajı:
|
|
127
|
-
> "Otomatik yenileme iptal edildi. Aboneliğiniz {bitiş tarihi} tarihine kadar aktif kalacaktır."
|
|
128
|
-
|
|
129
|
-
#### Kullanıcı Fikir Değiştirirse
|
|
130
|
-
|
|
131
|
-
- İptal sadece otomatik yenilemeyi kapatır, mevcut dönem erişimi devam eder
|
|
132
|
-
- Kullanıcı forumdan yeniden `/pay/checkout?uid={uid}` üzerinden aynı planı satın alarak devam edebilir
|
|
133
|
-
- Veya admin panelden otomatik yenileme tekrar açılabilir
|
|
134
|
-
|
|
135
|
-
### 3.6 NodeBB Grup Yönetimi
|
|
136
|
-
|
|
137
|
-
- Her plan için ayrı NodeBB grubu: `lite`, `premium`, `vip`
|
|
138
|
-
- Kullanıcı **sadece** aktif planının grubunda olur
|
|
139
|
-
- Plan yükseltmede: eski gruptan çıkar, yeni gruba ekle
|
|
140
|
-
- Süre dolduğunda: gruptan çıkar
|
|
141
|
-
|
|
142
|
-
### 3.7 Admin Paneli — Tam Yetki
|
|
143
|
-
|
|
144
|
-
Admin paneli NodeBB foruma bağlıdır ve admin aşağıdaki tüm işlemleri yapabilir:
|
|
145
|
-
|
|
146
|
-
#### Kullanıcı Doğrulama
|
|
147
|
-
|
|
148
|
-
- Admin, UID veya kullanıcı adı girerek işlem yapar
|
|
149
|
-
- Girilen bilgi NodeBB API üzerinden doğrulanır; kullanıcı bulunamazsa hata gösterilir
|
|
150
|
-
- Doğrulanan kullanıcının profil bilgileri (avatar, username, email, kayıt tarihi) gösterilir
|
|
151
|
-
|
|
152
|
-
#### Manuel Plan Atama
|
|
153
|
-
|
|
154
|
-
- Admin herhangi bir kullanıcıya herhangi bir plan (Lite / Premium / VIP) atayabilir
|
|
155
|
-
- Manuel atama PayTR ödemesi gerektirmez
|
|
156
|
-
- Süre admin tarafından belirlenir (1 ay / 3 ay / 6 ay / 12 ay / özel tarih, varsayılan: 30 gün)
|
|
157
|
-
- Period admin tarafından seçilir (aylık / yıllık)
|
|
158
|
-
- Atama sonrası NodeBB'de ilgili gruba eklenir (eski grup varsa çıkarılır)
|
|
159
|
-
- Subscription kaydı `source: "admin"` ve `adminAssignedBy` ile oluşturulur
|
|
160
|
-
|
|
161
|
-
#### Manuel Plan Değiştirme (Upgrade & Downgrade)
|
|
162
|
-
|
|
163
|
-
- Admin, kullanıcının mevcut planını **herhangi bir plana** değiştirebilir (hem yükseltme hem düşürme)
|
|
164
|
-
- Downgrade dahil — normal kullanıcılar yapamaz ama admin yapabilir
|
|
165
|
-
- Plan değiştirildiğinde: eski NodeBB grubundan çıkarılır, yeni gruba eklenir
|
|
166
|
-
- Bitiş tarihi korunur (admin isterse bitiş tarihini de değiştirebilir)
|
|
167
|
-
- `previousPlan` kaydedilir, `source: "admin"` olarak işaretlenir
|
|
168
|
-
|
|
169
|
-
#### Abonelik İptali
|
|
170
|
-
|
|
171
|
-
- Admin, aktif bir aboneliği anında iptal edebilir
|
|
172
|
-
- İptal sonrası: kullanıcı NodeBB grubundan çıkarılır, status "cancelled" olarak işaretlenir
|
|
173
|
-
- İptal nedeni opsiyonel olarak kaydedilebilir (`cancelReason`)
|
|
174
|
-
|
|
175
|
-
#### Süre Düzenleme
|
|
176
|
-
|
|
177
|
-
- Admin, mevcut aboneliğin bitiş tarihini ileri veya geri alabilir
|
|
178
|
-
- Süre uzatma veya kısaltma serbesttir
|
|
179
|
-
|
|
180
|
-
#### Kullanıcı Detay Sayfası
|
|
181
|
-
|
|
182
|
-
- Tek kullanıcıya ait tüm abonelik geçmişi (aktif + geçmiş) listelenir
|
|
183
|
-
- Mevcut plan, period, başlangıç/bitiş tarihi, kaynak (ödeme/admin/upgrade), otomatik yenileme durumu
|
|
184
|
-
- Üzerinden doğrudan plan değiştirme, iptal, süre düzenleme işlemleri yapılabilir
|
|
185
|
-
- NodeBB'deki grup üyeliği durumu gösterilir
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
## 4. Teknik Tasarım
|
|
190
|
-
|
|
191
|
-
### 4.1 Veritabanı Modeli Değişiklikleri
|
|
192
|
-
|
|
193
|
-
**Subscription Model** (`src/models/subscription.model.js`) — güncellenecek alanlar:
|
|
194
|
-
|
|
195
|
-
```javascript
|
|
196
|
-
{
|
|
197
|
-
// Mevcut alanlar (korunacak)
|
|
198
|
-
uid, username, status, startedAt, expiresAt, premiumRevokedAt,
|
|
199
|
-
billingInfo, paytrMerchantOid, paytrRaw,
|
|
200
|
-
|
|
201
|
-
// YENİ ALANLAR
|
|
202
|
-
plan: {
|
|
203
|
-
type: String,
|
|
204
|
-
enum: ["lite", "premium", "vip"],
|
|
205
|
-
required: true,
|
|
206
|
-
index: true
|
|
207
|
-
},
|
|
208
|
-
period: {
|
|
209
|
-
type: String,
|
|
210
|
-
enum: ["monthly", "yearly"],
|
|
211
|
-
default: "monthly"
|
|
212
|
-
},
|
|
213
|
-
amount: {
|
|
214
|
-
type: Number, // kuruş cinsinden ödenen tutar
|
|
215
|
-
required: true
|
|
216
|
-
},
|
|
217
|
-
source: {
|
|
218
|
-
type: String,
|
|
219
|
-
enum: ["payment", "admin", "upgrade"],
|
|
220
|
-
default: "payment"
|
|
221
|
-
},
|
|
222
|
-
previousPlan: {
|
|
223
|
-
type: String,
|
|
224
|
-
enum: ["lite", "premium", "vip", null],
|
|
225
|
-
default: null
|
|
226
|
-
},
|
|
227
|
-
autoRenew: {
|
|
228
|
-
type: Boolean,
|
|
229
|
-
default: true // varsayılan olarak açık
|
|
230
|
-
},
|
|
231
|
-
adminAssignedBy: {
|
|
232
|
-
type: String, // admin username (null if not admin-assigned)
|
|
233
|
-
default: null
|
|
234
|
-
},
|
|
235
|
-
cancelReason: {
|
|
236
|
-
type: String, // admin tarafından iptal edildiğinde sebep (opsiyonel)
|
|
237
|
-
default: null
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
**Yeni Model: Setting** (`src/models/setting.model.js`) — admin panelden yönetilebilen ayarlar:
|
|
243
|
-
|
|
244
|
-
```javascript
|
|
245
|
-
{
|
|
246
|
-
key: {
|
|
247
|
-
type: String,
|
|
248
|
-
required: true,
|
|
249
|
-
unique: true,
|
|
250
|
-
index: true
|
|
251
|
-
},
|
|
252
|
-
value: {
|
|
253
|
-
type: String,
|
|
254
|
-
required: true
|
|
255
|
-
},
|
|
256
|
-
updatedBy: {
|
|
257
|
-
type: String, // admin username
|
|
258
|
-
default: null
|
|
259
|
-
},
|
|
260
|
-
updatedAt: {
|
|
261
|
-
type: Date,
|
|
262
|
-
default: Date.now
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
Önceden tanımlı ayar anahtarları:
|
|
268
|
-
- `allowedCancelIp` — Abonelik iptali endpoint'inin kabul ettiği IP adresi. Boş veya kayıt yoksa `ALLOWED_CANCEL_IP` env değişkenine fallback yapılır.
|
|
269
|
-
|
|
270
|
-
**Yeni Model: Plan Config** (`src/models/plan.model.js`) — plan tanımları için (opsiyonel, config dosyasında da tutulabilir):
|
|
271
|
-
|
|
272
|
-
Plan tanımları `src/config/plans.js` config dosyasında tutulacak (veritabanında değil):
|
|
273
|
-
|
|
274
|
-
```javascript
|
|
275
|
-
const PLANS = {
|
|
276
|
-
lite: {
|
|
277
|
-
name: "Lite",
|
|
278
|
-
slug: "lite",
|
|
279
|
-
level: 1,
|
|
280
|
-
monthlyPrice: 11900, // kuruş
|
|
281
|
-
yearlyPrice: 47600, // kuruş (8 ay bedava)
|
|
282
|
-
nodebbGroup: "lite",
|
|
283
|
-
features: ["Tüm çalışma sorularına sınırsız erişim", "En güncel ders notları arşivi"],
|
|
284
|
-
},
|
|
285
|
-
premium: {
|
|
286
|
-
name: "Premium",
|
|
287
|
-
slug: "premium",
|
|
288
|
-
level: 2,
|
|
289
|
-
monthlyPrice: 13900,
|
|
290
|
-
yearlyPrice: 55600,
|
|
291
|
-
nodebbGroup: "premium",
|
|
292
|
-
badge: "En Popüler",
|
|
293
|
-
features: ["Lite planındaki her şey", "Gelişmiş PDF önizleme ve araçları", "Akıllı CV Oluşturucu", "Hedef odaklı GPA Hesaplayıcı", "Sıfır Reklam", "Niki Wallet: %30 indirimli kahve hediye", "Sosyal Analitik"],
|
|
294
|
-
},
|
|
295
|
-
vip: {
|
|
296
|
-
name: "VIP",
|
|
297
|
-
slug: "vip",
|
|
298
|
-
level: 3,
|
|
299
|
-
monthlyPrice: 15900,
|
|
300
|
-
yearlyPrice: 63600,
|
|
301
|
-
nodebbGroup: "vip",
|
|
302
|
-
badge: "Elit Deneyim",
|
|
303
|
-
features: ["Premium'daki her şey", "Prestij: Profilde özel VIP Badge", "Öncülük: Yeni özelliklere erken erişim"],
|
|
304
|
-
},
|
|
305
|
-
};
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
### 4.2 Değiştirilecek Dosyalar
|
|
309
|
-
|
|
310
|
-
| Dosya | Değişiklik |
|
|
311
|
-
| --------------------------------------- | ------------------------------------------------------------------------------- |
|
|
312
|
-
| `src/models/subscription.model.js` | plan, period, amount, source, previousPlan, adminAssignedBy alanları eklenir |
|
|
313
|
-
| `src/config/plans.js` | **YENİ** — Plan tanımları ve fiyatlandırma |
|
|
314
|
-
| `src/config/env.js` | Yeni NodeBB grup env değişkenleri (veya plans.js'den okunur) |
|
|
315
|
-
| `src/services/paytr.service.js` | Dinamik fiyat ve ürün adı desteği (plan + period parametreleri) |
|
|
316
|
-
| `src/services/nodebb.service.js` | Çoklu grup desteği: addToGroup(uid, groupName), removeFromGroup(uid, groupName) |
|
|
317
|
-
| `src/services/subscription.service.js` | createOrExtend → plan-aware, upgrade hesaplaması, admin atama |
|
|
318
|
-
| `src/services/admin.service.js` | Plan bazlı istatistikler, manuel atama servisi, gelir hesabı güncelleme |
|
|
319
|
-
| `src/controllers/payment.controller.js` | Plan seçimi ve period akışı, upgrade flow |
|
|
320
|
-
| `src/controllers/admin.controller.js` | Manuel plan atama endpoint'i, gelişmiş dashboard |
|
|
321
|
-
| `src/routes/payment.routes.js` | Yeni route'lar (plan seçim, upgrade) |
|
|
322
|
-
| `src/routes/admin.routes.js` | Manuel atama route'ları |
|
|
323
|
-
| `src/jobs/subscriptionWatcher.job.js` | Plan-aware grup çıkarma |
|
|
324
|
-
| `src/views/home.ejs` | 3 kart plan seçim UI, aylık/yıllık toggle |
|
|
325
|
-
| `src/views/billing-form.ejs` | Plan ve period bilgisi taşıma |
|
|
326
|
-
| `src/views/payment.ejs` | Seçilen plan bilgisi gösterme |
|
|
327
|
-
| `src/views/result.ejs` | Plan adı gösterme |
|
|
328
|
-
| `src/models/setting.model.js` | **YENİ** — Ayarlar modeli (key-value, admin panelden yönetilen yapılandırmalar) |
|
|
329
|
-
| `src/middleware/ipRestrict.js` | **YENİ** — IP kısıtlama middleware'i (DB'den veya env'den IP okur) |
|
|
330
|
-
| `src/views/cancel.ejs` | **YENİ** — Kullanıcı iptal sayfası (abonelik bilgileri + iptal butonu) |
|
|
331
|
-
| `src/views/admin/dashboard.ejs` | Plan bazlı istatistikler, gelişmiş grafikler |
|
|
332
|
-
| `src/views/admin/subscribers.ejs` | Plan filtresi, manuel atama butonu |
|
|
333
|
-
| `src/views/admin/assign.ejs` | **YENİ** — Admin kullanıcı arama + manuel plan atama formu |
|
|
334
|
-
| `src/views/admin/subscriber-detail.ejs` | **YENİ** — Tek kullanıcı detay sayfası (plan değiştir, iptal, süre düzenle) |
|
|
335
|
-
| `src/views/admin/settings.ejs` | **YENİ** — Ayarlar sayfası (IP adresi vb. yapılandırmalar) |
|
|
336
|
-
| `.env.example` | Yeni env değişkenleri |
|
|
337
|
-
|
|
338
|
-
### 4.3 API Endpoint'leri
|
|
339
|
-
|
|
340
|
-
#### Mevcut Route'lar (Güncelleme)
|
|
341
|
-
|
|
342
|
-
- `GET /pay/checkout?uid={uid}` → Plan seçim sayfası (3 kart + aylık/yıllık toggle)
|
|
343
|
-
- `GET /pay/checkout/billing?uid={uid}&plan={slug}&period={monthly|yearly}` → Fatura formu
|
|
344
|
-
- `POST /pay/checkout/billing` → Form işleme (plan + period eklenir)
|
|
345
|
-
- `GET /pay/checkout/start?uid={uid}&plan={slug}&period={monthly|yearly}&...` → PayTR başlat
|
|
346
|
-
- `POST /pay/checkout/callback` → PayTR callback (plan bilgisi merchantOid'den parse)
|
|
347
|
-
- `GET /pay/checkout/result` → Sonuç sayfası
|
|
348
|
-
|
|
349
|
-
#### Yeni Route'lar
|
|
350
|
-
|
|
351
|
-
- `GET /pay/checkout/upgrade?uid={uid}&plan={slug}` → Upgrade sayfası (fark ücreti göster)
|
|
352
|
-
- `POST /pay/checkout/upgrade` → Upgrade işlemi başlat → PayTR'ye yönlendir
|
|
353
|
-
- `GET /pay/cancel?uid={uid}` → İptal sayfası (abonelik bilgileri + iptal butonu)
|
|
354
|
-
- `POST /pay/api/cancel-subscription` → IP kısıtlamalı iptal endpoint'i (sadece NodeBB sunucu IP'sinden)
|
|
355
|
-
|
|
356
|
-
#### Admin Route'ları (Güncelleme + Yeni)
|
|
357
|
-
|
|
358
|
-
- `GET /pay/admin` → Gelişmiş dashboard (plan bazlı breakdown)
|
|
359
|
-
- `GET /pay/admin/subscribers` → Plan filtresiyle liste
|
|
360
|
-
- `GET /pay/admin/subscriber/:uid` → **YENİ** Tek kullanıcı detay sayfası (abonelik geçmişi + işlemler)
|
|
361
|
-
- `GET /pay/admin/assign` → **YENİ** Manuel plan atama formu (UID/username ile kullanıcı arama)
|
|
362
|
-
- `POST /pay/admin/assign` → **YENİ** Manuel plan atama işlemi
|
|
363
|
-
- `POST /pay/admin/change-plan` → **YENİ** Plan değiştirme (upgrade/downgrade)
|
|
364
|
-
- `POST /pay/admin/cancel` → **YENİ** Abonelik iptal etme
|
|
365
|
-
- `POST /pay/admin/extend` → **YENİ** Süre düzenleme (uzatma/kısaltma)
|
|
366
|
-
- `GET /pay/admin/lookup?q={uid|username}` → **YENİ** NodeBB kullanıcı arama (AJAX)
|
|
367
|
-
- `GET /pay/admin/settings` → **YENİ** Ayarlar sayfası (IP adresi vb. yapılandırmalar)
|
|
368
|
-
- `POST /pay/admin/settings` → **YENİ** Ayarları kaydet
|
|
369
|
-
|
|
370
|
-
### 4.4 Ödeme Akışı (Güncel)
|
|
371
|
-
|
|
372
|
-
```
|
|
373
|
-
1. Kullanıcı → /pay/checkout?uid=123
|
|
374
|
-
2. Plan seçim sayfası gösterilir (3 kart + aylık/yıllık toggle)
|
|
375
|
-
- Aktif aboneliği varsa: mevcut plan gösterilir + sadece üst planlar seçilebilir (upgrade)
|
|
376
|
-
- Aktif aboneliği yoksa: tüm planlar seçilebilir
|
|
377
|
-
3. Kullanıcı plan + period seçer → "Satın Al" butonuna tıklar
|
|
378
|
-
4. Billing form → Plan ve period bilgisi hidden field'larda taşınır
|
|
379
|
-
5. PayTR'ye gönderilir:
|
|
380
|
-
- merchantOid formatı: {uid}x{planSlug}x{period}x{timestamp}
|
|
381
|
-
- Tutar: plans.js'den ilgili fiyat
|
|
382
|
-
- Basket: Plan adı + period
|
|
383
|
-
6. PayTR callback gelir → merchantOid parse edilir → plan + period çıkarılır
|
|
384
|
-
7. NodeBB'de ilgili gruba eklenir (eski grup varsa önce çıkarılır)
|
|
385
|
-
8. Subscription kaydı oluşturulur (plan, period, amount bilgileriyle)
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
### 4.5 Upgrade Akışı
|
|
389
|
-
|
|
390
|
-
```
|
|
391
|
-
1. Kullanıcı → /pay/checkout?uid=123 (aktif aboneliği var)
|
|
392
|
-
2. Mevcut planı gösterilir, üst planların "Yükselt" butonu aktif
|
|
393
|
-
3. "Yükselt" → /pay/checkout/upgrade?uid=123&plan=premium
|
|
394
|
-
4. Prorated fark ücreti hesaplanıp gösterilir:
|
|
395
|
-
- kalanGün = (expiresAt - now) / (1000*60*60*24)
|
|
396
|
-
- eskiGünlükFiyat = eskiPlan.fiyat / toplamGün
|
|
397
|
-
- yeniGünlükFiyat = yeniPlan.fiyat / toplamGün
|
|
398
|
-
- fark = (yeniGünlükFiyat - eskiGünlükFiyat) * kalanGün
|
|
399
|
-
- Minimum fark: 1₺ (100 kuruş)
|
|
400
|
-
5. Kullanıcı onaylar → Billing form → PayTR (fark ücreti kadar)
|
|
401
|
-
6. Callback → Eski gruptan çıkar, yeni gruba ekle
|
|
402
|
-
7. Subscription güncelle: plan değişir, expiresAt aynı kalır, previousPlan kaydedilir
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
### 4.6 Admin Paneli Güncellemeleri
|
|
406
|
-
|
|
407
|
-
#### Dashboard İstatistikleri
|
|
408
|
-
|
|
409
|
-
- **Toplam Gelir**: Plan ve period bazlı breakdown
|
|
410
|
-
- **Aktif Aboneler**: Plan bazlı dağılım (pasta grafik veya bar)
|
|
411
|
-
- **Plan Dağılımı**: Lite vs Premium vs VIP oranları
|
|
412
|
-
- **Aylık vs Yıllık**: Period dağılımı
|
|
413
|
-
- **Bu Ay Gelir**: Plan bazlı
|
|
414
|
-
- **Son Abonelikler**: Plan bilgisiyle birlikte
|
|
415
|
-
- **Aylık Gelir Grafiği**: Plan bazlı stacked bar chart
|
|
416
|
-
|
|
417
|
-
#### Kullanıcı Arama & Atama Sayfası (`assign.ejs`)
|
|
418
|
-
|
|
419
|
-
- UID veya kullanıcı adı giriş alanı
|
|
420
|
-
- "Ara" butonuna basıldığında NodeBB API'den kullanıcı doğrulanır (AJAX ile `/pay/admin/lookup`)
|
|
421
|
-
- Kullanıcı bulunamazsa hata mesajı gösterilir
|
|
422
|
-
- Bulunursa: avatar, username, email, kayıt tarihi ve mevcut abonelik durumu gösterilir
|
|
423
|
-
- Plan seçimi (Lite / Premium / VIP)
|
|
424
|
-
- Period seçimi (Aylık / Yıllık)
|
|
425
|
-
- Süre seçimi (1 ay / 3 ay / 6 ay / 12 ay / özel tarih)
|
|
426
|
-
- "Ata" butonuna basıldığında:
|
|
427
|
-
- Subscription kaydı oluşturulur (source: "admin", adminAssignedBy kaydedilir)
|
|
428
|
-
- NodeBB grubuna eklenir (eski grup varsa çıkarılır)
|
|
429
|
-
|
|
430
|
-
#### Ayarlar Sayfası (`settings.ejs`) — YENİ
|
|
431
|
-
|
|
432
|
-
- Admin panelde **Ayarlar** menü öğesi eklenir
|
|
433
|
-
- Ayarlar sayfasında sistem genelindeki yapılandırmalar yönetilir:
|
|
434
|
-
- **İptal IP Adresi**: Abonelik iptali endpoint'inin kabul ettiği IP adresi (NodeBB sunucu IP'si)
|
|
435
|
-
- Mevcut IP gösterilir
|
|
436
|
-
- Yeni IP girilerek güncellenebilir
|
|
437
|
-
- Boş bırakılırsa `ALLOWED_CANCEL_IP` env değişkenine fallback yapılır
|
|
438
|
-
- Ayarlar veritabanında `Setting` modelinde key-value olarak saklanır
|
|
439
|
-
|
|
440
|
-
#### Kullanıcı Detay Sayfası (`subscriber-detail.ejs`)
|
|
441
|
-
|
|
442
|
-
- NodeBB'den çekilen profil bilgileri (avatar, username, email, uid)
|
|
443
|
-
- Mevcut aktif abonelik bilgisi (plan, period, başlangıç/bitiş, kaynak, otomatik yenileme)
|
|
444
|
-
- NodeBB grup üyeliği durumu
|
|
445
|
-
- **İşlem butonları:**
|
|
446
|
-
- **Plan Değiştir**: Dropdown ile yeni plan seç → onayda upgrade veya downgrade yapılır
|
|
447
|
-
- **Süre Düzenle**: Bitiş tarihini değiştir (date picker)
|
|
448
|
-
- **Aboneliği İptal Et**: Onay modal → iptal nedeni (opsiyonel) → iptal işlemi
|
|
449
|
-
- Geçmiş abonelik kayıtları tablosu (tüm subscription history)
|
|
450
|
-
|
|
451
|
-
#### Abone Listesi (`subscribers.ejs`)
|
|
452
|
-
|
|
453
|
-
- Mevcut filtreler + plan filtresi (Lite / Premium / VIP)
|
|
454
|
-
- Period filtresi (Aylık / Yıllık)
|
|
455
|
-
- Source filtresi (Ödeme / Admin / Upgrade)
|
|
456
|
-
- Her satırda plan badge'i gösterilir
|
|
457
|
-
- Her satırda kullanıcı detay sayfasına link
|
|
458
|
-
- Hızlı işlem butonları (iptal, plan değiştir)
|
|
459
|
-
|
|
460
|
-
---
|
|
461
|
-
|
|
462
|
-
## 5. NodeBB Entegrasyonu (Plugin Yok)
|
|
463
|
-
|
|
464
|
-
NodeBB tarafında **herhangi bir plugin yazılmaz**. Tüm iletişim NodeBB'nin yerleşik grup sistemi ve API'si üzerinden sağlanır.
|
|
465
|
-
|
|
466
|
-
### 5.1 Güvenlik Modeli
|
|
467
|
-
|
|
468
|
-
| İşlem | Güvenlik Riski | Çözüm |
|
|
469
|
-
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ---------------------------------------------- |
|
|
470
|
-
| **Plan satın alma** (`/pay/checkout?uid={uid}`) | Düşük — saldırgan başkasının uid'sini girse bile kendi parasıyla başkasına abonelik alır (hediye gibi) | Mevcut akış yeterli |
|
|
471
|
-
| **Plan yükseltme** (`/pay/checkout/upgrade?uid={uid}`) | Düşük — aynı mantık, saldırgan kendi kartıyla ödeme yapar | Mevcut akış yeterli |
|
|
472
|
-
| **Abonelik iptali** | Yüksek — başkasının aboneliğini iptal etme riski | IP kısıtlamalı endpoint ile çözüldü (bkz. 3.5) |
|
|
473
|
-
|
|
474
|
-
Sonuç: Ödeme gerektiren işlemlerde cross-service auth gerekmez (PayTR güvenliği yeterli). İptal endpoint'i sadece NodeBB sunucusunun IP'sinden gelen istekleri kabul eder.
|
|
475
|
-
|
|
476
|
-
### 5.2 NodeBB Tarafında Yapılacaklar (Admin Panelden, Kod Yazmadan)
|
|
477
|
-
|
|
478
|
-
#### 1. Grupları Oluştur
|
|
479
|
-
|
|
480
|
-
NodeBB Admin Panel → Groups → Create:
|
|
481
|
-
|
|
482
|
-
| Grup Adı | Tür | Amaç |
|
|
483
|
-
| --------- | -------------- | -------------------- |
|
|
484
|
-
| `lite` | Gizli (Hidden) | Lite plan üyeleri |
|
|
485
|
-
| `premium` | Gizli (Hidden) | Premium plan üyeleri |
|
|
486
|
-
| `vip` | Gizli (Hidden) | VIP plan üyeleri |
|
|
487
|
-
|
|
488
|
-
- Plan grupları (`lite`, `premium`, `vip`) → **Hidden** ve sadece API ile yönetilir. Kullanıcılar kendileri katılamaz/çıkamaz.
|
|
489
|
-
|
|
490
|
-
#### 2. Navigasyon Linkleri
|
|
491
|
-
|
|
492
|
-
NodeBB Admin Panel → Navigation:
|
|
493
|
-
|
|
494
|
-
- **"Planını Yükselt"** → `https://pay.ieu.app/pay/checkout?uid={uid}` (NodeBB template değişkeni ile uid otomatik eklenir)
|
|
495
|
-
- **"Aboneliği İptal Et"** → `https://pay.ieu.app/pay/cancel?uid={uid}` (ödeme servisindeki iptal sayfasına yönlendirir)
|
|
496
|
-
|
|
497
|
-
### 5.3 Ödeme Servisi Tarafında — IP Kısıtlamalı İptal Endpoint'i
|
|
498
|
-
|
|
499
|
-
Ödeme servisinde kullanıcının abonelik iptalini işleyen, IP kısıtlamalı endpoint:
|
|
500
|
-
|
|
501
|
-
#### Endpoint: `POST /pay/api/cancel-subscription`
|
|
502
|
-
|
|
503
|
-
```
|
|
504
|
-
Request:
|
|
505
|
-
Body: { uid: Number }
|
|
506
|
-
IP Kontrolü: Sadece ALLOWED_CANCEL_IP env değişkeninde tanımlı IP'den gelen istekler kabul edilir
|
|
507
|
-
|
|
508
|
-
İşlem:
|
|
509
|
-
1. IP kontrolü yap:
|
|
510
|
-
- req.ip veya x-forwarded-for header'ından gelen IP kontrol edilir
|
|
511
|
-
- ALLOWED_CANCEL_IP ile eşleşmiyorsa → 403 Forbidden döndür
|
|
512
|
-
2. MongoDB'de aktif abonelik ara (uid, status: "active")
|
|
513
|
-
3. Aktif abonelik varsa:
|
|
514
|
-
- autoRenew = false
|
|
515
|
-
- cancelRequestedAt = new Date()
|
|
516
|
-
4. Aktif abonelik yoksa → 404 döndür
|
|
517
|
-
5. Başarılı yanıt döndür (abonelik bitiş tarihi bilgisiyle)
|
|
518
|
-
|
|
519
|
-
Response (200):
|
|
520
|
-
{ success: true, expiresAt: "2025-03-15T00:00:00Z", message: "Otomatik yenileme iptal edildi." }
|
|
521
|
-
|
|
522
|
-
Response (403):
|
|
523
|
-
{ error: "Forbidden" }
|
|
524
|
-
|
|
525
|
-
Response (404):
|
|
526
|
-
{ error: "Aktif abonelik bulunamadı." }
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
#### İptal Sayfası: `GET /pay/cancel?uid={uid}`
|
|
530
|
-
|
|
531
|
-
- Kullanıcının aktif abonelik bilgilerini gösterir (plan, bitiş tarihi, otomatik yenileme durumu)
|
|
532
|
-
- "Otomatik Yenilemeyi İptal Et" butonu
|
|
533
|
-
- Butona tıklandığında `POST /pay/api/cancel-subscription` çağrılır
|
|
534
|
-
- İşlem sonrası onay mesajı gösterilir
|
|
535
|
-
|
|
536
|
-
#### IP Kısıtlama Middleware'i
|
|
537
|
-
|
|
538
|
-
```javascript
|
|
539
|
-
// src/middleware/ipRestrict.js
|
|
540
|
-
const Setting = require("../models/setting.model");
|
|
541
|
-
|
|
542
|
-
async function ipRestrict(req, res, next) {
|
|
543
|
-
// Önce veritabanından admin panelde tanımlanan IP'yi kontrol et
|
|
544
|
-
const setting = await Setting.findOne({ key: "allowedCancelIp" });
|
|
545
|
-
const allowedIp = setting?.value || process.env.ALLOWED_CANCEL_IP;
|
|
546
|
-
|
|
547
|
-
const clientIp = req.ip || req.headers["x-forwarded-for"]?.split(",")[0].trim();
|
|
548
|
-
if (clientIp !== allowedIp) {
|
|
549
|
-
return res.status(403).json({ error: "Forbidden" });
|
|
550
|
-
}
|
|
551
|
-
next();
|
|
552
|
-
}
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
> **Not**: IP adresi öncelik sırası: 1) Veritabanındaki `allowedCancelIp` ayarı (admin panelden yönetilir), 2) `ALLOWED_CANCEL_IP` environment değişkeni. Admin panelden ayar yapıldığında sunucu yeniden başlatılmadan IP değişikliği uygulanır.
|
|
556
|
-
|
|
557
|
-
### 5.4 Akış Diyagramları
|
|
558
|
-
|
|
559
|
-
#### Kullanıcı Aboneliğini İptal Eder
|
|
560
|
-
|
|
561
|
-
```
|
|
562
|
-
Kullanıcı (forum.ieu.app) Ödeme Servisi (pay.ieu.app)
|
|
563
|
-
│ │
|
|
564
|
-
│ "Aboneliği İptal Et" linkine tıklar │
|
|
565
|
-
│ → /pay/cancel?uid=123 │
|
|
566
|
-
│─────────────────────────────────────────────────────────────►│
|
|
567
|
-
│ │
|
|
568
|
-
│ İptal sayfası (aktif abonelik bilgileri + iptal butonu) │
|
|
569
|
-
│◄─────────────────────────────────────────────────────────────│
|
|
570
|
-
│ │
|
|
571
|
-
│ "Otomatik Yenilemeyi İptal Et" butonuna tıklar │
|
|
572
|
-
│ POST /pay/api/cancel-subscription {uid: 123} │
|
|
573
|
-
│─────────────────────────────────────────────────────────────►│
|
|
574
|
-
│ │
|
|
575
|
-
│ IP kontrolü (ALLOWED_CANCEL_IP)
|
|
576
|
-
│ ✓ Geçerli IP → devam et
|
|
577
|
-
│ │
|
|
578
|
-
│ autoRenew = false
|
|
579
|
-
│ cancelRequestedAt = now
|
|
580
|
-
│ │
|
|
581
|
-
│ Onay: "İptal edildi, aboneliğiniz │
|
|
582
|
-
│ {tarih}'e kadar aktif kalacaktır" │
|
|
583
|
-
│◄─────────────────────────────────────────────────────────────│
|
|
584
|
-
```
|
|
585
|
-
|
|
586
|
-
#### Kullanıcı Plan Satın Alır
|
|
587
|
-
|
|
588
|
-
```
|
|
589
|
-
Kullanıcı (forum.ieu.app) Ödeme Servisi (pay.ieu.app)
|
|
590
|
-
│ │
|
|
591
|
-
│ "Planını Yükselt" tıklar │
|
|
592
|
-
│ → /pay/checkout?uid=123 │
|
|
593
|
-
│─────────────────────────────────────────────────────────────►│
|
|
594
|
-
│ │
|
|
595
|
-
│ Plan seçim sayfası (3 kart + aylık/yıllık) │
|
|
596
|
-
│◄─────────────────────────────────────────────────────────────│
|
|
597
|
-
│ │
|
|
598
|
-
│ Plan seçer → billing form → PayTR ödeme │
|
|
599
|
-
│─────────────────────────────────────────────────────────────►│
|
|
600
|
-
│ │
|
|
601
|
-
│ PayTR callback → NodeBB grubuna ekle
|
|
602
|
-
│ → Subscription oluştur │
|
|
603
|
-
│ │
|
|
604
|
-
│ result?status=success │
|
|
605
|
-
│◄─────────────────────────────────────────────────────────────│
|
|
606
|
-
```
|
|
607
|
-
|
|
608
|
-
---
|
|
609
|
-
|
|
610
|
-
## 6. Frontend Tasarım
|
|
611
|
-
|
|
612
|
-
### 6.1 Plan Seçim Sayfası (home.ejs)
|
|
613
|
-
|
|
614
|
-
- 3 kart yan yana (mobilde alt alta)
|
|
615
|
-
- Aylık/Yıllık toggle switch (üstte)
|
|
616
|
-
- Yıllık seçildiğinde: "8 ay bedava!" badge, aylık eşdeğer fiyat gösterimi
|
|
617
|
-
- Premium kartı: "En Popüler" badge, hafif vurgu (border/shadow)
|
|
618
|
-
- VIP kartı: "Elit Deneyim" badge
|
|
619
|
-
- Her kartta: Özellik listesi + fiyat + "Satın Al" butonu
|
|
620
|
-
- Aktif aboneliği olan kullanıcı: mevcut plan vurgulanır, alt planlar disabled, üst planlarda "Yükselt" butonu
|
|
621
|
-
|
|
622
|
-
### 6.2 Upgrade Sayfası
|
|
623
|
-
|
|
624
|
-
- Mevcut plan vs yeni plan karşılaştırması
|
|
625
|
-
- Prorated fark ücreti hesabı gösterimi
|
|
626
|
-
- Kalan gün bilgisi
|
|
627
|
-
- Onay butonu → billing form'a yönlendir
|
|
628
|
-
|
|
629
|
-
---
|
|
630
|
-
|
|
631
|
-
## 7. Yasal Uyumluluk ve Bilgilendirmeler
|
|
632
|
-
|
|
633
|
-
Ödeme içeren bir abonelik sistemi olduğundan, Türkiye mevzuatına tam uyum sağlanmalıdır.
|
|
634
|
-
|
|
635
|
-
### 7.1 Uyulması Gereken Mevzuat
|
|
636
|
-
|
|
637
|
-
| Mevzuat | Kapsam |
|
|
638
|
-
| ---------------------------------------------------------------- | ------------------------------------------------------------------- |
|
|
639
|
-
| **6502 sayılı Tüketicinin Korunması Hakkında Kanun** | Tüketici hakları, cayma hakkı, haksız şartlar |
|
|
640
|
-
| **Mesafeli Sözleşmeler Yönetmeliği** | Ön bilgilendirme, sözleşme, cayma hakkı, dijital içerik istisnaları |
|
|
641
|
-
| **6698 sayılı KVKK** | Kişisel verilerin korunması, aydınlatma yükümlülüğü, açık rıza |
|
|
642
|
-
| **6563 sayılı Elektronik Ticaretin Düzenlenmesi Hakkında Kanun** | Hizmet sağlayıcı bilgileri, ticari iletişim, sipariş onayı |
|
|
643
|
-
| **5651 sayılı İnternet Kanunu** | İçerik sağlayıcı sorumlulukları |
|
|
644
|
-
| **Abonelik Sözleşmeleri Yönetmeliği** | Otomatik yenileme bilgilendirme, abonelik iptali |
|
|
645
|
-
|
|
646
|
-
### 7.2 Satın Alma Öncesi Bilgilendirmeler
|
|
647
|
-
|
|
648
|
-
Kullanıcı ödeme yapmadan önce aşağıdaki bilgilendirmeler **açıkça** sunulmalı ve onay alınmalıdır:
|
|
649
|
-
|
|
650
|
-
#### Ön Bilgilendirme Formu (Zorunlu)
|
|
651
|
-
|
|
652
|
-
Plan seçim sayfasında veya billing formunda kullanıcıya gösterilecek:
|
|
653
|
-
|
|
654
|
-
- Hizmet sağlayıcı bilgileri (unvan, adres, iletişim)
|
|
655
|
-
- Seçilen planın adı, kapsamı ve özellikleri
|
|
656
|
-
- Toplam fiyat (KDV dahil, kuruş cinsinden net tutar)
|
|
657
|
-
- Ödeme yöntemi ve koşulları
|
|
658
|
-
- Abonelik süresi (aylık: 30 gün, yıllık: 365 gün)
|
|
659
|
-
- Otomatik yenileme durumu ve koşulları
|
|
660
|
-
- Cayma hakkı bilgilendirmesi (dijital içerik istisnası dahil)
|
|
661
|
-
- Şikayet ve itiraz mekanizmaları
|
|
662
|
-
|
|
663
|
-
#### Onay Checkbox'ları (Satın alma butonundan önce)
|
|
664
|
-
|
|
665
|
-
Kullanıcının tüm checkbox'ları işaretlemesi zorunludur:
|
|
666
|
-
|
|
667
|
-
1. **Sözleşme onayı** (mevcut, güncellenmeli):
|
|
668
|
-
|
|
669
|
-
> "Mesafeli Satış Sözleşmesi'ni, Kullanım Koşulları'nı, Gizlilik Politikası'nı ve KVKK Aydınlatma Metni'ni okudum, anladım ve kabul ediyorum."
|
|
670
|
-
|
|
671
|
-
2. **Dijital içerik cayma hakkı feragati** (mevcut, güncellenmeli):
|
|
672
|
-
|
|
673
|
-
> "Dijital içerik hizmetinin derhal ifasına başlanmasını talep ettiğimi ve bu sebeple 14 günlük cayma hakkımdan feragat ettiğimi onaylıyorum."
|
|
674
|
-
|
|
675
|
-
3. **Otomatik yenileme bilgilendirmesi** (YENİ — varsayılan tikli):
|
|
676
|
-
|
|
677
|
-
> "Abonelik sürem dolduğunda, aynı plan ve ödeme tutarı ile otomatik olarak yenileneceğini biliyorum. Otomatik yenilemeyi istediğim zaman iptal edebileceğimi anlıyorum."
|
|
678
|
-
|
|
679
|
-
4. **Ön bilgilendirme formu onayı** (YENİ):
|
|
680
|
-
> "Ön Bilgilendirme Formu'nu okudum ve satın alma öncesi gerekli tüm bilgileri aldım."
|
|
681
|
-
|
|
682
|
-
### 7.3 Otomatik Yenileme — Yasal Gereklilikler
|
|
683
|
-
|
|
684
|
-
Abonelik Sözleşmeleri Yönetmeliği gereği:
|
|
685
|
-
|
|
686
|
-
- **Satış anında**: Otomatik yenileme tercihi açıkça gösterilmeli, fiyat ve yenilenme tarihi belirtilmeli
|
|
687
|
-
- **Yenileme öncesi bildirim**: Abonelik sona ermeden **en az 3 gün önce** kullanıcıya e-posta ile bildirim gönderilmeli:
|
|
688
|
-
- Yenilenecek plan adı
|
|
689
|
-
- Yenileme tutarı
|
|
690
|
-
- Yenileme tarihi
|
|
691
|
-
- İptal etme linki / talimatları
|
|
692
|
-
- **Kolay iptal**: Kullanıcı otomatik yenilemeyi kolayca kapatabilmeli (forum profili veya ödeme sayfası üzerinden)
|
|
693
|
-
- **İptal onayı**: Otomatik yenileme kapatıldığında kullanıcıya onay bildirimi gönderilmeli
|
|
694
|
-
|
|
695
|
-
### 7.4 Cayma Hakkı ve İade Politikası
|
|
696
|
-
|
|
697
|
-
6502 sayılı Kanun ve Mesafeli Sözleşmeler Yönetmeliği kapsamında:
|
|
698
|
-
|
|
699
|
-
- **Genel kural**: Mesafeli satışlarda tüketici 14 gün içinde cayma hakkına sahiptir
|
|
700
|
-
- **Dijital içerik istisnası**: Elektronik ortamda anında ifa edilen dijital içeriklerde, tüketicinin önceden açık onayı ve cayma hakkından feragat beyanı alınmışsa cayma hakkı uygulanmaz
|
|
701
|
-
- **Bu sistemde**: Kullanıcı satın alma öncesinde dijital içerik feragat checkbox'ını onayladığı için cayma hakkı bulunmaz
|
|
702
|
-
- **İade**: İade politikası sayfasında (`legal-refund.ejs`) bu durum açıkça belirtilmelidir
|
|
703
|
-
- **Admin iptali**: Admin tarafından yapılan iptallerde iade kararı admin'in insiyatifindedir
|
|
704
|
-
|
|
705
|
-
### 7.5 Güncellenecek Yasal Sayfalar
|
|
706
|
-
|
|
707
|
-
Mevcut yasal sayfalar çok katmanlı plan yapısına göre güncellenmelidir:
|
|
708
|
-
|
|
709
|
-
| Sayfa | Güncellenecek İçerik |
|
|
710
|
-
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
711
|
-
| `legal-distance.ejs` | Plan isimleri (Lite/Premium/VIP), fiyat tablosu, otomatik yenileme maddeleri, yıllık abonelik koşulları, upgrade/downgrade kuralları |
|
|
712
|
-
| `legal-terms.ejs` | Çoklu plan tanımları, plan yükseltme/düşürme koşulları, otomatik yenileme kuralları, admin iptal yetkisi |
|
|
713
|
-
| `legal-refund.ejs` | Plan bazlı iade kuralları, upgrade'de prorated hesaplama açıklaması, otomatik yenileme iptali prosedürü |
|
|
714
|
-
| `legal-privacy.ejs` | Otomatik yenileme için saklanan ödeme bilgileri, plan tercihi verisi |
|
|
715
|
-
| `legal-kvkk.ejs` | Ödeme bilgileri işleme amacı, otomatik yenileme kapsamında veri saklama süresi |
|
|
716
|
-
|
|
717
|
-
### 7.6 Satın Alma Sonrası Bilgilendirmeler
|
|
718
|
-
|
|
719
|
-
#### Sipariş Onay E-postası / Ekranı
|
|
720
|
-
|
|
721
|
-
Ödeme başarılı olduğunda kullanıcıya gösterilecek ve (e-posta altyapısı varsa) gönderilecek bilgiler:
|
|
722
|
-
|
|
723
|
-
- Satın alınan plan adı ve özellikleri
|
|
724
|
-
- Ödenen tutar (KDV dahil)
|
|
725
|
-
- Abonelik başlangıç ve bitiş tarihi
|
|
726
|
-
- Otomatik yenileme durumu (açık/kapalı)
|
|
727
|
-
- Bir sonraki yenileme tarihi ve tutarı (otomatik yenileme açıksa)
|
|
728
|
-
- İptal ve iletişim bilgileri
|
|
729
|
-
|
|
730
|
-
#### Result Sayfası (`result.ejs`)
|
|
731
|
-
|
|
732
|
-
Başarılı ödeme sonrası gösterilecek ek bilgiler:
|
|
733
|
-
|
|
734
|
-
- Seçilen plan adı
|
|
735
|
-
- Abonelik bitiş tarihi
|
|
736
|
-
- Otomatik yenileme durumu
|
|
737
|
-
- Destek iletişim bilgileri
|
|
738
|
-
|
|
739
|
-
### 7.7 Fiyat Gösterimi Kuralları
|
|
740
|
-
|
|
741
|
-
- Tüm fiyatlar **KDV dahil** olarak gösterilmelidir
|
|
742
|
-
- Para birimi açıkça belirtilmelidir (₺ / TL)
|
|
743
|
-
- Yıllık planda: toplam tutar + aylık eşdeğer fiyat + tasarruf miktarı gösterilmelidir
|
|
744
|
-
- Upgrade'de: fark ücreti hesaplaması kullanıcıya şeffaf şekilde gösterilmelidir (kalan gün, günlük fark, toplam fark)
|
|
745
|
-
- İndirimli fiyat gösteriminde eski fiyat ve indirim oranı belirtilmelidir
|
|
746
|
-
|
|
747
|
-
### 7.8 Hizmet Sağlayıcı Bilgileri
|
|
748
|
-
|
|
749
|
-
Tüm sayfalarda (footer veya erişilebilir bir yerde) bulunması gereken bilgiler:
|
|
750
|
-
|
|
751
|
-
- Hizmet sağlayıcı unvanı
|
|
752
|
-
- İletişim e-posta adresi
|
|
753
|
-
- Website adresi
|
|
754
|
-
- Şikayet/destek kanalı
|
|
755
|
-
|
|
756
|
-
---
|
|
757
|
-
|
|
758
|
-
## 8. Environment Değişkenleri
|
|
759
|
-
|
|
760
|
-
```env
|
|
761
|
-
# Mevcut değişkenler korunur, ek olarak:
|
|
762
|
-
NODEBB_LITE_GROUP=lite
|
|
763
|
-
NODEBB_PREMIUM_GROUP=premium
|
|
764
|
-
NODEBB_VIP_GROUP=vip
|
|
765
|
-
ALLOWED_CANCEL_IP=1.2.3.4 # NodeBB sunucusunun IP adresi — varsayılan değer; admin panelden güncellenebilir (DB'deki değer önceliklidir)
|
|
766
|
-
```
|
|
767
|
-
|
|
768
|
-
> Not: Grup isimleri `src/config/plans.js` içinde tanımlı olacağından, env'den de okunabilir veya direkt config'te sabitlenebilir.
|
|
769
|
-
|
|
770
|
-
---
|
|
771
|
-
|
|
772
|
-
## 9. Migration / Geçiş Planı
|
|
773
|
-
|
|
774
|
-
Mevcut "premium" grubundaki kullanıcılar için geçiş:
|
|
775
|
-
|
|
776
|
-
1. Mevcut tüm aktif aboneliklere `plan: "premium"` ve `period: "monthly"` atanır (geriye dönük uyumluluk)
|
|
777
|
-
2. `amount: 9990` (mevcut fiyat 99.90₺) olarak set edilir
|
|
778
|
-
3. NodeBB'de mevcut "premium" grubundaki kullanıcılar "premium" grubunda kalır (grup adı aynı)
|
|
779
|
-
4. Migration script'i `src/scripts/migrate-plans.js` olarak yazılır
|
|
780
|
-
|
|
781
|
-
---
|
|
782
|
-
|
|
783
|
-
## 10. Uygulama Sırası
|
|
784
|
-
|
|
785
|
-
### Faz 1: Altyapı
|
|
786
|
-
|
|
787
|
-
1. `src/config/plans.js` oluştur — plan tanımları
|
|
788
|
-
2. `subscription.model.js` güncelle — yeni alanlar
|
|
789
|
-
3. Migration script yaz ve çalıştır
|
|
790
|
-
|
|
791
|
-
### Faz 2: Servis Katmanı
|
|
792
|
-
|
|
793
|
-
4. `nodebb.service.js` güncelle — çoklu grup desteği
|
|
794
|
-
5. `paytr.service.js` güncelle — dinamik fiyat/ürün
|
|
795
|
-
6. `subscription.service.js` güncelle — plan-aware CRUD + upgrade hesaplama
|
|
796
|
-
|
|
797
|
-
### Faz 3: Ödeme Akışı
|
|
798
|
-
|
|
799
|
-
7. `payment.controller.js` güncelle — plan seçimi + upgrade flow
|
|
800
|
-
8. `payment.routes.js` güncelle — yeni route'lar
|
|
801
|
-
9. Frontend: `home.ejs` (plan kartları), `billing-form.ejs`, `payment.ejs`, `result.ejs`
|
|
802
|
-
|
|
803
|
-
### Faz 4: Admin Paneli
|
|
804
|
-
|
|
805
|
-
10. `admin.service.js` güncelle — plan bazlı istatistikler + manuel atama
|
|
806
|
-
11. `admin.controller.js` güncelle — yeni endpoint'ler
|
|
807
|
-
12. `admin.routes.js` güncelle — yeni route'lar
|
|
808
|
-
13. Frontend: `dashboard.ejs`, `subscribers.ejs`, `assign.ejs` (yeni)
|
|
809
|
-
|
|
810
|
-
### Faz 5: Yasal Uyumluluk
|
|
811
|
-
|
|
812
|
-
14. Yasal sayfalar güncelle — çoklu plan, otomatik yenileme, upgrade/downgrade kuralları
|
|
813
|
-
15. Ön bilgilendirme formu ve onay checkbox'ları ekle
|
|
814
|
-
16. Otomatik yenileme öncesi bildirim mekanizması (cron + e-posta)
|
|
815
|
-
|
|
816
|
-
### Faz 6: Test & Doğrulama
|
|
817
|
-
|
|
818
|
-
17. `.env.example` güncelle
|
|
819
|
-
18. Tüm akışları test et (yeni abone, upgrade, admin atama, süre dolumu, yasal onaylar)
|
|
820
|
-
|
|
821
|
-
---
|
|
822
|
-
|
|
823
|
-
## 11. Doğrulama (Verification)
|
|
824
|
-
|
|
825
|
-
### Test Senaryoları
|
|
826
|
-
|
|
827
|
-
1. **Yeni Abonelik**: Her 3 plan x 2 period = 6 senaryo test
|
|
828
|
-
2. **Upgrade**: Lite→Premium, Lite→VIP, Premium→VIP = 3 senaryo
|
|
829
|
-
3. **Admin Atama**: Her plan için manuel atama testi
|
|
830
|
-
4. **Süre Dolumu**: Cron job'un doğru grubu kaldırdığını doğrula
|
|
831
|
-
5. **NodeBB Grup**: Upgrade'de eski gruptan çıkıp yeni gruba girdiğini doğrula
|
|
832
|
-
6. **PayTR Callback**: merchantOid parse'ın doğru çalıştığını doğrula
|
|
833
|
-
7. **Prorated Hesaplama**: Fark ücretinin doğru hesaplandığını doğrula
|
|
834
|
-
8. **Dashboard**: Plan bazlı istatistiklerin doğru gösterildiğini doğrula
|
|
835
|
-
9. **Yasal Onaylar**: Checkbox'lar işaretlenmeden ödeme butonunun aktif olmadığını doğrula
|
|
836
|
-
10. **Otomatik Yenileme Bildirimi**: Süre dolmadan 3 gün önce bildirim cron job'ının çalıştığını doğrula
|
|
837
|
-
11. **Yasal Sayfalar**: Tüm yasal sayfalarda plan isimleri, fiyatlar ve otomatik yenileme bilgilerinin güncel olduğunu doğrula
|
|
838
|
-
|
|
839
|
-
### Test Yöntemi
|
|
840
|
-
|
|
841
|
-
- PayTR test mode ile ödeme akışı testi
|
|
842
|
-
- MongoDB'de kayıt doğrulama
|
|
843
|
-
- NodeBB API'den grup üyeliği doğrulama
|
|
844
|
-
- Admin panel üzerinden manuel kontrol
|