Cüzdan
Panel Kılavuzu
Operasyonlar & Müdahale

Panel — Operasyonlar & Müdahale

Bu uçları kim çağırır?Merchant panel
Taban yol
/api/panel/v1/wallet
Kimlik
Panel oturumu (JWT) — Authorization: Bearer <panel access token>. Token panel girişinden gelir; s2s imza anahtarı bu uçları AÇMAZ.
Yetki
RBAC izin kodu: wallet:operation:read · wallet:operation:interveneDört-göz: isteği yapan ile onaylayan aynı kişi olamaz — rol kapısıyla değil, kimlik karşılaştırmasıyla zorlanır.
Çapraz yüzey
Yalnız OKUMA kısmen var: GET operations, GET operations/:id, /receipt, GET topups/:id, GET withdrawals/:id s2s API'de de vardır; s2s'teki POST topups/:id/refund uç sizin kendi onay akışınızla çalışır. Dört-göz talep ve onay uçlarının s2s'te karşılığı YOKTUR: */intervention-requests, cash-out/:id/hold-requests, suspense-funds/:id/match-requests|return, topups/:id/refund-requests, GET suspense-funds, ops-health, bill-payments, operations/:id/receipt.pdf.

Bu bölüm iki işi yapar: izleme (ne oldu) ve müdahale (takılan paraya ne yapılacak). Müdahaleler doğrudan yürütülmez: bir operatör talep açar, başka bir yetkili onaylar.

İzleme

GET operations                      # filtre: endUserId, walletAccountId, status, operationType
GET operations/:id
GET operations/:id/receipt
GET operations/:id/receipt.pdf
GET operations/export
GET topups/:id
GET withdrawals/:id
GET bill-payments
GET bill-payments/:id

Operasyon alanlarının anlamı: Operasyonlar.

Destek görüşmesinde önce durum, sonra failureCode ve fraudDecision alanlarına bakın. Bu üçü, "işlemime ne oldu" sorusunun cevabını neredeyse her zaman verir.

Ops-health — takılı ve askıdaki paranın tek bakışta özeti

GET ops-health

İzin: wallet:operation:read

Liste ekranındaki sayaçlar yalnız o an çekilen sayfayı sayar; ops-health aynı soruyu sunucu tarafında, kiracı genelinde cevaplar. Operasyon ekranında gördüğünüz KPI ile bu ucunuz sayısı farklıysa, otoriter olan budur.

AlanNe söyler
operations.postingTotal / postingStuckPOSTING durumunda bekleyen ve eşiği aşmış operasyonlar
operations.oldestPostingAgeSecondsEn eski POSTING kaydın yaşı
operations.awaitingReconOperatör çözümü bekleyen mutabakat kuyruğu
operations.heldRisk/uyum kilidiyle tutulan operasyonlar
operations.reversingGeri alma ya da kart yükleme iadesi süren operasyonlar; sistem bunları kendisi sonuçlandırır
operations.failedRecentSon 24 saatteki FAILED sayısı
suspense.unmatched + unmatchedAmountMinor + oldestUnmatchedAgeSecondsEşleşmemiş gelen para
cashout.held + heldAmountMinorİncelemede tutulan nakit çekim kodları
bulk.processingBatchesYarım kalmış toplu ödeme partileri

Yanıt ayrıca generatedAt, postingStuckMinutes (varsayılan 5) ve failedLookbackHours (24) alanlarını taşır.

⚠️

Bu ucu bir izleme paneline bağlayın. postingStuck ve oldestPostingAgeSeconds birlikte artıyorsa para yolu bir yerde takılmıştır; kullanıcı şikâyeti gelmeden önce burada görünür.

Tutarlar minor-unit stringtir — sayıya çevirip toplamayın.

Dört-göz talepleri

Paraya dokunan her müdahale iki adımlıdır:

  1. Talep. Bir operatör müdahaleyi talep eder. Talep kalıcı olarak kaydedilir; talep eden, oturumunuzdan alınır.
  2. Onay. Talebi açandan farklı bir yetkili talebi onaylar. İşlem ancak bu anda yürütülür.

