İş ortağı yüzeyi sözleşmesi Bakiye PA-32
Bakiye yükleme
POST/api/partner/v1/balance/top-ups
> Künye: TASK-317; REQ-021 KK-10, DEC-254, DEC-285.
Amaç
Hesabın bakiyesini yüklemek (REQ-021 KK-10'un iş ortağına verdiği tek yazma kalemi).
Yetki
İki kademeli kimlik: X-App-Key (hangi iş ortağı) + Authorization: Bearer (hangi hesap adına). Hesap anahtarı partner-api yeteneği taşır ve tek başına /api/v1e giremez; cookie oturumu bu yüzeye giremez.
Başarı 201
yükleme kaydı oluşur.
Hatalar
422, 403, 502; ayrıca 401 (uygulama ya da hesap anahtarı yok / tanınmıyor / iptal / süresi dolmuş - dört neden tek gövdeye düşer ve ayırt edilemez), 403 (iş ortağı askıda ya da hesap anahtarının kökeni sunulan uygulama anahtarıyla eşleşmiyor), 429 (oran limiti, Retry-After).
Hesap sahibi adına ön ödemeli bakiye yükleme oturumu açar. Para hesap sahibinin cüzdanına girer ve fatura ona kesilir: "kimin adına" sorusunun cevabı gövdeden değil ikinci kademe kimlikten gelir. Uç para hareketi yapmaz - kredi, imza doğrulanmış callback/webhook yolundan gelir ve o yol bu görevde hiç değişmedi.
İstek
| Alan | Kural |
|---|---|
amount_minor |
zorunlu, tam sayı kuruş; yapılandırılmış asgari ve azami tutar aralığı. Boolean true reddedilir (RISK-029) |
return_urls |
opsiyonel nesne; anahtarları kapalı sözlükten: success, cancel, failure. Sözlük dışı anahtar 422 |
return_urls.{amaç} |
opsiyonel https adres (≤2048). İş ortağının onaylı adres listesinde aynı amaçla birebir bulunmak zorundadır |
`save_card` bu yüzeyde YOKTUR, ama istek bu yüzden REDDEDİLMEZ
Ayrım taşıyıcıdır, çünkü tek bir sözcük iki ayrı şeyi anlatabiliyor: kayıtlı kart YETENEĞİ kapalı yetki kümesinin dışındadır (DEC-285), alanı göndermek ise isteği bozmaz. Ölçülen davranış tektir: save_card gönderilsin ya da gönderilmesin yanıt 201dir, alan yok sayılır ve iyzico oturumuna cardUserKey geçirilmez. Değer istekten okunmaz, kodda SABİTTİR
Alan doğrulama kurallarına hiç girmediği için değeri de denetlenmez: boolean olmayan bir değer göndermek bile isteği bozmaz, yanıt yine 201dir. Bu, alanın kapalı yetki kümesi dışında kalmasının doğrudan sonucudur ve mekanik olarak bağlıdır
201'i "kart kaydedildi" diye okumayın
Kart kaydedilmez ve barındırılan ödeme sayfasında kayıtlı kart gösterilmez. Kayıtlı kart yolu yalnız hesap sahibinin kendi SPA oturumundaki yükleme ucunda vardır; iş ortağı yüzeyi o yeteneği taşımaz ve iş ortağı hesap sahibi adına kart kaydedemez.
Karşılaştırma, çünkü bu uçta "reddedilir" GERÇEK bir davranıştır
return_urls sözlüğü KAPALIDIR ve sözlük dışı bir anahtar 422 verir. save_card o sınıfa girmez: sessizce düşer.
Yanıt - 201 + {checkoutFormContent, paymentPageUrl, top_up_id} (SPA ucuyla aynı gövde). 502: iyzico oturumu açılamadı (ham sağlayıcı hatası sızmaz). 422: tutar ya da dönüş adresi.
DÖNÜŞ ADRESİ - AÇIK YÖNLENDİRME SINIRI
Ödemesini az önce tamamlamış bir kullanıcıyı saldırganın adresine götürmek, kimlik avının en ikna edici biçimidir. Bu yüzden hedef istekten serbestçe alınmaz; kapı iki kademelidir ve sıra tasarımdır:
1. Beyaz liste (yetki): adres + amaç, iş ortağının kendi listesindeki satırla birebir aynı mı (DEC-285)? Köken ya da yol öneki eşleşmesi reddedildi: iş ortağının kendi kökenindeki herhangi bir açık yönlendirme ya da kullanıcı içeriği yolu bu kapıyı dolaylı olarak açardı. 2. Giden adres kapısı (şekil): adres genel (public) bir alan adına çözümleniyor mu? Webhook aboneliğindeki kapının ikinci kullanımıdır; yeni bir doğrulama noktası açılmaz (KK-4).
Sıra tersine çevrilemez: kapı alan adını DNS'te çözer, önce koşsaydı kimliği doğrulanmış bir çağıran keyfî bir host için sunucuya DNS sorgusu yaptırabilirdi. İki kapı aynı şeyi korumaz - beyaz liste saldırganın seçtiği adresi, kapı ise onaylanmış ama özel/ayrılmış ağa çözümlenen adresi kapatır (ödeme dönüşünün localhost'a düşmesi; bu kod tabanında bir kez yaşanmış arıza sınıfı). Liste dışı ya da güvensiz adres 422'dir ve yükleme kaydı oluşmaz - reddedilen istek bir ödeme oturumu da açmaz.
Çerçevenin genel kırpma ara katmanı gövdeyi doğrulamadan önce kırpar, dolayısıyla boşluklu bir adres reddedilmez, kırpılır - ve kırpma yalnızca onaylı adresin kendisini üretebilir, başka bir hedefi asla.
DÖNÜŞ ANI
Adres yükleme kaydına yazılır; callback hedefi kayıttan okur, kendisine gelen hiçbir değerden almaz (rota PUBLIC'tir ve Sevkora oturumu taşımaz - hedefi istekten okumak onu herkese açmak olurdu). Sonuç -> amaç eşlemesi:
| Sonuç | Seçilen amaç | Sorgu |
|---|---|---|
Succeeded |
success |
?topup=success |
Pending (dolandırıcılık incelemesi, kredi yok) |
success |
?topup=pending |
Failed (imza/tutar reddi, fraud ret, oturumsuz callback) |
failure |
?topup=failed |
cancel hiçbir dalda seçilmez ve bu bir eksik değildir: iyzico Checkout Form tek bir callbackUrl tanır ve hem başarıyı hem hatayı oraya yollar, bir iptal çağrısı üretmez. O adres iş ortağının kendi vazgeçme akışı içindir. Sonuç sorgu dizesine eklenmek zorundadır çünkü success ve pending aynı adrese düşer - iş ortağı kredinin kesinleşip kesinleşmediğini başka hiçbir yerden öğrenemezdi. Mevcut sorgu ve parça (#...) korunur.
Kayıtta adres yoksa bugünkü SPA dönüşü varsayılan olarak sürer (KK-2), yani SPA akışı bu değişiklikten etkilenmez - o akışta return_urls daima NULL doğar.
BİLİNEN VE SINIRLI PENCERE (RISK-085)
Adres yükleme başlarken doğrulanır; callback'te üyelik yeniden sorulmaz, çünkü top_ups bilerek bir iş ortağı bağı taşımaz. Yani beyaz listeden bir satır kaldırıldığında uçuştaki oturumlar hâlâ o adrese döner. Pencere dakikalar mertebesindedir ve iş ortağını tek hamlede kapatmanın yolu askıya almadır (sonraki her istek 403).
curl -X POST "{{host}}/api/partner/v1/balance/top-ups" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-App-Key: SEVKORA_UYGULAMA_ANAHTARINIZ" \
-H "Authorization: Bearer SEVKORA_API_ANAHTARINIZ" \
-d '{"amount_minor":25000}'