Kimlik Doğrulama
Lunixi API'sinde statik bir API anahtarını doğrudan Authorization başlığına koymazsınız. Uzun ömürlü secret, Ed25519 özel anahtarınızdır ve o hiçbir zaman telde gitmez. Onunla imzalayıp kısa ömürlü bir erişim token'ı basar, çağrılarınızı o token'la yaparsınız.
Ed25519 özel anahtar ──imzala──▶ POST /api/v1/auth/token ──▶ at_live_… (5 dk)
│
Authorization: Bearer at_live_…Neden böyle? Statik bir anahtar sızarsa saldırgan onu süresiz kullanır. Burada sızabilecek olan token'ın ömrü dakikalarla sınırlıdır; özel anahtar ise sunucunuzdan hiç çıkmaz. Para hareketi uçlarında bunun üstüne bir imza katmanı daha vardır (aşağıda Step-Up).
Adım 1 — Token basın
POST /api/v1/auth/tokenBu istek Bearer token istemez; imzalıdır.
| Başlık | Değer |
|---|---|
X-Key-Id | Kayıtlı Ed25519 public anahtarının kimliği (kid) |
X-Date | ISO 8601 zaman damgası — sunucu saatine göre ±5 dakika içinde olmalı |
X-Nonce | İstek başına benzersiz değer (UUID) — tek kullanımlık |
Digest | Ham gövdenin SHA-256 özeti (Base64) — gövde varsa zorunlu |
X-Signature | Kanonik dizenin Base64 Ed25519 imzası |
Kanonik dize
İmzaladığınız metin şudur — satırlar \n ile birleşir:
METHOD
URL
X-Date:<değer>
X-Nonce:<değer>
Digest:<değer> ← YALNIZ gövde varsaMETHOD büyük harfe çevrilir. URL isteğin yolu ve sorgu dizesidir.
Gövdesiz isteklerde Digest: satırı kanonik dizeye HİÇ EKLENMEZ. Boş değerle eklerseniz (Digest:) imza tutmaz. Token basma çağrısının gövdesi yoktur ⇒ kanonik dize dört satırdır.
Sıra ve büyük/küçük harf birebir olmalı. Satırları farklı sıralar veya başlık adlarını farklı yazarsanız imza tutmaz ve 401 alırsınız.
Digest başlığının biçimi
Gövdeli isteklerde başlık SHA-256= önekli olmalıdır:
Digest: SHA-256=<gövdenin sha256 özeti, base64>Önek yoksa ya da base64 dolgusu (=) kırpılmışsa doğrulama başarısız olur.
İmzalama algoritması
Ed25519'da hash algoritması belirtilmez. Node.js'te:
crypto.sign(null, Buffer.from(canonical), privateKey).toString('base64')⚠️ İlk argüman null olmalı. 'sha256' yazarsanız imza üretilir ama sunucuda doğrulanmaz.
Hata kodları
| Kod | Anlamı |
|---|---|
INVALID_DATE | X-Date 5 dakikalık pencerenin dışında |
DIGEST_MISSING | Gövde var ama Digest başlığı yok |
INVALID_DIGEST | Gövde özeti Digest ile uyuşmuyor |
401 | İmza geçersiz veya zaman damgası eski |
403 | IP izinli listede değil, ya da merchant askıya alınmış |
Adım 2 — Yanıt
{
"access_token": "at_live_5f3e2b1a...",
"token_type": "Bearer",
"expires_in": 300,
"expires_at": 1710000000,
"refresh_expires_in": 43200,
"refresh_expires_at": 1710043200,
"session_id": "authsess_3e46a2f3-1f02-42a9-9c4d-ef12b8f6f2d1"
}| Alan | Anlamı |
|---|---|
access_token | Opak token — at_{ortam}_ önekli. İçinde çözülecek bir bilgi yoktur, ayrıştırmaya çalışmayın |
expires_in | Saniye cinsinden ömür (tipik 300 = 5 dakika) |
refresh_expires_in | Yenileme penceresi (tipik 43200 = 12 saat) |
session_id | Oturum kimliği — destek talebinde ve log korelasyonunda kullanılır |
Önek ortamı taşır: at_live_… canlı, at_test_… test. Token'ın hangi ortama ait olduğunu ön ekinden çıkarsamayın — hangi anahtarla bastıysanız o ortamdasınız.
Adım 3 — Çağrılarınızda kullanın
curl "https://api-gateway.lunixi.com/api/v1/payments?page=1&limit=20" \
-H "Authorization: Bearer at_live_5f3e2b1a..."Kimliği doğrulanan taraf (merchantId) token'dan okunur, istek gövdesinden asla — gövde başka bir kiracıyı taklit edemez.
Token 5 dakikada bir yenilenir. Her çağrıda yeni token basmayın; token'ı süresi dolana kadar önbellekte tutun ve expires_at'e bakarak yenileyin. POST /auth/token her istekte çağrılırsa gereksiz yük ve gecikme üretirsiniz.
Step-Up — para hareketi uçları
Para hareketi yapan uçlar (ödeme intent'i oluşturma, direct çekim, capture, void, refund, marketplace ödemeleri) hem geçerli bir Bearer token hem de o isteğin üzerine ayrı bir Ed25519 imzası ister.
Authorization: Bearer at_live_… ← token
X-Key-Id / X-Date / X-Nonce / Digest / X-Signature ← isteğin kendi imzasıAmaç şudur: token'ınız çalınsa bile saldırgan para hareket ettiremez — özel imza anahtarınız olmadan Step-Up isteğini imzalayamaz. Bu yüzden özel anahtarı token'ı bastığınız yerden ayrı tutmak anlamlıdır.
İmza şeması Adım 1'dekiyle aynıdır: aynı kanonik dize, aynı başlıklar, aynı ±5 dakika penceresi, aynı tek-kullanımlık nonce.
Anahtar yönetimi
Ed25519 anahtar çiftini üretin
Özel anahtar sizin sunucunuzda kalır. Bize yalnız public anahtarı verirsiniz.
Public anahtarı kaydedin
Panelden kaydedersiniz; karşılığında bir kid (key id) alırsınız. X-Key-Id başlığında bu değeri gönderirsiniz.
Döndürme
Yeni bir anahtar çifti üretin, public anahtarı kaydedin, servislerinizi yeni kid ile güncelleyin, sonra eskisini iptal edin. Eski kid iptal edildiği anda o anahtarla imzalanan istekler 401 almaya başlar — yenisini yayına almadan eskisini iptal etmeyin.
Özel imza anahtarını tarayıcıya, mobil uygulamaya veya herkese açık bir depoya asla koymayın. Sızarsa panelden kid'i iptal edin ve yeni çift üretin.
IP izin listesi
API anahtarınıza bir IP izin listesi tanımlayabilirsiniz; liste doluysa anahtarla imzalanan istekler yalnız bu adreslerden kabul edilir. Listeye tek tek IP adresleri (IPv4 ya da IPv6) yazılır; adres aralıkları (CIDR) kabul edilmez, en çok 50 adres eklenebilir.
Bazı yetkiler yalnız IP izin listesi olan anahtara verilir. Banka hesabınızdan para transferi ve döviz işlemi yapan bank-connect:transfer yetkisi bunlardandır: liste boşken bu yetkiyi anahtara eklemeye çalışırsanız işlem 400 organization.api_key.scope_requires_ip_allowlist ile reddedilir (details.scopes hangi yetkinin liste istediğini verir). Bu yetkiyle yapılan isteklerde doğrulama kodu olmadığı için onay; anahtar yetkisi, istek imzası ve isteğin geldiği IP adresidir. → Banka Hesapları › IP izin listesi
Sunucunuzun dışarıya çıktığı adresi yazın; yük dengeleyici, NAT ya da yeni sunucu bu adresi değiştirebilir. Adres değiştiğinde listeyi güncellemezseniz istekler 403 alır.
Ortam değişkenleri
Saklanacak şey token değil, özel anahtar ve kid'dir:
# .env
LUNIXI_KEY_ID=kid_...
LUNIXI_PRIVATE_KEY_PATH=/secure/lunixi-ed25519.pemToken'ı uygulamanız çalışırken basar ve bellekte tutar; ortam değişkenine yazılacak bir şey değildir.
Sonraki adımlar
- Hızlı Başlangıç — ilk çağrınızı yapma
- Ödemelerde Kimlik Doğrulama — checkout token'ı, publishable key ve idempotency
- Hata Yönetimi — hata zarfı ve kodlar