Admin Yönetim Paneli (Admin Console)
Kurs moderasyonu, finansal yönetim, ödeme/iade, fiyat katmanları (admin.price-tiers), KYC onayları ve çoklu ödeme yöntemi desteği.
Achidemy’de Admin rolüne sahip kullanıcılar, Admin Console üzerinden kurs onaylama/reddetme, platform geliri ve bekleyen ödemeleri yönetme, iade (refund) takibi, KYC (kimlik doğrulama) onayları ve fiyat katmanları (tier) güncellemesi yapar. Bu sayfa kullanıcı ve kurs moderasyonu, finansal yönetim (toplam gelir, bekleyen ödemeler, iade), KYC onay paneli ve admin.price-tiers.tsx ile global fiyat güncellemelerini açıklar.
Genel Erişim
Section titled “Genel Erişim”- Yetki: Tüm admin route’larında
session.user.role === "admin"kontrolü yapılır; değilse 401 veya 404. - Layout:
app/routes/admin.tsx— sidebar (Kurslar, Kullanıcılar, Finans, Ödemeler, İadeler, Fiyat Katmanları, Abonelik, KYC Onayları, Şikayetler (DMCA) vb.) ve bildirim kutusu (Son Hareketler / Tüm Bildirimler). - Dashboard:
admin._index.tsx—getAdminStats(db)ile özet metrikler (kullanıcı sayıları, onay bekleyen kurs, gelir özeti).
Kullanıcı ve Kurs Moderasyonu
Section titled “Kullanıcı ve Kurs Moderasyonu”Kurs Onaylama / Reddetme Süreçleri
Section titled “Kurs Onaylama / Reddetme Süreçleri”Dosya: app/routes/admin.courses.tsx
Loader:
- Tüm kurslar eğitmen bilgisiyle sayfalanır (
courses+usersjoin); alanlar:id,title,status,slug,price,thumbnailUrl,instructor.name,instructor.email. statusdeğerleri:draft,pending_review,published,archived.
Liste:
- Her satırda kurs başlığı, eğitmen adı/e-posta, durum badge’i (İnceleme Bekliyor / Yayında / Taslak), fiyat, thumbnail.
- İnceleme Bekliyor (
pending_review): “İncele” ve “Onayla” / “Reddet” aksiyonları.
Karar mekanizması:
- Onayla: GraphQL
updateCourse(id, status: "published")→ kurs yayına alınır. - Reddet: GraphQL
updateCourse(id, status: "draft")→ kurs taslağa çekilir. - İşlem sonrası toast ve
revalidate()ile liste güncellenir.
Önizleme: “İncele” ile admin.course.$slug.preview sayfasına gidilir.
Kurs Önizleme (İnceleme Öncesi)
Section titled “Kurs Önizleme (İnceleme Öncesi)”Dosya: app/routes/admin.course.$slug.preview.tsx
URL: /admin/course/:slug/preview
Loader:
- Admin oturumu kontrolü;
getCourseBySlug(db, params.slug)ile kurs;getCourseCurriculum(db, course.id)ile müfredat. - Toplam süre ve ders sayısı müfredattan hesaplanır; bölgesel fiyat
getRegionalPrice(db, course.priceTierId, country)ile alınır.
Sayfa: Kurs başlığı, açıklama, öğrenme çıktıları, müfredat (bölüm/ders listesi, video hazır bilgisi), fiyat. “Denetim Listesine Dön” ile /admin/courses’a dönülür; onay/red işlemi kurs listesi sayfasındaki butonlarla yapılır.
AI Kalite Ön İncelemesi: Sayfada AICourseReviewer bileşeni (app/components/admin/AICourseReviewer.tsx) bulunur. “Otomatik Tara” butonu ile Cloudflare AI (Llama 3.1 8B) kursun başlığını, açıklamasını, müfredatını, fiyatını ve eksik asset’leri (kapak, tanıtım videosu) analiz eder; kalite skoru, küfür tespiti ve eylem tavsiyesi sunar. Detay için Yapay Zeka Destekli Moderasyon sayfasına bakın.
Şikayetler (DMCA) ve Kurs İnceleme
Section titled “Şikayetler (DMCA) ve Kurs İnceleme”Kurs Bazlı Şikayet Listesi
Section titled “Kurs Bazlı Şikayet Listesi”- Dosya:
app/routes/admin.reports.tsx - URL:
/admin/reports
Özellikler:
course_reportstablosundaki kayıtlar kurs bazlı gruplanır; her kurs için tek kart gösterilir.- Her kartta:
- Kurs başlığı ve eğitmen bilgisi
totalReports— ilgili kurs için açılmış toplam şikayet sayısıpendingReports— durumupendingolan açık şikayet sayısı- Son şikayetin özeti (neden, tarih)
- Sıralama:
- Önce
pendingReports(azalan), - sonra
totalReports(azalan), - ardından en yeni şikayet tarihi (azalan).
- Önce
- Her kartta:
/admin/reports/:courseIddetay sayfasına giden “İncele” butonu- Alt tabloda yer alan bireysel şikayet satırları için durum dropdown’u (
pending,reviewed,resolved,rejected) veuseFetcherile anlık güncelleme.
Bu sayfa, en çok şikayet alan kursları en üstte göstererek admin’in önceliklendirme yapmasını sağlar.
Detaylı Şikayet Sayfası
Section titled “Detaylı Şikayet Sayfası”- Dosya:
app/routes/admin.reports.$courseId.tsx - URL:
/admin/reports/:courseId
Loader:
- İlgili kurs bilgileri (
courses+usersjoin):id,title,slug,status,isMarketplaceVisible- Eğitmen adı ve e‑posta
- Kursa ait tüm
course_reportskayıtları:reason,description,status,createdAt, raporu gönderen kullanıcı bilgileri
Sayfa:
- Üst bölümde kurs başlığı, mevcut durum, pazarda görünürlük (
isMarketplaceVisible) ve açık şikayet sayısı gösterilir. - Alt bölümde her bir şikayet kartı:
- Şikayet nedeni ve açıklama
- Şikayet sahibi (ad/e‑posta)
- Oluşturulma tarihi
- Durum badge’i (
pending,reviewed,resolved,rejected)
Action:
- Intent:
mark_under_review - İşlemler:
- Kurs:
status = "pending_review"isMarketplaceVisible = false(kurs pazardan kaldırılır)
- İlgili kurs için durumu
pendingolan tümcourse_reportskayıtlarıreviewedyapılır. - Eğitmene, bildirim sistemi üzerinden (
createNotification) kursun şikayet/DMCA nedeniyle inceleme altına alındığını ve geçici olarak yayından kaldırıldığını anlatan bir mesaj gönderilir. Bildirim dili,getNotificationLangForUserile kullanıcının ülkesine göre seçilir.
- Kurs:
AI Şikayet Analizi: Sayfada Achidemy AI Moderatör (AIReportAnalyzer) paneli bulunur. “Tüm Şikayetleri Analiz Et” butonu ile Cloudflare AI (Llama 3.1 8B) tüm şikayetleri özetler; ortak nedenler, çıkarılan linkler ve kritiklik skoru üretir. Detay için Yapay Zeka Destekli Moderasyon sayfasına bakın.
Bu akış, platformun DMCA / Safe Harbor yükümlülükleri kapsamında, şikayetlerin kayıt altına alınması, incelenmesi ve kursun gerekirse pazardan kaldırılması için standart bir süreç sunar.
Finansal Yönetim
Section titled “Finansal Yönetim”Toplam Platform Geliri ve Metrikler
Section titled “Toplam Platform Geliri ve Metrikler”Dosya: app/routes/admin.finances.tsx
Loader: getAdminStats(db) ve getAdminSystemStats(db) (app/lib/db-queries.ts).
getAdminStats: earnings tablosundan (status ≠ refunded) satış türüne göre ayrıştırma:
- Brüt satış geliri, organik/direkt/affiliate satış sayıları ve payları.
- Abonelik: brüt abonelik geliri, platform payı (%60), eğitmen havuzu (%40).
- Toplam iade tutarı, net platform karı (totalRevenue) vb.
getAdminSystemStats:
- Tamamlanan öğretmen ödemeleri toplamı (
payout_requests.status = 'completed'). - Bekleyen ödemeler toplamı (
payout_requests.status = 'pending').
Sayfa kartları (örnek):
- Net Platform Karı (totalRevenue).
- Organik Satış Payı (purchaseRevenue, %55 komisyon).
- Bekleyen Ödemeler (system.pendingPayoutAmount).
- Toplam İade Tutarı (totalRefundedAmount).
- Affiliate satış payı ve affiliate komisyonu.
- Abonelik ekonomisi: brüt gelir, platform %60, eğitmen havuzu %40.
- “Gelir Havuzunu Dağıt” butonu →
adminDistributeSubscriptionEarnings(totalPool)mutation (abonelik havuzunu eğitmenlere dağıtım).
Abonelik Analiz Merkezi ve Havuz Dağıtımı
Section titled “Abonelik Analiz Merkezi ve Havuz Dağıtımı”Abonelik ekonomisi için ayrı bir analiz merkezi ve havuz dağıtım mantığı vardır:
- Dosya:
app/lib/db-queries.ts—getAdminSubscriptionStats(db)- Aktif abone sayısı, aylık abonelik fiyatı, brüt abonelik geliri, platform payı (%60), eğitmen havuzu (%40).
- Son 6 ay için aylık trend (gross/platform/instructorPool).
- Dosya:
app/lib/payout-engine.ts—distributeMonthlySubscriptionPool(db, month, year, monthlySubscriptionPrice)- Abonelik gelirlerinin %40’lık eğitmen havuzunu,
subscription_watch_logstablosundaki izlenme sürelerine göre eğitmenlere dağıtır. - Her eğitmen için havuzdan gelen payı earnings tablosuna
saleType = "subscription_pool_share"ile yazar (cent cinsinden).
- Abonelik gelirlerinin %40’lık eğitmen havuzunu,
Admin tarafında bu bilgiler:
- Finans kartları ile özetlenir (brüt abonelik geliri, platform payı, eğitmen havuzu).
- Abonelik analitik sayfasında aylık trend grafikleri olarak gösterilir.
- “Havuzu Dağıt” aksiyonu ile ilgili ay için
distributeMonthlySubscriptionPooltetiklenir.
KYC Onay Paneli (Eğitmen Kimlik Doğrulama)
Section titled “KYC Onay Paneli (Eğitmen Kimlik Doğrulama)”Liste Sayfası: app/routes/admin.kyc-requests.tsx — /admin/kyc-requests
Detay Sayfası: app/routes/admin.kyc.$userId.preview.tsx — /admin/kyc/:userId/preview
Amaç: Payoneer veya Cenoa ödeme yöntemi seçen eğitmenlerin KYC (Know Your Customer) başvurularını incelemek ve onaylamak/reddetmek.
Liste Sayfası
Section titled “Liste Sayfası”- İstatistik kartları: Bekleyen, onaylanan, reddedilen başvuru sayıları
- Filtre sekmeleri: Tümü / Bekleyen / Onaylanan / Reddedilen
- Tablo: Her başvuru için yasal ad, e-posta, ülke, ödeme yöntemi (logo ile), durum badge’i, tarih
- “İncele” butonu: Detay sayfasına yönlendirir
Ödeme Yöntemi Gösterimi (Logo ile)
Section titled “Ödeme Yöntemi Gösterimi (Logo ile)”<div className="flex items-center gap-2"> {req.payoutMethod === "payoneer" ? ( <img src="/images/payoneer.png" alt="Payoneer" className="h-4 w-auto object-contain" /> ) : req.payoutMethod === "cenoa" ? ( <img src="/images/cenoa.png" alt="Cenoa" className="h-4 w-auto object-contain" /> ) : req.payoutMethod === "stripe_connect" ? ( <img src="/images/stripe.webp" alt="Stripe" className="h-4 w-auto object-contain" /> ) : ( <span className="text-xs font-bold text-slate-600 uppercase">{req.payoutMethod || "-"}</span> )}</div>Detay Sayfası
Section titled “Detay Sayfası”- Eğitmen bilgileri: Ad, e-posta, ülke
- Kişisel bilgiler: Yasal ad, vergi/TC no
- Ödeme bilgileri: Payoneer e-posta veya Cenoa telefon numarası
- Kimlik belgeleri: Ön ve arka yüz görüntüleme (modal ile)
- Onay/Red butonları: Sağ tarafta sabit konum
Action (Form POST):
| intent | Açıklama |
|---|---|
approve | kycStatus = "approved", kycRejectionReason = null → Eğitmen artık ödeme talebi oluşturabilir. |
reject | kycStatus = "rejected", kycRejectionReason = reason → Eğitmen red sebebini görür, tekrar başvurabilir. |
Detaylı bilgi için KYC Onboarding sayfasına bakın.
Bekleyen Ödemeler ve Ödeme Onayı
Section titled “Bekleyen Ödemeler ve Ödeme Onayı”Dosya: app/routes/admin.payouts.tsx
URL: /admin/payouts
Loader: payout_requests listesi; her talep için:
- Eğitmen bilgisi (ad, e-posta, ülke)
- KYC durumu (
kycStatus) - Payoneer/Cenoa bilgisi (
manualPayoutDetails) - Stripe Connect ID (
stripeConnectId) - Onboarding durumu (
isConnectOnboardingCompleted) - Ödeme yöntemi (
payoutMethod)
Doğrulama Yöntemi Gösterimi (Logo ile):
| Doğrulama | Görünüm |
|---|---|
| Payoneer | logo + “Doğrulandı” badge (yeşil) + Payoneer/IBAN bilgileri yeşil kutuda |
| Cenoa | logo + “Doğrulandı” badge (mavi) + Cenoa telefon bilgileri mavi kutuda |
| Stripe Connect | logo + “Doğrulandı” badge (indigo) + Connect ID indigo kutuda |
{/* Ödeme yöntemi gösterimi */}<div className="flex items-center gap-2"> {payout.isPayoneerVerified ? ( <> <img src="/images/payoneer.png" alt="Payoneer" className="h-5 w-auto object-contain" /> <span className="bg-emerald-100 text-emerald-700">Doğrulandı</span> </> ) : payout.isCenoaVerified ? ( <> <img src="/images/cenoa.png" alt="Cenoa" className="h-5 w-auto object-contain" /> <span className="bg-blue-100 text-blue-700">Doğrulandı</span> </> ) : payout.isStripeVerified ? ( <> <img src="/images/stripe.webp" alt="Stripe" className="h-5 w-auto object-contain" /> <span className="bg-indigo-100 text-indigo-700">Doğrulandı</span> </> ) : null}</div>Uyarı Mesajları:
- Stripe Connect + Bekleyen: “Otomatik İşlenebilir: Bu ödeme Stripe Connect ile otomatik olarak işlenecektir.”
- Payoneer + Bekleyen: “Manuel Ödeme Gerekli: Bu eğitmen Payoneer ile doğrulandı. Yukarıdaki Payoneer/IBAN bilgilerine manuel olarak ödeme yapmanız gerekmektedir.”
- Cenoa + Bekleyen: “Manuel Ödeme Gerekli: Bu eğitmen Cenoa ile doğrulandı. Yukarıdaki telefon numarasına Cenoa üzerinden manuel olarak ödeme yapmanız gerekmektedir.”
Action (Form POST):
intent:approve|reject,payoutId: talep ID.- Onay (approve):
- Önce eğitmenin doğrulama yöntemi belirlenir:
const isStripeVerified = instructor?.isConnectOnboardingCompleted ?? false;const isPayoneerVerified = instructor?.kycStatus === "approved" &&!isStripeVerified &&instructor?.payoutMethod === "payoneer";const isCenoaVerified = instructor?.kycStatus === "approved" &&!isStripeVerified &&instructor?.payoutMethod === "cenoa";
- Stripe Connect doğrulamalı (
isStripeVerified): Stripetransfers.createile platform bakiyesinden eğitmen Connect hesabına otomatik transfer;stripeTransferIdkaydedilir. - Payoneer doğrulamalı (
isPayoneerVerified): Stripe Transfer yapılmaz; admin Payoneer/IBAN’a manuel ödeme yapar; sadece durum güncellenir. - Cenoa doğrulamalı (
isCenoaVerified): Stripe Transfer yapılmaz; admin Cenoa telefon numarasına manuel ödeme yapar; sadece durum güncellenir. payout_requests: status =completed,processedAt,stripeTransferId(sadece Stripe için).- İlgili
earnings: status =withdrawn.
- Önce eğitmenin doğrulama yöntemi belirlenir:
- Red (reject):
payout_requests.status = 'rejected'; ilgili earnings status =completed(tekrar talep edilebilir).
Önemli: Payoneer veya Cenoa doğrulamalı eğitmenler için “Onayla” butonuna basıldığında Stripe API çağrısı yapılmaz. Admin önce ilgili ödeme bilgilerine manuel ödeme yapar, ardından “Onayla” ile talebi tamamlandı olarak işaretler.
İade (Refund) Yönetimi
Section titled “İade (Refund) Yönetimi”Dosya: app/routes/admin.refunds.tsx
Loader:
- İade edilmiş kayıtlar:
enrollments+coursesjoin;refundedAt IS NOT NULLverefundStatus = 'completed';enrollments.paidAmountMinor,paidCurrency,stripeCheckoutSessionId,stripePaymentIntentIdseçilir. - Refunded
earningsüzerinden satış anı kuru (rateAtSale) alınır;getCachedRates(env)ile güncel kurlar kullanılır. - Toplam iade tutarı: Tüm iadelerin USD karşılığı toplanır (
totalRefundAmountUsd): satış anı kuru varsaminor/100/rateAtSale, yoksaconvertMinorToUsd(..., rates)ile hesaplanır.
Sayfa: Toplam İade Tutarı (USD) kartı totalRefundAmountUsd ile; her iade kartında İade Tutarı orijinal para biriminde gösterilir: formatPriceWithCurrency(paidAmountMinor, paidCurrency) (TRY/€/$). Tablo — öğrenci, kurs, eğitmen, kayıt tarihi, iade tarihi, iade sebebi. Arama ve filtre. İade işleminin kendisi (Stripe refund vb.) genelde webhook veya ayrı refund aksiyonu ile yapılır; bu sayfa geçmiş iadeleri listeler ve raporlar. Detay için Döviz Gösterimi ve İade Akışları sayfasına bakın.
Admin dashboard (Finans üssü): admin._index.tsx içindeki satışların döviz dağılımı tablosunda “Platform net (USD)” sütunu platformun payını (direkt satışta %5, organikte %55 vb.) USD karşılığında gösterir; hesaplama row.platformShareUsd ile yapılır.
Fiyat Katmanları (Tier Management)
Section titled “Fiyat Katmanları (Tier Management)”Dosya: app/routes/admin.price-tiers.tsx
URL: /admin/price-tiers (admin layout altında).
Amaç: Bölgesel fiyatlandırmada kullanılan price_tiers ve tier_prices tablolarını yönetmek; eğitmenler kurslarına bir tier atar, bu sayfadan global fiyat güncellenir.
Loader
Section titled “Loader”- Admin kontrolü;
priceTierstablosuorderartan sırada; her tier içintierPrices(currency, amount) çekilir. - Dönüş:
tiers— her biriid,name,order,prices: [{ id, tierId, currency, amount }].
Action (Form intent’lere göre)
Section titled “Action (Form intent’lere göre)”| intent | Açıklama |
|---|---|
createTier | Yeni katman: name, order → price_tiers insert. |
updateTier | Katman güncelle: tierId, name, order → price_tiers update. |
deleteTier | Katman sil: tierId → price_tiers delete (cascade ile tier_prices da silinir). |
addPrice | Tier’a fiyat ekle: tierId, currency, amount → tier_prices insert. |
updatePrice | Fiyat güncelle: priceId, amount → tier_prices update. |
deletePrice | Fiyat sil: priceId → tier_prices delete. |
Para birimleri: USD, EUR, TRY, GBP (CURRENCIES sabiti). Her tier için bu para birimlerinde ayrı satır; eksik currency’ler için “Fiyat ekle” formu.
Sayfa Yapısı
Section titled “Sayfa Yapısı”- Başlık: “Fiyat Katmanları” — “Eğitmenlerin kurslarına atayabileceği katmanları ve bölgesel fiyatları buradan yönetin.”
- Yeni katman ekle: Form — name, order; submit → createTier.
- Mevcut katmanlar: Accordion/liste — her tier için ad, sıra, fiyat sayısı; genişletilince:
- Tier ad/sıra güncelleme formu (updateTier).
- Fiyat listesi: currency + amount + “Kaydet” (updatePrice) + “Sil” (deletePrice).
- Eksik currency için “Fiyat ekle” (addPrice) — currency select + amount.
- “Katmanı sil” (deleteTier).
Böylece global fiyat güncellemeleri tek yerden yapılır; kurslar price_tier_id ile bu katmanlara bağlı olduğu için bölgesel fiyatlar (pricing-engine, tier_prices) otomatik güncellenir.
Renk Temaları (Ödeme Yöntemleri)
Section titled “Renk Temaları (Ödeme Yöntemleri)”| Ödeme Yöntemi | Ana Renk | Tema |
|---|---|---|
| Stripe | İndigo (#6366F1) | bg-indigo-50, text-indigo-600, border-indigo-200 |
| Payoneer | Turuncu (#F97316) | bg-orange-50, text-orange-600, border-orange-200 |
| Cenoa | Mavi (#0052FF) | bg-blue-50, text-blue-600, border-blue-200 |
| Konu | Açıklama |
|---|---|
| Kurs moderasyonu | admin.courses: liste (status badge); Onayla → updateCourse(…, published); Reddet → draft. Önizleme: admin.course.$slug.preview. |
| Şikayet yönetimi (DMCA) | admin.reports: kurs bazlı şikayet kartları (total/pending), sıralama; admin.reports.$courseId: detay sayfası, kursu pending_review + isMarketplaceVisible=false yapma, ilgili raporları reviewed işaretleme, eğitmene bildirim gönderme. |
| Finansal yönetim | admin.finances: getAdminStats (gelir, organik/affiliate/abonelik, iade); getAdminSystemStats (bekleyen ödemeler); abonelik havuzu dağıtımı. |
| KYC onayları | admin.kyc-requests: Liste paneli (logo ile ödeme yöntemi gösterimi); admin.kyc.$userId.preview: Detay/onay sayfası; Payoneer/Cenoa doğrulama başvuruları; approve/reject. |
| Bekleyen ödemeler | admin.payouts: liste; Payoneer/Cenoa doğrulamalı → manuel ödeme bilgileri (logo ile) gösterilir; Stripe Connect doğrulamalı → otomatik transfer; approve/reject. |
| İade yönetimi | admin.refunds: iade edilmiş enrollment listesi; toplam iade tutarı USD; kartlarda orijinal döviz (formatPriceWithCurrency). Platform net (USD) sütunu: platform payı. |
| Fiyat katmanları | admin.price-tiers: tier CRUD + tier_prices CRUD (currency/amount); global fiyat güncellemeleri. |
İlgili mimari: Bölgesel Fiyatlandırma (tier_prices kullanımı), Stripe Connect, TR Payout (ödeme onayı) ve KYC Onboarding (kimlik doğrulama).
İlgili Dosyalar
Section titled “İlgili Dosyalar”| Dosya | Açıklama |
|---|---|
app/routes/admin.tsx | Admin layout; session ve role kontrolü; Son hareketler / Tüm bildirimler. |
app/routes/admin._index.tsx | Admin dashboard. |
app/routes/admin.courses.tsx | Kurs listesi, onay/red. |
app/routes/admin.course.$slug.preview.tsx | Kurs önizleme. |
app/routes/admin.reports.tsx | Kurs bazlı şikayet listesi (DMCA, Safe Harbor). |
app/routes/admin.reports.$courseId.tsx | Kurs şikayet detayları, incelemeye alma ve bildirim akışı. |
app/routes/admin.kyc-requests.tsx | KYC liste paneli (logo ile ödeme yöntemi). |
app/routes/admin.kyc.$userId.preview.tsx | KYC detay/onay sayfası. |
app/routes/admin.payouts.tsx | Ödeme talepleri paneli (Payoneer/Cenoa/Stripe logo ile doğrulama bilgileri dahil). |
app/routes/admin.users.tsx, admin.finances.tsx, admin.refunds.tsx, admin.messages.tsx, admin.price-tiers.tsx, admin.subscription.tsx | Alt sayfalar. |
app/routes/api.admin.activities.ts | GET /api/admin/activities. |
app/routes/api.instructor.submit-kyc.ts | KYC başvuru API endpoint’i. |
app/lib/db-queries.ts | getAdminStats, getAdminNotificationCounts, getAdminRecentActivities, getAdminAllActivities. |
app/lib/stripe-connect-payout.ts | processPayoutTransfer (admin onayı sonrası). |
public/images/stripe.webp | Stripe logosu |
public/images/payoneer.png | Payoneer logosu |
public/images/cenoa.png | Cenoa logosu |
logo + “Doğrulandı” badge (yeşil) + Payoneer/IBAN bilgileri yeşil kutuda
logo + “Doğrulandı” badge (mavi) + Cenoa telefon bilgileri mavi kutuda
logo + “Doğrulandı” badge (indigo) + Connect ID indigo kutuda