Döviz İşlemi
- 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 anahtar403 PRODUCT_NOT_ENABLED, yetkisi olmayan anahtar403 API_INSUFFICIENT_SCOPEalı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ış
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öntem | Yol | Açıklama |
|---|---|---|
GET | /fx/rates?connectionId=… | Bağlantının güncel kurları |
POST | /fx/quotes | Döviz teklifi |
POST | /fx/orders | Teklifi işleme alır. Idempotency-Key zorunlu. |
GET | /fx/orders | Dö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"
}| Alan | Açıklama |
|---|---|
items[].currency / pairCurrency | Kurun para birimi ve karşılığı. |
items[].buyRate / sellRate | Bankanın alış ve satış kuru; ondalık metin olarak döner. Kayan noktalı sayıya çevirmeden kullanın. |
items[].spread | Banka bildiriyorsa alış-satış farkı; yoksa null. |
refreshSeconds | Bankanın kurları yenileme aralığı (saniye). Bu aralıktan sık sorgulamanın yararı yoktur. |
fetchedAt | Kurların bankadan alındığı an. |
Teklif alma
POST /api/v1/bank-connect/fx/quotes
| Gövde alanı | Tip | Zorunlu | Açıklama |
|---|---|---|---|
sourceAccountId | string (UUID) | Evet | Sattığınız para biriminin hesabı (bu hesaptan çıkar). |
targetAccountId | string (UUID) | Evet | Aldığınız para biriminin hesabı (bu hesaba girer). Aynı bağlantıda, farklı para biriminde olmalıdır. |
sourceAmountMinor | integer | İkisinden biri | Satmak istediğiniz tutar, kaynak hesabın para biriminde minor birim. |
targetAmountMinor | integer | İkisinden biri | Almak 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
| Alan | Tip | Açıklama |
|---|---|---|
id | string (UUID) | Teklifin kimliği; işlem açarken quoteId olarak gönderilir. |
connectionId | string (UUID) | Hesapların bağlantısı. |
sourceAccountId / targetAccountId | string (UUID) | Sattığınız ve aldığınız hesap. |
sourceCurrency / targetCurrency | string | İki hesabın para birimi. |
sourceAmountMinor | integer | Kaynak hesaptan çıkacak tutar, minor birimde. |
targetAmountMinor | integer | Hedef hesaba girecek tutar, minor birimde. |
requestedSide | string | Hangi tutarı sizin verdiğiniz: SOURCE ya da TARGET. Diğer tutarı banka hesaplar. |
appliedRate | string | Uygulanacak kur, ondalık metin. |
taxAmountMinor | integer | null | Banka bildiriyorsa işlemden alınacak vergi. |
expiresAt | string | null | Teklifin geçerlilik sonu. İşlemi bu zamandan önce açın. |
validForSeconds | integer | Yanıt anında teklifin kalan geçerlilik süresi (saniye). |
insufficientBalance | boolean | true: banka, kaynak hesabın bakiyesinin yetmeyebileceğini bildirdi. |
belowMinimum | boolean | true: tutar bankanın alt sınırının altında. |
createdAt | string | null | Teklifin oluşturulma zamanı. |
İşlem açma
POST /api/v1/bank-connect/fx/orders
| Başlık | Değer |
|---|---|
Idempotency-Key | Zorunlu. 8–200 yazdırılabilir ASCII karakter. Kurallar transferle aynıdır. → Para Transferi › Idempotency-Key |
| Gövde alanı | Tip | Zorunlu | Açıklama |
|---|---|---|---|
quoteId | string (UUID) | Evet | Süresi dolmamış ve daha önce kullanılmamış teklifin id'si. |
description | string | Hayır | Açı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şlem404 bank_connect.fx.order_not_founddöner.GET /api/v1/bank-connect/fx/ordersiş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.
| Alan | Tip | Açıklama |
|---|---|---|
id | string (UUID) | İşlemin kimliği. |
quoteId | string (UUID) | İşlemin teklifi. |
connectionId, sourceAccountId, targetAccountId | string (UUID) | Bağlantı ve iki hesap. |
sourceCurrency / targetCurrency | string | İki hesabın para birimi. |
sourceAmountMinor / targetAmountMinor | integer | Teklifteki tutarlar, minor birimde. |
appliedRate | string | Uygulanan kur, ondalık metin. |
description | string | null | Gönderdiğiniz açıklama. |
idempotencyKey | string | İşlemin oluşturulduğu Idempotency-Key. |
status | string | SUBMITTED, COMPLETED ya da FAILED. → Kavramlar › Döviz işlemi |
failureCode | string | null | FAILED işlemde sebep kodu (bank_connect.fx.*). → Hata Kodları › Döviz sonuç kodları |
outcomeUnknown | boolean | true: sonuç bankadan henüz doğrulanamadı. |
initiatedVia | string | API ya da PANEL. |
sourceBalanceAfterMinor / targetBalanceAfterMinor | integer | null | Banka bildiriyorsa işlemden sonra iki hesabın bakiyesi. |
createdAt, submittedAt, completedAt, failedAt | string | null | Zaman damgaları. |
fxSessionId | string | null | Yalnız panelden açılan işlemlerde dolu; API işlemlerinde null. |
Hatalar
| HTTP | code | Ne yapmalı |
|---|---|---|
400 | VALIDATION_ERROR | Tanımlanmamış bir alan ya da parametre gönderdiniz, ya da alan biçimi hatalı. |
400 | bank_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. |
400 | bank_connect.transfer.idempotency_key_required | İşlem açarken Idempotency-Key başlığını ekleyin. |
403 | API_INSUFFICIENT_SCOPE | Anahtarınıza bank-connect:transfer yetkisini ekleyin. |
403 | bank_connect.auth.ip_allowlist_required / bank_connect.auth.ip_not_allowed | IP izin listesini tanımlayın ya da isteği listedeki bir adresten gönderin. |
404 | bank_connect.connection.not_found / bank_connect.account.not_found | Bağlantı ya da hesap kimliğini kontrol edin. |
404 | bank_connect.fx.quote_not_found / bank_connect.fx.order_not_found | Kimliği ve anahtarınızın ortamını kontrol edin. |
409 | bank_connect.fx.quote_expired / bank_connect.fx.quote_used | Yeni teklif alın. |
409 | bank_connect.fx.idempotency_conflict | Bu anahtarı başka bir gövdeyle kullandınız; yeni işlem için yeni anahtar kullanın. |
409 | bank_connect.transfer.account_not_eligible | Hesap, bağlantı ya da banka bilgileri şu anda etkin değil. |
412 | bank_connect.fx.capability_unavailable | Bu bağlantı döviz işlemi desteklemiyor. |
422 | bank_connect.fx.accounts_invalid | Aynı bağlantıda, farklı para birimli iki etkin hesap seçin. |
422 | bank_connect.fx.pair_unsupported | Banka bu döviz çiftinde işlem yapmıyor. |
422 | bank_connect.fx.quote_rejected | Banka teklif vermedi; sebep details.reasonCode alanında. |
429 | RATE_LIMITED | İstek limiti aşıldı; Retry-After kadar bekleyin. → Sınırlar |