Banka Hesapları
API Referansı
Döviz İşlemi

Döviz İşlemi

Bu uçları kim çağırır?Dış API (s2s)
Taban yol
/api/v1/bank-connect
Kimlik
Her istekte Ed25519 istek imzası — X-Key-Id, X-Date, X-Nonce, X-Signature. Zaman penceresi ±5 dk, nonce tek kullanımlık. Bearer jetonu ya da panel oturumu bu uçlarda kabul edilmez (401 AUTH_HEADERS_MISSING).
Yetki
Anahtarınız Banka Bağlantıları ürününü (BANK_CONNECT) ve bu sayfadaki uçların yetkisini taşımalıdır: bank-connect:transfer. Ürünü olmayan anahtar 403 PRODUCT_NOT_ENABLED, yetkisi olmayan anahtar 403 API_INSUFFICIENT_SCOPE alır. Bkz. API'ye Giriş › Yetkiler.
Çapraz yüzey
Bu uçlar s2s yüzeyindedir; kendi sunucunuzdan imzalı istekle çağırırsınız. Aynı verinin panelde ekranları var, ama panel uçları API anahtarıyla çağrılamaz; bu uçlar da panel oturumuyla çağrılamaz. Bankayı bağlama ve kesme yalnız panelde yapılır.

Bağlantınız döviz işlemi destekliyorsa aynı bankadaki iki hesabınız arasında döviz alıp satabilirsiniz: bir hesaptan satarsınız, farklı para birimindeki diğer hesabınıza alırsınız. Bir bağlantının döviz işlemi destekleyip desteklemediğini Bağlantılar ucundaki capabilities alanından okursunuz: listede FX_EXCHANGE olmalıdır.

API anahtarıyla yapılan döviz işleminde e-posta doğrulama kodu istenmez. Yetki ve IP izin listesi kuralı Para Transferi ile aynıdır: anahtarınız bank-connect:transfer yetkisini ve bir IP izin listesini taşımalı, istek listedeki bir adresten gelmelidir.

Akış

Döviz işlemi akışıAkış: isteğe bağlı olarak kurları okursunuz, kısa süre geçerli bir teklif alırsınız ve süresi dolmadan teklifi işleme dönüştürürsünüz; işlem SUBMITTED açılır, bankanın yanıtına göre COMPLETED veya FAILED olur. Webhook gönderilmediği için sonucu işlem ucundan okursunuz.SÜRE DOLMADANKurlarGET /fx/ratesTeklifPOST /fx/quotesİşlemPOST /fx/ordersCOMPLETEDFAILEDisteğe bağlı~1–2 dk geçerli · expiresAtSUBMITTED açılırGET /fx/orders/{orderId}webhook yok — işlemi okuyunLEJANTİSTEĞE BAĞLIKISA ÖMÜRLÜBANKAYA GÖNDERİLİRSON
Teklif hiçbir tutarı bloke etmez ve kısa süre geçerlidir; işlemi expiresAt dolmadan açın. Sonucu işlem ucundan okuyun — döviz işlemleri için webhook gönderilmez.

Kurları görün (isteğe bağlı)

GET /fx/rates bağlantının güncel alış ve satış kurlarını döner. Kurlar bilgi amaçlıdır; uygulanacak kur teklifte verilir.

Teklif alın

POST /fx/quotes ile kaynak hesabı (sattığınız), hedef hesabı (aldığınız) ve tutarı gönderin. Banka uygulanacak kuru ve iki taraftaki tutarı verir. Teklif hiçbir şeyi bloke etmez.

Teklifi süresi dolmadan işleme alın

POST /fx/orders ile teklifin id'sini gönderin. Teklifin geçerlilik süresini banka belirler ve kısadır (çoğunlukla bir iki dakika); teklifteki expiresAt zamanından önce işlem açın. İşlem SUBMITTED durumunda açılır ve bankaya iletilir.

Sonucu sorgulayın

GET /fx/orders/{orderId} ile işlemin COMPLETED ya da FAILED olduğunu görün. Döviz işlemleri için webhook gönderilmez.

Uçlar