İstek gövdesinde kişi alanı yoktur. Gövdeye requesterPrincipal ya da approverPrincipal eklenirse istek 400 ile reddedilir. Talebi açan kişi kendi talebini onaylamaya çalışırsa istek 403 WALLET_FOUR_EYES_VIOLATION ile reddedilir; karşılaştırma talep kaydındaki kalıcı "talep eden" alanıyla yapılır.

GET  intervention-requests                 # status, kind, targetId, limit, cursor
GET  intervention-requests/:id
POST intervention-requests/:id/approve     # { reason? }
POST intervention-requests/:id/reject      # { reason }
Talep türü (kind)Talebi açan uçTalep izniOnay/ret izni
OPERATIONPOST operations/:id/intervention-requests · POST withdrawals/:id/intervention-requestswallet:operation:intervenewallet:operation:intervene
CASHOUT_HOLDPOST cash-out/:id/hold-requestswallet:operation:intervenewallet:operation:intervene
SUSPENSE_MATCHPOST suspense-funds/:id/match-requestswallet:operation:intervenewallet:operation:intervene
TOPUP_REFUNDPOST topups/:id/refund-requestswallet:operation:intervenewallet:operation:intervene
KYC_OVERRIDEPOST end-users/:id/kyc-level/override-requestswallet:enduser:kyc-overridewallet:enduser:kyc-approve
LEGAL_HOLD_RELEASEPOST legal-holds/:id/release-requestswallet:legal-hold:managewallet:legal-hold:approve

Talep durumları:

DurumAnlamı
PENDINGOnay bekliyor. Aynı kayıt için aynı türden yalnız bir açık talep olabilir; ikinci talep 409 WALLET_INTERVENTION_REQUEST_CONFLICT alır
APPROVEDOnaylandı, işlem yürütülüyor. Kısa süren bir ara durumdur
EXECUTEDOnaylandı ve işlem uygulandı (decidedBy, executedAt, resultRef)
FAILEDOnaylandı ama işlem uygulanamadı; failureCode ve failureMessage nedenini söyler. Talep yeniden onaylanmaz, gerekirse yeni talep açın
REJECTEDReddedildi; para hareketi olmadı. Talebi açan, karar izni varsa kendi talebini bu yolla geri çekebilir

Onaydan sonra sistem bir arıza nedeniyle yürütmeyi tamamlayamazsa talep APPROVED durumunda kalmaz: birkaç dakika içinde otomatik olarak ele alınır. İşlem uygulanmamışsa onaylayanın kaydıyla uygulanır; uygulanmışsa talep EXECUTED olarak kapanır. İşlemin bu taleple uygulandığı kanıtlanamazsa talep FAILED olur ve failureCode: WALLET_INTERVENTION_OUTCOME_UNVERIFIED taşır. Bu durumda kaydın geçmişine bakıp gerekiyorsa yeni talep açın.

Ön koşullar iki kez denetlenir: talep açılırken (aksiyon kaydın o anki durumunda anlamlı mı) ve onay anında (durum o arada değişmiş olabilir). Talep açmak parayı hareket ettirmez.

Panelde onay kuyruğu Cüzdan → Operasyon → Dört-Göz Onayları ekranındadır. Kendi açtığınız talepte Onayla düğmesi pasiftir ve nedeni yazılıdır.

Askıda fon

Hesabınıza gelen ama sahibi çözülemeyen para askıya alınır.

GET  suspense-funds                       # status ile filtre
POST suspense-funds/:id/match-requests    # { instructionId, reason } — dört-göz talebi
POST suspense-funds/:id/return            # { reason }
İşlemNe yapar
EşleştirParayı bir yatırma talimatına bağlama talebi açar; onaylandığında kullanıcıya kredilenir
İade etParayı gönderene geri gönderir
⚠️

Eşleştirme para hareketidir ve geri alınması zordur. Talebi onaylamadan önce gönderen bilgisi ile talimat sahibinin tutarlı olduğunu doğrulayın; şüphedeyseniz talebi reddedip parayı iade edin. Yanlış kişiye kredilenmiş bir havaleyi geri almak, kullanıcı parayı harcadıysa mümkün olmayabilir.

Operasyon ve çekim müdahalesi

Takılmış veya tutulmuş bir operasyonu sonuçlandırmak için talep açın. Çekim de bir operasyondur; iki uç aynı talep türünü (OPERATION) üretir.

