SaaS Gelir Modeli: Tek Seferlik Satıştan Aboneliğe Geçiş
2025'te yazılım dünyasının standardı artık Subscription (Abonelik) modelidir. Kullanıcılar bir yazılımı satın almak yerine, kullandıkları kadar ödemeyi (Pay-as-you-go) veya aylık sabit ücreti tercih ediyorlar. Bu model, işletmeler için öngörülebilir gelir (MRR - Monthly Recurring Revenue) demektir.
Ancak teknik olarak bir abonelik sistemi kurmak, tek seferlik ödeme almaktan çok daha karmaşıktır. Kartın süresi dolarsa ne olacak? Kullanıcı paketini yükseltirse (upgrade) aradaki fark nasıl hesaplanacak? İptal ederse erişim ne zaman kesilecek?
Exludio Co. olarak geliştirdiğimiz SaaS projelerinde kullandığımız Next.js + Stripe + Prisma mimarisini bu yazıda detaylandırıyoruz.
1. Veritabanı Modellemesi (Prisma Schema)
Abonelik sisteminin kalbi veritabanıdır. Kullanıcı ile abonelik durumu arasındaki ilişkiyi doğru kurmalısınız.
model User {
id String @id @default(cuid())
email String @unique
stripeCustomerId String? @unique // Stripe'daki Müşteri ID'si
subscription Subscription?
}
model Subscription {
id String @id @default(cuid())
userId String @unique
user User @relation(fields: [userId], references: [id])
stripeSubscriptionId String @unique
status String // active, past_due, canceled, trialing
priceId String // Hangi pakette olduğu
currentPeriodEnd DateTime // Yenilenme tarihi
}
2. Stripe Entegrasyonu: Checkout vs Elements
Stripe iki ana yöntem sunar:
- Stripe Checkout: Kullanıcıyı Stripe'ın güvenli ödeme sayfasına yönlendirirsiniz. En hızlı ve güvenli yöntemdir.
- Stripe Elements: Kendi sitenizde ödeme formu oluşturursunuz. Daha fazla özelleştirme sunar ama geliştirme süresi uzundur.
Exludio Önerisi: MVP aşamasında kesinlikle Stripe Checkout kullanın. Hem mobil uyumlu hem de Apple Pay / Google Pay hazır gelir.
3. Webhook Yönetimi: Senkronizasyonun Sırrı
Ödeme işlemi Stripe tarafında gerçekleştiği için, veritabanınızı güncellemek için Webhook kullanmalısınız. Stripe, bir olay olduğunda (ödeme başarılı, abonelik iptal vb.) sizin API'nize bir POST isteği atar.
Kritik Webhook Event'leri:
checkout.session.completed: İlk ödeme başarılı, aboneliği veritabanına kaydet.invoice.payment_succeeded: Aylık yenileme başarılı, süreyi uzat.invoice.payment_failed: Karttan çekim yapılamadı, kullanıcıya e-posta at ve erişimi kısıtla.customer.subscription.updated: Paket değişikliği veya iptal durumu.
4. Customer Portal: Kullanıcı Kendi Aboneliğini Yönetsin
Kullanıcı "Kartımı değiştirmek istiyorum" veya "Faturamı indir" dediğinde destek ekibine yazmamalı. Stripe'ın sunduğu Customer Portal özelliği ile, tek satır kodla kullanıcılara self-service panel sunabilirsiniz.
5. Abonelik Durumuna Göre Erişim (Middleware)
Next.js Middleware kullanarak, kullanıcının abonelik durumunu her sayfada kontrol edebilirsiniz.
// middleware.ts
export default async function middleware(req) {
const session = await getSession(req);
if (req.nextUrl.pathname.startsWith('/dashboard')) {
if (!session) return NextResponse.redirect('/login');
if (session.subscriptionStatus !== 'active') return NextResponse.redirect('/pricing');
}
}
Exludio ile SaaS Altyapınızı Kurun
Abonelik sistemi, bir SaaS projesinin en riskli kısmıdır. Yanlış bir kurgu, gelir kaybına veya yasal sorunlara yol açabilir. Exludio Co. olarak, Stripe sertifikalı uzmanlarımızla güvenli ve ölçeklenebilir ödeme altyapıları kuruyoruz.
SaaS projeniz için teknik danışmanlık almak isterseniz bizimle iletişime geçin.