YöntemYolAçıklama
GET/fx/rates?connectionId=…Bağlantının güncel kurları
POST/fx/quotesDöviz teklifi
POST/fx/ordersTeklifi işleme alır. Idempotency-Key zorunlu.
GET/fx/ordersDöviz işlemlerini listeler
GET/fx/orders/{orderId}Tek döviz işlemi

Taban adres: https://api-gateway.lunixi.com/api/v1/bank-connect. Gövdeli isteklerin imzası: Para Transferi › Gövdeli isteği imzalama. PHP örnekleri SDK'nın 0.22.0 ve üstü sürümünde $bankConnect->fx() ile çalışır.

Kurlar

GET /api/v1/bank-connect/fx/rates?connectionId={connectionId}

{
  "status": "success",
  "code": "SUCCESS",
  "data": {
    "items": [
      { "currency": "USD", "pairCurrency": "TRY", "buyRate": "34.0100", "sellRate": "34.2400", "spread": null, "updatedAt": "2026-01-01T07:00:00.000Z" }
    ],
    "refreshSeconds": 30,
    "fetchedAt": "2026-01-01T07:00:00.000Z"
  },
  "statusCode": 200,
  "requestId": "00000000-0000-0000-0000-000000000000"
}
AlanAçıklama
items[].currency / pairCurrencyKurun para birimi ve karşılığı.
items[].buyRate / sellRateBankanın alış ve satış kuru; ondalık metin olarak döner. Kayan noktalı sayıya çevirmeden kullanın.
items[].spreadBanka bildiriyorsa alış-satış farkı; yoksa null.
refreshSecondsBankanın kurları yenileme aralığı (saniye). Bu aralıktan sık sorgulamanın yararı yoktur.
fetchedAtKurların bankadan alındığı an.

Teklif alma

POST /api/v1/bank-connect/fx/quotes

Gövde alanıTipZorunluAçıklama
sourceAccountIdstring (UUID)EvetSattığınız para biriminin hesabı (bu hesaptan çıkar).
targetAccountIdstring (UUID)EvetAldığınız para biriminin hesabı (bu hesaba girer). Aynı bağlantıda, farklı para biriminde olmalıdır.
sourceAmountMinorintegerİkisinden biriSatmak istediğiniz tutar, kaynak hesabın para biriminde minor birim.
targetAmountMinorintegerİkisinden biriAlmak istediğiniz tutar, hedef hesabın para biriminde minor birim.

sourceAmountMinor ve targetAmountMinor alanlarından tam olarak birini gönderin. Teklif isteği Idempotency-Key almaz; her istek yeni bir teklif üretir.

source lunixi-sign.sh
REQ_PATH="/api/v1/bank-connect/fx/quotes"
BODY='{"sourceAccountId":"00000000-0000-0000-0000-000000000100","targetAccountId":"00000000-0000-0000-0000-000000000101","targetAmountMinor":100000}'
lunixi_sign POST "$REQ_PATH" "$BODY"
 
curl -X POST "https://api-gateway.lunixi.com$REQ_PATH" \
  -H "Content-Type: application/json" \
  -H "X-Key-Id: $LUNIXI_KEY_ID" \
  -H "X-Date: $DATE" \
  -H "X-Nonce: $NONCE" \
  -H "Digest: $DIGEST" \
  -H "X-Signature: $SIGNATURE" \
  --data-raw "$BODY"

Başarılı yanıt 201 döner; data teklif nesnesidir:

{
  "status": "success",
  "code": "SUCCESS",
  "data": {
    "id": "00000000-0000-0000-0000-000000003000",
    "connectionId": "00000000-0000-0000-0000-000000000010",
    "sourceAccountId": "00000000-0000-0000-0000-000000000100",
    "targetAccountId": "00000000-0000-0000-0000-000000000101",
    "sourceCurrency": "TRY",
    "targetCurrency": "USD",
    "sourceAmountMinor": 3412500,
    "targetAmountMinor": 100000,
    "requestedSide": "TARGET",
    "appliedRate": "34.1250",
    "taxAmountMinor": null,
    "expiresAt": "2026-01-01T07:01:20.000Z",
    "validForSeconds": 80,
    "insufficientBalance": false,
    "belowMinimum": false,
    "createdAt": "2026-01-01T07:00:00.000Z"
  },
  "statusCode": 201,
  "requestId": "00000000-0000-0000-0000-000000000000"
}