POST operations/:id/intervention-requests
POST withdrawals/:id/intervention-requests
AlanZorunluKural
action✅reject | approve | force_reverse | recon_close
reason✅3–1000 karakter
AksiyonKabul ettiği durumOnaylandığında
rejectHELD, INITIALIZED, CHALLENGEDFAILED — bloke fon serbest bırakılır
approveHELDRisk incelemesinden geçen para çıkışı yürütülür
force_reverseCOMPLETED, AWAITING_RECONPara yolu tersine çevrilir — aşağıya bakın
recon_closeAWAITING_RECONCOMPLETED — banka parayı gönderdi kabul edilir
🚫

Onaylandığında dört aksiyon da geri alınamaz. Yanlış aksiyonun "geri alma" ucu yoktur; düzeltme yeni bir para hareketi gerektirir.

reason zorunludur ve 3 karakterden kısa olamaz — ama asıl mesele uzunluk değil: bu alan denetim kaydıdır ve "test", "ok" gibi değerler bir denetimde hiçbir şey açıklamaz.

⚠️

AWAITING_RECON bir operasyonu banka tarafındaki gerçek sonucu görmeden çözmeyin. "Muhtemelen gitmemiştir" diyerek geri almak, para gerçekten gittiyse çift ödemeye yol açar.

Geri alma (force_reverse) nasıl ilerler

Geri alma, para hareketinden önce operasyonu REVERSING durumuna alarak başlar. Bu sahiplenmeyi kazanamayan eşzamanlı bir işlem (ör. aynı anda gelen banka sonucu ya da başka bir müdahale) defter kaydına hiç ulaşmaz; para yalnız bir kez geri alınır.

Defterin cevabıOperasyonun durumuNe yapmalısınız
Geri alma kabul edildiREVERSEDHiçbir şey; wallet.*.reversed olayı gönderilir
Geri alma reddedildi (ör. alıcının bakiyesi yetersiz)AWAITING_RECON (failureCode: WALLET_REVERSAL_FAILED)Para hareket etmedi. Nedeni giderip geri almayı yeniden talep edebilir ya da banka sonucuna göre recon_close talep edebilirsiniz
Sonuç belirsiz (zaman aşımı)REVERSINGBekleyin. Sistem geri almayı aynı kayıt anahtarıyla otomatik olarak yeniden dener ve sonuçlandırır; ikinci bir geri alma oluşmaz

Otomatik banka iadesi (banka çekimi reddettiğinde) de aynı sırayı izler. Banka reddi ile eşzamanlı bir recon_close onayı çakışırsa yalnız biri uygulanır ve çelişki, platform izlemesine para-bütünlüğü uyarısı olarak düşer.

Tutulan nakit çekim kodu

POST cash-out/:id/hold-requests           # { action, reason }

Risk incelemesine takılmış (HELD) bir nakit çekim kodu için talep açar. Aksiyon kümesi farklıdır:

AlanZorunluKural
action✅approve | reject
reason✅3–1000 karakter
AksiyonOnaylandığında
approveHELD → ACTIVE; kod kendi TTL'i içinde kullanılmaya devam eder
rejectHELD → RELEASED; bloke fon kullanıcıya iade edilir

Yükleme iadesi

POST topups/:id/refund-requests           # { reason }

Tamamlanmış bir kart yüklemesinin iadesi için talep açar; iade onay anında yürütülür.

⚠️

Talebi onaylamadan önce kullanıcının bakiyesini kontrol edin — para harcanmışsa cüzdan borçlandırılamaz ve iade yürütülmez.

Komisyon

GET business-accounts/:id/commission
PUT business-accounts/:id/commission

İşletme hesabının komisyon yapılandırması. Şema sürümleme: Panel — Limit & Ücret Şemaları.

Müdahale disiplini

  1. Önce okuyun, sonra dokunun. Operasyon geçmişi (durum geçişleri) neredeyse her soruyu cevaplar.
  2. Gerekçe yazın. reason alanı denetim kaydıdır; sonradan "neden yapılmış" sorusunun tek cevabı.
  3. Belirsizde bekleyin. AWAITING_RECON bir karar değil, bir bekleme durumudur.
  4. Onaylamadan önce talebi okuyun. Talebi açan ve onaylayan oturumlardan alınır ve aynı kişi olamaz; ikinci gözün değeri, onaylayanın talebi gerçekten incelemesindedir.