Sistem

Mimari

api-yos, iki ayrı uygulama ile bir ortak veritabanından oluşur ve karşı tarafta bir banka (HHS) ile konuşur. Kullanıcı bir şey isteyince (örneğin "bakiyem ne?") o istek birkaç durak arasında dolaşır. Aşağıda kim kiminle nasıl konuşuyor, adım adım ve sade dille anlatılıyor.

Kuşbakışı

Önce büyük resme bakalım. Soldan sağa doğru: kullanıcı, kullanıcının konuştuğu web servisi, ortak veritabanı, arka planda çalışan işçi ve en sağda banka. Her kutu bir görevi üstlenir; oklar da verinin hangi yönde aktığını gösterir.

Kullanıcı
(tarayıcı / mobil)
Public API
apps/api · :8444
MSSQL
paylaşımlı DB
Batch İşçi
apps/batch · :8445
Banka (HHS)
api-hhs · :8443
Public API — sadece DB okur Batch — bankaya bağlanan tek taraf MSSQL — iki uygulama ortak HHS — banka / simülatör
Altın kural: Public API bankaya asla doğrudan bağlanmaz — banka işini her zaman Batch işçi yapar. API'nin bu işi Batch'e devretmesinin iki yolu vardır. Bazı akışlar (ödeme gönderimi, rıza iptali, periyodik yenileme) asenkron ilerler: API veritabanındaki "niyet kutusuna" (SyncIntent) bir not bırakır, işini bitirir; Batch bu notu sonra görüp bankayla konuşur ve sonucu veritabanına yazar. Bazı akışlar ise (rıza oluşturma, yetkilendirme tamamlama, canlı okuma) senkron ilerler: API, Batch'e doğrudan bir iç çağrı (internal RPC) yapar ve sonucu bekler — kullanıcı yanıtı hazır olana kadar bekletilir. Her iki durumda da bankayla yalnızca Batch konuşur; bankaya çıkan tek kapı vardır ve güvenlik tek yerde toplanır.

İki uygulama, iki görev

Neden tek uygulama değil de iki tane? Çünkü iki iş çok farklı: biri kullanıcıya hızlı yanıt vermek zorunda, diğeri bankayla yavaş ve dikkatli konuşuyor. Bu ikisini ayırmak, birinin yavaşlığı diğerini yavaşlatmasın diye önemli. Aşağıda her uygulamanın ne yaptığı var.

Public API (apps/api)

Kullanıcının konuştuğu web servisi. Hızlı olması gerekir, o yüzden hep yakındaki veritabanından okur.

  • Uygulama anahtarı (X-App-Key) + kullanıcı kimliği (userKey + customerNo) ile kaydeder, kullanıcıya bir JWT token (kimliği kanıtlayan dijital bilet) verir
  • Hesap, kart, işlem ve ödeme uçlarını (endpoint) sunar — uygulamanın konuştuğu adresler
  • Sadece MSSQL veritabanını okur-yazar; bankaya sıfır bağlantı kurar
  • Banka işini Batch'e devreder: kimini "niyet kutusuna" (SyncIntent) not olarak yazar, kimini de Batch'e senkron iç çağrıyla (RPC) yaptırıp sonucu bekler
  • Bankadaki onay tamamlanınca gelen geri dönüşü (callback — banka bize haber verir) karşılar; yetkilendirmeyi Batch'e senkron iç çağrıyla tamamlatır (token değişimi + hesap/kart çekimi aynı anda yapılır) ve ancak sonra kullanıcıya yanıt döner / onu yönlendirir

Batch İşçi (apps/batch)

Bankayla konuşan tek taraf. Arka planda çalışan bir işçi (Hangfire worker); kullanıcı onu doğrudan göremez.

  • Dışarıya açık web servisi yoktur; yalnızca arka planda, kimseye görünmeden çalışır
  • Niyet kutusundaki notları sırayla (ilk gelen ilk işlenir) alır ve yerine getirir
  • Bankaya mTLS (iki tarafın da kimliğini sertifikayla kanıtladığı güvenli bağlantı) ve imzalı (JWS) istek atar
  • Bankadan gelen hesap, bakiye, kart ve işlem verisini veritabanına yazar
  • Belirli aralıklarla verileri otomatik tazeleyen periyodik işleri yürütür
