Fraud & Fraud AI
Akışlar ve Çözümleme

Akışlar ve Çözümleme

Fraud kararı sabit bir kural kümesiyle değil, yayınladığınız akışlarla verilir. Bir akışı işlem tipine göre kapsamlarsınız (kart ödemesi, havale, cüzdan çekimi…); karar isteği geldiğinde sistem eşleşen yayınlanmış akışların hepsini çözümler, koşar ve sonuçları tek karar altında birleştirir.

Bu sayfa çözümlemenin nasıl işlediğini anlatır — yani "isteğim hangi akışlara düştü?" sorusunun cevabını. Uç sözleşmesi için: Karar API'si.

Kuralları tetikleyen uç

Yayınladığınız akış (ve içindeki kurallar) tek bir çağrıyla tetiklenir:

POST /api/v1/fraud/decisions/evaluate
Authorization: Bearer <access-token>

Token'ı Ed25519 imzanızla POST /api/v1/auth/token'dan alırsınız. Gereken yetki: fraud:view_decisions. Ayrıntı ve tam alan sözlüğü: Karar API'si.

İstekteki hangi alan hangi ekseni sürer

Çözümlemeyi siz yönlendirirsiniz — hangi akışların koşacağı, gövdede gönderdiğiniz şu alanlardan türer:

Çözümleme ekseniİstekte nereden gelir
merchantIdToken'ınızdan — gövdede göndermezsiniz
merchantGroupIdsToken bağlamınızdan
subjectTypeGövdedeki işlem tipi (payment, bankTransfer, billPayment … hangi objeyi doldurduğunuz)
productContextGövdede; verilmezse direct_api
integrationModeGövdede
Akış adımetadata.fraudFlowName (ya da liveFraudFlowName / flowName)
curl -X POST "https://api-gateway.lunixi.com/api/v1/fraud/decisions/evaluate" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "bankTransfer": { "amount": 250000, "currency": "TRY", "iban": "TR33…" },
    "customer": { "id": "cust_84213" },
    "productContext": "direct_api"
  }'

Bu çağrı bank_transfer işlem tipine kapsamlanmış akışlarınızın hepsini bulur, koşar ve birleşik kararı döndürür. Yanıtta hangi akışların koştuğu ve hangi kuralların eşleştiği açıklanabilirlik alanlarında ve multiFlow bloğunda gelir — kararın neden verildiğini oradan okursunuz.

Geçmişe dayanan kurallar (hız/velocity, temel çizgi sapması) için ayrıca olay besleyin: POST /api/v1/fraud/events/transactions (tekli) ve /batch (toplu). Karar çağrısı tek bir işleme bakar; "bu müşteri son 24 saatte 12 işlem yaptı" bilgisi olay omurgasından gelir. Bu uçlar Ed25519 imzalıdır, Bearer değil.

Akış hangi eksenlerde kapsamlanır

Bir akış yayınlanırken aşağıdaki boyutlarla daraltılabilir. Boş bırakılan boyut "hepsi" demektir — o eksende her değere uyar.

BoyutÖrnek değerBoş bırakılırsa
merchantIdBelirli bir merchantGlobal akış — tüm merchant'lara uyar
merchantGroupIdsMerchant grubu listesiGrup eşleşmesi aranmaz
flowTypefraud_decision—
subjectTypecard_payment, bank_transfer …Her işlem tipine uyar
integrationModeEntegrasyon biçimiHepsine uyar
productContextdirect_api (varsayılan)Hepsine uyar

subjectType değerleri işlem tipini taşır: card_payment · bank_transfer · eft · fast · crypto_transfer · wallet_deposit · wallet_withdrawal · wallet_payment · wallet_transfer · bill_payment · loan · payout · refund · cash_in · cash_out · international_transfer

Yalnız published ve isActive akışlar çözümlemeye girer. Taslak ya da pasif bir akış, kapsamı ne kadar dar olursa olsun hiç değerlendirilmez. Ayrıca karar yolunda yalnız triggerType='inline_request' akışlar koşar: event, kafka ya da schedule tetikleyicili akışlar kendi tetikleyicilerinde koşar, karar yoluna girmez — aksi hâlde aynı akış iki kez koşardı.