Teklif nesnesi

AlanTipAçıklama
idstring (UUID)Teklifin kimliği; işlem açarken quoteId olarak gönderilir.
connectionIdstring (UUID)Hesapların bağlantısı.
sourceAccountId / targetAccountIdstring (UUID)Sattığınız ve aldığınız hesap.
sourceCurrency / targetCurrencystringİki hesabın para birimi.
sourceAmountMinorintegerKaynak hesaptan çıkacak tutar, minor birimde.
targetAmountMinorintegerHedef hesaba girecek tutar, minor birimde.
requestedSidestringHangi tutarı sizin verdiğiniz: SOURCE ya da TARGET. Diğer tutarı banka hesaplar.
appliedRatestringUygulanacak kur, ondalık metin.
taxAmountMinorinteger | nullBanka bildiriyorsa işlemden alınacak vergi.
expiresAtstring | nullTeklifin geçerlilik sonu. İşlemi bu zamandan önce açın.
validForSecondsintegerYanıt anında teklifin kalan geçerlilik süresi (saniye).
insufficientBalancebooleantrue: banka, kaynak hesabın bakiyesinin yetmeyebileceğini bildirdi.
belowMinimumbooleantrue: tutar bankanın alt sınırının altında.
createdAtstring | nullTeklifin oluşturulma zamanı.

İşlem açma

POST /api/v1/bank-connect/fx/orders

BaşlıkDeğer
Idempotency-KeyZorunlu. 8–200 yazdırılabilir ASCII karakter. Kurallar transferle aynıdır. → Para Transferi › Idempotency-Key
Gövde alanıTipZorunluAçıklama
quoteIdstring (UUID)EvetSüresi dolmamış ve daha önce kullanılmamış teklifin id'si.
descriptionstringHayırAçıklama, en çok 140 karakter.
source lunixi-sign.sh
REQ_PATH="/api/v1/bank-connect/fx/orders"
BODY='{"quoteId":"00000000-0000-0000-0000-000000003000"}'
lunixi_sign POST "$REQ_PATH" "$BODY"
 
curl -X POST "https://api-gateway.lunixi.com$REQ_PATH" \
  -H "Content-Type: application/json" \
  -H "X-Key-Id: $LUNIXI_KEY_ID" \
  -H "X-Date: $DATE" \
  -H "X-Nonce: $NONCE" \
  -H "Digest: $DIGEST" \
  -H "X-Signature: $SIGNATURE" \
  -H "Idempotency-Key: fx-2026-0042" \
  --data-raw "$BODY"

Başarılı yanıt 201 döner: data.order döviz işlemi, data.replayed aynı anahtar ve gövdeyle var olan işlemin dönüp dönmediğidir.

{
  "status": "success",
  "code": "SUCCESS",
  "data": {
    "order": {
      "id": "00000000-0000-0000-0000-000000004000",
      "quoteId": "00000000-0000-0000-0000-000000003000",
      "connectionId": "00000000-0000-0000-0000-000000000010",
      "sourceAccountId": "00000000-0000-0000-0000-000000000100",
      "targetAccountId": "00000000-0000-0000-0000-000000000101",
      "sourceCurrency": "TRY",
      "targetCurrency": "USD",
      "sourceAmountMinor": 3412500,
      "targetAmountMinor": 100000,
      "appliedRate": "34.1250",
      "description": null,
      "idempotencyKey": "fx-2026-0042",
      "status": "SUBMITTED",
      "failureCode": null,
      "outcomeUnknown": false,
      "initiatedVia": "API",
      "sourceBalanceAfterMinor": null,
      "targetBalanceAfterMinor": null,
      "createdAt": "2026-01-01T07:00:30.000Z",
      "submittedAt": "2026-01-01T07:00:30.000Z",
      "completedAt": null,
      "failedAt": null,
      "fxSessionId": null
    },
    "replayed": false
  },
  "statusCode": 201,
  "requestId": "00000000-0000-0000-0000-000000000000"
}
⚠️

Bir teklifle yalnız bir işlem açılır. Teklifin süresi dolduysa 409 bank_connect.fx.quote_expired, teklif kullanıldıysa 409 bank_connect.fx.quote_used döner; yeni teklif alın. İşlem açıldıktan sonra bankaya iletilmeden teklif süresi dolarsa işlem FAILED olur ve failureCode bank_connect.fx.quote_expired döner.

