Skip to content

Checkout & Webhooks

payment.checkout.tsx loader'ı ve Stripe checkout.session.completed olaylarının işlenmesi.

Coursio’da ödeme akışı Stripe Checkout ile tamamlanır; tamamlanan oturumlar webhook ile işlenir. Bu sayfa, payment.checkout.tsx loader’ının rolünü ve Stripe’tan gelen checkout.session.completed sinyallerinin nasıl işlendiğini açıklar.

payment.checkout.tsx — Loader’ın Rolü

Section titled “payment.checkout.tsx — Loader’ın Rolü”

Dosya: app/routes/payment.checkout.tsx

Checkout sayfasına girildiğinde loader şunları yapar:

  1. Kimlik doğrulama: Oturum kontrolü; yoksa /${lang}/login’e yönlendirme.
  2. Sepet / tek ürün: URL’den courseId veya bundleId (veya sepet için birden fazla ürün) alınır; mükerrer satın alma kontrolü (paket veya kurs zaten alınmış mı).
  3. Veritabanı: Sepet (getCart), tek kurs (getCourseById), tek paket (getBundleById) paralel çekilir.
  4. Bölgesel fiyat: getCountryFromRequest(request, env, context?.cloudflare) ile ülke; getRegionalPriceFromRequest(db, priceTierId, request) ile fiyat ve para birimi alınır. Geliştirme için ?test_country=TR ile ülke taklidi yapılabilir.
  5. Stripe Payment Methods: Kullanıcının kayıtlı kartları stripe.paymentMethods.list ile listelenir; varsayılan kart bilgisi de gelir.
  6. Dönüş: Loader, checkout sayfasında kullanılacak veriyi döner: sepet içeriği, toplam tutar, bölgesel fiyat, para birimi sembolü, kayıtlı ödeme yöntemleri, tek kurs/paket bilgisi vb.

Checkout sayfası bu veriyle ödeme formunu ve (gerekirse) Stripe Checkout Session oluşturma / yönlendirme adımını sunar. Session oluşturulurken metadata içine userId, courseId/courseIds, bundleId/bundleIds, affiliateCode, saleType, instructorRef vb. eklenir; webhook tarafında bu metadata kullanılır.

Stripe Webhook — checkout.session.completed

Section titled “Stripe Webhook — checkout.session.completed”

Dosya: app/routes/api.stripe.webhook.ts

Stripe, ödeme tamamlandığında checkout.session.completed event’ini webhook URL’ine (örn. /api/stripe/webhook) POST eder.

  • Gelen gövde ve Stripe-Signature header’ı, STRIPE_WEBHOOK_SECRET ile doğrulanır: stripe.webhooks.constructEventAsync(body, sig, webhookSecret).
  • Doğrulama başarısızsa istek reddedilir; böylece sahte ödeme bildirimi engellenir.
  1. metadata: userId, courseId / courseIds, bundleId / bundleIds, saleType, affiliateCode vb. okunur.
  2. Mod kontrolü:
    • subscription: Abonelik satın alma; kullanıcı abone yapılır (abonelik güncelleme fonksiyonu çağrılır).
    • payment: Tek seferlik ödeme (kurs veya sepet).
  3. Payment modunda:
    • Idempotency: Aynı session.id için daha önce enrollment oluşturulmuşsa tekrar oluşturulmaz.
    • Enrollment: Satın alınan her kurs için enrollments tablosuna kayıt: userId, courseId, bundleId (paket satışıysa), stripeCheckoutSessionId, stripePaymentIntentId.
    • Komisyon motoru: handleCourseSale (veya eşdeğer fonksiyon) çağrılır; toplam tutar, eğitmen/platform/affiliate oranlarına göre bölünür ve earnings tablosuna yazılır (instructor_ref, affiliate, organik vb. kurallara göre).
  4. Fatura / e-posta: İsteğe bağlı olarak fatura oluşturma ve satın alma bildirim e-postası tetiklenir.

Böylece checkout.session.completed tek bir event ile hem kayıt (enrollment) hem kazanç dağılımı (earnings) hem de (varsa) abonelik güncellemesi ve bildirimler yapılır.

AşamaAçıklama
1Kullanıcı checkout sayfasına girer → loader sepeti, fiyatı (bölgesel), ödeme yöntemlerini hazırlar.
2Kullanıcı ödemeyi tamamlar → Stripe Checkout Session tamamlanır.
3Stripe checkout.session.completed webhook’u gönderir → api.stripe.webhook imzayı doğrular.
4Enrollment’lar oluşturulur; komisyon motoru earnings kayıtlarını yazar; abonelik/fatura/e-posta işlemleri yapılır.

Diğer event’ler (örn. payment_intent.succeeded, abonelik iptali) de aynı webhook dosyasında idempotency ve enrollment/earnings kurallarına uygun şekilde işlenir; ana “ödeme tamamlandı” sinyali checkout.session.completed’dır.

  • app/routes/api.stripe.webhook.ts — Stripe webhook; checkout.session.completed ve diğer event’lerin işlenmesi.
  • app/routes/payment.checkout.tsx — Checkout sayfası loader ve Stripe Session oluşturma.
  • app/routes/cart.tsx — Sepet sayfası.
  • app/lib/stripe-connect-payout.ts — Connect transfer (admin onayı sonrası processPayoutTransfer).
  • app/lib/payout-engine.ts — Payout talebi ve earnings mantığı.