Çözümleme: eşleşen akışların hepsi koşar

Kapsam eksenleri değişmedi — merchantId · merchantGroupIds · flowType · subjectType · integrationMode · productContext (boş kolon = hepsine uyar). Değişen şey seçim adımı: sistem artık en dar kapsamlı tek akışı seçmez. Süzgeçten geçen yayınlanmış akışların hepsi çözülür ve executionMode alanına göre iki şeritten birinde koşar: sync akışlar karar yanıtını üretir, async akışlar kararı bekletmeden arka planda koşar.

Çoklu akış çözümlemesi ve sync/async şeritlerKarar isteği geldiğinde yayınlanmış ve aktif akışlar altı eksende süzülür. Eski davranışın aksine tek akış seçilmez: süzgeçten geçen akışların HEPSİ çözülür. executionMode alanı sync olanlar bağımsız koşar ve sonuçları en şiddetli karar kuralıyla birleştirilerek karar yanıtını üretir; async olanlar kararı bekletmeden kuyruğa alınır ve arka planda koşar.EŞLEŞEN HEPSİKarar isteğiPOST /fraud/decisions/evaluateSüzgeç — 6 eksenpublished + isActiveSync şeritbağımsız koşum · sıfır tabanexecutionMode syncAsync şeritkuyruğa alınır · kararı bekletmezexecutionMode asyncBirleştirmeen şiddetli kazanırskor tavanı · fail-closed · bütçeTek kararmultiFlowAsync koşumadvisory — kararı değiştirmez
Süzgeç aynı kaldı; değişen seçim adımı. Artık kapsam önceliğiyle tek akış seçilmiyor — eşleşen akışların hepsi koşuyor. sync olanlar birleşip kararı üretir, async olanlar kararı bekletmeden arka planda koşar.

Sync şerit: bağımsız koşum, tek karar

executionMode='sync' akışların her biri sıfır taban state ile bağımsız koşar: akışların sırası sonucu etkilemez, bir akış diğerinin skorunu ya da reason code'larını görmez. Koşum bitince sonuçlar tek karar altında birleştirilir:

BoyutBirleştirme kuralı
KararEn şiddetli kazanır: allow < force_3d < review < block
SkorAkış başına tavan (varsayılan 100) + toplam tavan (varsayılan 250). Tavan aşıldığında yanıtta multi_flow_score_capped reason code'u görünür
Akış hatasıDiğer akışlar devam eder; hata veren akış skippedFlows'a girer ve karar en az review seviyesine yükselir (flow_failed_fail_closed:<akış-adı> reason code'u). Mevcut bir block asla aşağı çekilmez
Süre bütçesiİstek başına varsayılan 25 sn. Bütçe dolarsa kalan akışlar koşulmaz ve skippedFlows'ta budget_exceeded nedeniyle listelenir

Üç seviyeli zaman sınırı

Süre bütçesi tek katman değildir; iç içe üç sınır vardır ve dıştaki içtekini bağlar:

SeviyeVarsayılanAşılırsa
Düğüm8 snO düğüm hata verir
Akış20 snO akış atlanır, skippedFlows'a girer
İstek (tüm akışlar)25 snKalan akışlar koşulmaz, budget_exceeded

Bir düğümün kendi timeoutMs ayarı varsa o kullanılır — ama akış deadline'ını aşamaz; kalan süre neyse düğüm onunla sınırlanır.

🚫

Düğüm zaman aşımı, düğüm hatasıdır. continueOnError tanımlıysa hata dalına gider; tanımlı değilse akışın fail-closed duruşu devreye girer ve karar en az reviewe yükselir.

Pratik sonucu: http_request ya da grpc_call düğümünde yavaş bir dış servis, yalnız o düğümü değil kararın tamamını etkileyebilir. Dış çağrı yapan düğümlere kendi timeoutMs'ini vermek, bu davranışı sizin kontrolünüze alır.

⚠️