Döviz işlemlerini izleme

  • GET /api/v1/bank-connect/fx/orders/{orderId} tek işlemi döner. Bilinmeyen, başka bir organizasyona ya da diğer ortama ait işlem 404 bank_connect.fx.order_not_found döner.
  • GET /api/v1/bank-connect/fx/orders işlemleri en yeniden eskiye listeler. Süzgeçler: status (virgülle ayrılmış: SUBMITTED, COMPLETED, FAILED), limit (1–100), cursor.

outcomeUnknown true ise sonuç bankadan henüz doğrulanamamıştır; aynı işlemi yeniden açmayın. Lunixi sonucu bankayla doğrular ve işlemin durumunu günceller.

Döviz işlemi nesnesi

Değeri olmayan alanlar null döner.

AlanTipAçıklama
idstring (UUID)İşlemin kimliği.
quoteIdstring (UUID)İşlemin teklifi.
connectionId, sourceAccountId, targetAccountIdstring (UUID)Bağlantı ve iki hesap.
sourceCurrency / targetCurrencystringİki hesabın para birimi.
sourceAmountMinor / targetAmountMinorintegerTeklifteki tutarlar, minor birimde.
appliedRatestringUygulanan kur, ondalık metin.
descriptionstring | nullGönderdiğiniz açıklama.
idempotencyKeystringİşlemin oluşturulduğu Idempotency-Key.
statusstringSUBMITTED, COMPLETED ya da FAILED. → Kavramlar › Döviz işlemi
failureCodestring | nullFAILED işlemde sebep kodu (bank_connect.fx.*). → Hata Kodları › Döviz sonuç kodları
outcomeUnknownbooleantrue: sonuç bankadan henüz doğrulanamadı.
initiatedViastringAPI ya da PANEL.
sourceBalanceAfterMinor / targetBalanceAfterMinorinteger | nullBanka bildiriyorsa işlemden sonra iki hesabın bakiyesi.
createdAt, submittedAt, completedAt, failedAtstring | nullZaman damgaları.
fxSessionIdstring | nullYalnız panelden açılan işlemlerde dolu; API işlemlerinde null.

Hatalar

HTTPcodeNe yapmalı
400VALIDATION_ERRORTanımlanmamış bir alan ya da parametre gönderdiniz, ya da alan biçimi hatalı.
400bank_connect.validation.invalidİki tutar birden ya da hiç tutar gönderilmedi, iki hesap aynı ya da açıklama kurala uymuyor; details.errors[] alanına bakın.
400bank_connect.transfer.idempotency_key_requiredİşlem açarken Idempotency-Key başlığını ekleyin.
403API_INSUFFICIENT_SCOPEAnahtarınıza bank-connect:transfer yetkisini ekleyin.
403bank_connect.auth.ip_allowlist_required / bank_connect.auth.ip_not_allowedIP izin listesini tanımlayın ya da isteği listedeki bir adresten gönderin.
404bank_connect.connection.not_found / bank_connect.account.not_foundBağlantı ya da hesap kimliğini kontrol edin.
404bank_connect.fx.quote_not_found / bank_connect.fx.order_not_foundKimliği ve anahtarınızın ortamını kontrol edin.
409bank_connect.fx.quote_expired / bank_connect.fx.quote_usedYeni teklif alın.
409bank_connect.fx.idempotency_conflictBu anahtarı başka bir gövdeyle kullandınız; yeni işlem için yeni anahtar kullanın.
409bank_connect.transfer.account_not_eligibleHesap, bağlantı ya da banka bilgileri şu anda etkin değil.
412bank_connect.fx.capability_unavailableBu bağlantı döviz işlemi desteklemiyor.
422bank_connect.fx.accounts_invalidAynı bağlantıda, farklı para birimli iki etkin hesap seçin.
422bank_connect.fx.pair_unsupportedBanka bu döviz çiftinde işlem yapmıyor.
422bank_connect.fx.quote_rejectedBanka teklif vermedi; sebep details.reasonCode alanında.
429RATE_LIMITEDİstek limiti aşıldı; Retry-After kadar bekleyin. → Sınırlar