Küçük örnek: Kullanıcı ilk kez bir bankaya bağlanmak istediğinde, kullanıcı bankada onayı verip geri döndüğü an (callback), Public API yetkilendirmeyi Batch'e senkroniç çağrıyla tamamlatır: Batch bankayla mTLS üzerinden konuşur, token değişimini yapar ve hesap/kartları hemen aynı anda çeker. Böylece kullanıcı başarı ekranına düştüğünde bağlantısı "Connected" (bağlı) ve hesapları/kartları çoktan dolmuş olur — sonraki bir bakışı beklemesine gerek kalmaz. Asenkron (niyet kutusu üzerinden ertelenen) yol yalnızca bu senkron tamamlama başarısız olursa devreye giren yedek yoldur.

Neden bu ayrım? (Clean Architecture)

Her uygulama, iç içe geçmiş katmanlara bölünmüştür. Bunu bir soğanın halkaları gibi düşünün: en dış halka HTTP isteğini veya işçinin tetiklendiği anı karşılar, en iç halka ise asıl iş kurallarını (para nasıl transfer edilir, rıza ne zaman geçerlidir) barındırır. Önemli kural şudur: içerideki katman dışarıyı bilmez. Yani iş kuralları, verinin hangi veritabanından geldiğini ya da hangi web çerçevesinin kullanıldığını umursamaz. Bunun faydası büyük: dış dünya değişse bile (veritabanı değişse, arayüz değişse) çekirdek kurallar aynı kalır ve kod rahatça test edilir.

KatmanProjeNe yapar
SunumFinevoConnect.Yos.ApiDış dünyanın kapısı: HTTP controller'ları, araya giren kontroller (middleware), giriş noktası
UygulamaFinevoConnect.Yos.Applicationİş akışları — her özellik için bir servis. Örneğin ödeme emri işleri PaymentOrderService içinde yaşar
AltyapıFinevoConnect.Yos.InfrastructureDış dünyaya dokunan her şey: veritabanı erişimi, güvenlik, bağlantılar
Alan (Domain)FinevoConnect.Yos.Shared.DomainVarlıklar, iş kuralları ve sabitler — tüm gerçeğin tek kaynağı, en iç halka
KalıcılıkFinevoConnect.Yos.Shared.PersistenceVeritabanı şeması (tabloların yapısı) — iki uygulama da aynı şemayı paylaşır

Paylaşımlı köprüler

İki uygulama birbiriyle doğrudan telefonla konuşmaz; aralarındaki her mesajlaşma ortak veritabanı üzerinden olur. Aşağıdaki iki köprü, bu sessiz haberleşmenin nasıl güvenli ve güvenilir kaldığını anlatır.

SyncIntent (niyet kutusu)

API bir banka işi gerektiğinde, bu işi "niyet" olarak veritabanına yazar. Önemli olan, bu yazma işinin asıl veri değişikliğiyle aynı anda (aynı veritabanı işlemi/transaction içinde) olmasıdır — yani ya ikisi birden olur ya hiçbiri, arada kayıp yaşanmaz. Batch bu kutuyu gelme sırasına göre (FIFO — ilk giren ilk çıkar) okur, işi yapar ve "işlendi" diye işaretler. Her iş en az bir kez yapılır; aynı işin iki kez yapılması ise ayrıca engellenir. Örneğin ödeme emri iki kez işlenip para iki kez gitmez.

Paylaşımlı şifreleme anahtarı

Bankadan alınan erişim token'ları ve kullanıcının kişisel verileri (örneğin kimlik bilgisi) veritabanında açık değil, şifreli durur. Batch bu verileri yazarken şifreler, API okurken çözer. İkisinin de aynı kilidi açabilmesi için ortak bir anahtar halkasını ("yos-shared") paylaşırlar. Eğer iki taraf farklı isimde anahtar kullanırsa çözme işlemi bilerek başarısız olur — bu, veriyi yanlış elden korumak için konmuş bir güvenlik önlemidir.

Karşı taraf: HHS (banka)

HHS, gerçek hayatta kullanıcının hesabının bulunduğu bankadır (standart adıyla ASPSP). Geliştirme ve testte gerçek bankaya bağlanmak yerine api-hhs adlı bir simülatör kullanılır; bu simülatör tıpkı gerçek banka gibi davranır. Batch, bankaya mTLS (iki tarafın da sertifikayla kimliğini kanıtladığı bağlantı) ile bağlanır ve gönderdiği mesajların gövdesini JWS ile imzalar — böylece banka mesajın yolda değiştirilmediğinden emin olur. Banka da yanıtlarını aynı şekilde imzalar; imzasız ya da imzası doğrulanamayan bir yanıt gelirse Batch onu reddeder, çünkü sahte olabilir. Kullanıcının bankada verdiği onay (GKD — Güçlü Kimlik Doğrulama) tamamlanınca, banka bunu Public API'ye bir "callback" (geri arama) ile bildirir; yani "kullanıcı onayladı" haberini bize geri yollar.