Koşulmamış akış allow değildir. Bütçe nedeniyle atlanan akış, koşup temiz çıkan akıştan skippedFlows alanıyla ayırt edilir — izleme kurarken budget_exceeded nedenini ayrı sayın.

Açıklanabilirlikteki flowPath artık akış-öneklidir: her adım flow:<akış-adı>/<düğüm-id> biçiminde gelir — hangi düğümün hangi akışa ait olduğunu yanıttan okursunuz.

Async şerit: kararı bekletmez

executionMode='async' akışlar karar yanıtını bekletmez: koşum kuyruğa alınır, yanıtta asyncFlows listesinde queued durumuyla görünür ve arka planda aynı motorla koşar. Sonuç koşum kaydına yazılır — ayrıntı için aşağıdaki Async sonuçların iletimi bölümüne bakın.

Async sonuç advisory'dir: senkron verilmiş kararı geriye dönük değiştirmez. Akışın case açma ve aksiyon gibi yan etkileri ise normal işler.

Yanıttaki multiFlow bloğu

Karar yanıtına additive bir alan eklendi — mevcut alanlar değişmedi:

{
  "multiFlow": {
    "enabled": true,
    "executedFlows": ["kart-hiz-kurallari", "cihaz-itibari"],
    "skippedFlows": [
      { "name": "agir-analiz", "reason": "budget_exceeded" }
    ],
    "asyncFlows": [
      { "name": "vaka-taramasi", "status": "queued" }
    ]
  }
}

gRPC telinde aynı blok multiFlowJson alanında JSON string olarak taşınır.

Belirli bir akışı adıyla çağırma

İstek metadata içinde akış adı gönderirseniz çözümleme doğrudan o ada kilitlenir — çoklu çözümleme o istekte yalnız adı verilen akışı koşar:

{ "metadata": { "fraudFlowName": "yuksek-riskli-havale" } }

Kabul edilen anahtarlar: liveFraudFlowName, fraudFlowName, flowName. Bu, kanarya/deneme akışlarını sınamanın yoludur — üretimde varsayılanı ezmek için kullanmayın.

Async sonuçların iletimi

executionMode='async' akışların sonucu koşum kaydına yazılır.

Bu sonuçların size iletimi platform webhook olaylarıyla yapılacaktır — çok yakında. Platform webhook'larının kurulumu, imza doğrulaması ve yeniden deneme davranışı için: Webhook kurulumu.

Switch düğümünde eksik/bozuk veri: condition ve op farkı

Switch düğümünde bir case iki biçimde yazılabilir ve ikisinin eksik/bozuk veri (örneğin sayı beklenen alanda metin) davranışı bilinçli olarak farklıdır:

Case biçimiEksik/bozuk operand olursaNeden
condition (tam kural DSL'i)Case eşleşmiş sayılır ve o dala gidilir (fail-closed)Kural motorunun güvenlik doktrini: tip oynanmış bir istek block yönlü kontrolü sessizce atlatamaz
Basit op değer eşleme (eq, gt, in...)Case atlanır, akış default dala düşer ve indeterminateCases alanında görünür (fail-safe)Yönlendirme amaçlı ucuz eşlemede eksik veri akışı kilitlemesin, ama görünür olsun

Akış yazarı kuralı: karar-kritik (block yönlü) kontrolü condition ile yazın — fail-closed davranış istersiniz. Yönlendirme amaçlı ucuz eşlemeyi op ile yazın — eksik veri default'a düşsün ve indeterminateCases ile görünür olsun.

Gelen webhook tetiği (triggerType: webhook)

webhook tetikli bir akış, bir event-stream bağlantı profili üzerinden dışarıdan tetiklenir. Zincir:

  1. Panelden bir bağlantı profili tanımlanır (kaynak: webhook; imza secret'ı profildedir).
  2. Dış sistem şu adrese POST atar: POST /api/v1/fraud/database-events/{connectionProfileId}/webhook/{routingKey} — imza x-event-signature, zaman damgası x-event-timestamp header'ında taşınır.
  3. İmza doğrulanır (HMAC + zaman penceresi); ardından triggerType değeri webhook veya event olan ve triggerConfig.webhookPath değeri routingKey ile eşleşen yayınlanmış akışlar koşturulur.

Bu gelen tetik yalnız akışı çalıştırır; imza secret'ı bağlantı profilinde tutulur.

executionMode rehberi

ModNe için
syncKarar anını etkileyen hızlı kontroller — hız kuralları, eşikler, liste kontrolleri
asyncAğır analiz, raporlama ve vaka akışları — karar gecikmesine girmemesi gereken her şey

Hiç akış eşleşmezse

🚫

Yapılandırılmamış bir merchant sessizce allow almaz. Hiçbir capability paketi, kural grubu ve akış çözümlenemezse istek fraud.decision.unconfigured sebep koduyla işaretlenir ve politika varsayılanına düşer (FRAUD_UNCONFIGURED_DECISION, varsayılan review).

Bu bilinçli bir tasarım: önceki davranışta yapılandırılmamış merchant ile açıkça temiz çıkmış bir ödeme birbirinden ayırt edilemiyordu. Entegrasyonunuzu kurarken fraud.decision.unconfigured sebep kodunu izleyin — akışınız yayına girmediyse bunu üretimde görürsünüz.

Capability paketleri

Akışlar tek başına da koşar, ama üzerlerinde bir capability paketi katmanı vardır: paket, bir karar için hangi yeteneklerin hangi sırayla ve hangi hata politikasıyla çalışacağını tarif eder ve gerektiğinde birden çok akışı orkestre eder.

DurumNe koşar
Merchant için capability paketi çözümlendiPaket koşar; akışları o orkestre eder
Paket yokEşleşen yayınlanmış akışlar çoklu çözümlemeyle doğrudan koşar
İkisi de yokfraud.decision.unconfigured → politika varsayılanı

Akış çalışırken hata alırsa karar fail-closed davranır: o ana kadar toplanan kanıt (capability, kural grubu, canlı sinyaller) geçerli sayılır ve karar en az review seviyesine yükseltilir — mevcut bir block asla aşağı çekilmez.

Akış içinde kendi kodunuzu çalıştırmak

Kural düğümleri bir eşiği veya karşılaştırmayı ifade etmeye yeter; ama bazı politikalar kural diliyle yazılamaz — bir skorun kendi formülünüzle hesaplanması, bir dış yanıtın ayrıştırılması, iş kuralına özgü bir dönüşüm. Bunun için akışa script düğümü koyarsınız ve kendi JavaScript'inizi çalıştırırsınız.

Script varlığının yaşam döngüsü

AşamaNe olur
TaslakKaynak kodu, giriş/çıkış şeması, süre ve bellek tavanı tanımlanır
Statik analizYayın öncesi zorunlu kapı. import / export, require(), eval gibi desenler bloklanır. Sonuç: clean · warning · blocked
YayınYalnız analizi geçen kod yayınlanabilir; kaynak özeti (sourceHash) kaydedilir
Devre dışıYayından kaldırılır; akış onu çağıramaz

Nasıl çalışır

Kod, fraud servisinin içinde değil, ayrı bir yürütme servisinde koşar: gerçek bir V8 izolatı (isolated-vm) içinde, kendi heap tavanıyla, kendi süre sınırıyla. İzolatlar belirli sayıda işten sonra geri dönüştürülür, çıktı ve log boyutu tavanlanır.

⚠️

Script'iniz ağa çıkamaz, dosya sistemine erişemez, başka bir modül yükleyemez. Dışarıdan veri gerekiyorsa bunu akışın kendi düğümleriyle (http-request, database-lookup, redis-get) getirir, script'e girdi olarak verirsiniz.

İki mod

ModKullanım
sync_transformSaf dönüşüm — girdi al, değer döndür. Sıcak yolda tercih edilir
async_scriptBeklemeli işlem gerektiren, daha uzun soluklu mantık

Her çalıştırma denetime yazılır: success · failed · timeout. Süre tavanını aşan bir script akışı kilitlemez — hata olarak döner ve akışın fail-closed duruşu devreye girer.

İlgili