Kimlik doğrulama
InfraIO Pay’in farklı auth modelleriyle iki API yüzeyi vardır. Kimin çağırdığına uyanı seçin:
| Yüzey | Yol öneki | Hedef kitle | Auth |
|---|---|---|---|
| Satıcı B2B | /b2b/v1/* | Sunucunuz | HMAC-SHA256 istek imzalama |
| Panel | Servise göre: /auth/*, /payment/*, /merchant/*, /event/*, /user/*, … | Satıcı paneli için tarayıcı oturumları | Bearer JWT |
Bu sayfa B2B yüzeyini kapsar — bir API anahtar çifti ile sunucunuzdan çağırdığınız yüzey. InfraIO panelini gömüyorsanız veya dahili araçlar oluşturuyorsanız, panel yüzeyini kullanın (henüz herkese açık olmayan ayrı dokümanlar).
Geçit her yüzeyi, yönlendirmeden önce çıkardığı önde gelen bir önek
ile yönlendirir: /b2b/v1/checkout-sessions/quick payment-service’e
/v1/checkout-sessions/quick olarak ulaşır ve panelin /payment/v1/orders’ı
ona /v1/orders olarak ulaşır. Yani başka yerlerde çıplak /v1/* yolları
görürseniz, bu public öneki kaldırıldıktan sonraki backend-dahili
yoldur — istemciniz her zaman önekli formu gönderir. (İmzalama için bir
sonuç: B2B kanonik dizesi yolu hâlâ ekli /b2b öneki ile imzalar —
aşağıya bakın.)
Uç noktalar
| Ortam | Temel URL |
|---|---|
| Test | https://api-dev.infraio.xyz |
| Canlı | https://api.infraio.xyz |
Aynı URL deseni — ortam, URL ile değil, anahtar öneki ile kontrol
edilir (pk_test_… vs pk_live_…).
Anahtar çifti
Satıcı panelinden iki değer alırsınız (Geliştiriciler → API anahtarları → + Anahtar ekle):
- Publishable key (
pk_test_…veyapk_live_…) — hesabınızı tanımlar.X-Client-IDolarak gönderilir. Tarayıcı paketinize gömmek güvenlidir (SDK bunu zaten yapar). - Secret key (
sk_test_…veyask_live_…) — HMAC imzalama anahtarı. Yalnızca sunucu. Bir veritabanı şifresi gibi davranın.
Bir secret key bir tarayıcı paketine, git deposuna, log satırına veya paylaşılan sohbete düşerse — panelden hemen iptal edin. Çakışma penceresi yoktur; iptal anlıktır. Yeni bir anahtar verin ve yeniden dağıtın.
Bir isteği imzalama
/b2b/v1/*’a yapılan her çağrı üç başlık taşır:
X-Client-ID: pk_live_70d0becbd7a53047b0dfe88a960d10ad
X-Timestamp: 1715990400
X-Signature: 9a8b7c6d… (hex HMAC-SHA256)İmza bir kanonik dize üzerinde hesaplanır:
METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + BODYMETHOD— büyük harf HTTP fiili (POST,GET, …).PATH— host olmadan ve query string olmadan,/b2böneki dahil istek yolu (örn./b2b/v1/checkout-sessions/quick). Geçit imzayı/b2b’yi çıkarmadan önceki ham gelen yol üzerinde doğrular, bu yüzden önek mevcut olmalıdır. Query parametreleri imzalanmaz — birGET …?cursor=…&limit=20için yalnızca yolu imzalayın,?…kısmını değil.TIMESTAMP— unix saniye, ondalık string olarak (örn."1715990400"),X-Timestampile tam olarak eşleşmelidir.BODY— ham istek gövdesi baytları.GET/DELETEiçin boş string.
Secret anahtarla HMAC-SHA256 ile imzalayın, çıktı hex:
Node / TS
import { createHmac } from "node:crypto";
function sign({ method, path, body, secret }: {
method: string; path: string; body: string; secret: string;
}) {
const timestamp = Math.floor(Date.now() / 1000).toString();
const input = [method.toUpperCase(), path, timestamp, body].join("\n");
const signature = createHmac("sha256", secret).update(input).digest("hex");
return { timestamp, signature };
}Neden HMAC, Bearer değil?
Bir çıplak Bearer-token API’si, her istekte tek secret’ınızı tel üzerinden gönderir. Bir TLS-sonlandırılmış proxy logu yakalayan herkes hesabınızın anahtarlarını alır. HMAC imzalama, secret’ın asla seyahat etmediği anlamına gelir — yalnızca türetilmiş imzası, ki bu da tek kullanımlıktır (o tam isteğe + o tam dakikaya bağlı).
Ödünleşim: her çağrı için imzayı hesaplamanız gerekir. Bir sunucu SDK’sı bunu gizlerdi; biz birini yayımlayana kadar, yukarıdaki yardımcı dil başına ~15 satırdır.
Timestamp toleransı
Bağlayıcı tolerans, imzayı doğruladığında merchant-service tarafından
uygulanan ±5 dakikadır (300 saniye). Geçidin kendisi savunma derinliği
olarak biraz daha gevşek (310 saniye), ama geçidi geçen ve iç kontrolde
başarısız olan bir istek hâlâ 401 invalid_signature ile sonlanır —
sözleşme olarak 300s varsayın. İki sonuç:
- Sunucu saatinizi NTP ile senkronize edin. Kaymış saatli uzun süre çalışan bir cron aralıklı olarak başarısız olur.
- İmzaları önceden hesaplayıp kuyruğa almayın. Bir istek bir yeniden deneme kuyruğunda >5 dakika oturursa, imzasının süresi dolar.
Anahtar scope’ları
Secret anahtarlar şu scope demetlerinden bir veya daha fazlasını taşır:
| Scope | Kullanım amacı |
|---|---|
read | Siparişleri, oturumları, iadeleri listele/oku |
write_order | Checkout oturumları, siparişler oluştur |
write_refund | İadeler ver, iade-talep token’ları üret |
webhook_manage | Webhook uç noktalarını oluştur/güncelle/sil |
Panel varsayılan olarak bir “tam erişim” anahtarı verir (dört scope da). Entegrasyonun ihtiyaç duyduğu scope’ları işaretleyerek Geliştiriciler → API anahtarları → + Anahtar ekle üzerinden kısıtlı scope’lu bir anahtar üretebilirsiniz.
Scope uygulaması şu anda tavsiye niteliğindedir, kapı yoktur.
Scope’lar anahtarda kaydedilir ve panelde size geri gösterilir, ancak
geçit middleware’i henüz scope-dışı çağrıları reddetmez — herhangi bir
geçerli sk_… anahtarı bugün tam erişim olarak davranır. Uç nokta
başına scope kapıları sonraki sürümde. Scope’lara henüz bir güvenlik
sınırı olarak yaslanmayın; onları etiket olarak değerlendirin ve
erişimi kısıtlamak için hızlı rotation / iptal kullanın.
İmza nerede doğrulanır
HMAC doğrulaması bir kez, geçidde gerçekleşir. Geçit:
X-Client-ID,X-Timestamp,X-Signature’ı okur.pk_…üzerinden satıcı + secret’ı arar, timestamp pencere kontrolünü yapar, imzayı yeniden hesaplar, constant-time karşılaştırır.- Başarıda, auth başlıklarını çıkarır, isteği dahili başlıklarla
damgalar (
X-B2B-Auth: 1,X-Merchant-ID,X-Merchant-Domain) ve alt servise iletir (payment-service, merchant-service, vb.). Bugün ortam + çözümlenmiş scope’lar enjekte EDİLMEZ — ortama ihtiyaç duyan alt kod, başlıklardan değil, istek gövdesi / satıcı başına yapılandırmadan türetir. - Başarısızlıkta, backend’e asla dokunmadan 401
INVALID_SIGNATUREdöndürür.
Alt servisler HMAC’i yeniden çalıştırmaz — geçidin enjekte ettiği
başlıklara güvenir ve geçidin çözümlediği satıcıya göre hareket eder.
Uç nokta başına scope-kapısı da yapmazlar: yukarıda belirtildiği gibi,
anahtarın scope’u enjekte edilmez, bu yüzden herhangi bir doğrulanmış
sk_… satıcısı için herhangi bir uç noktaya ulaşır (scope uygulaması
bugün tavsiye niteliğindedir — bkz.
Anahtar scope’ları altındaki uyarı). Bu iki şekilde önemlidir:
- InfraIO Pay’in önünde kendi reverse proxy’nizi çalıştırıyorsanız,
X-B2B-Auth/X-Merchant-ID’yi çıkarmayın (ve onları sahteleştirmeyin de — geçit, bu başlıkları public kenarda taşıyan gelen istekleri reddeder). - Public ağ yolları (
/b2b/v1/*), HMAC adımını çalıştıran tek yüzeydir. Servislerimiz arası dahili gRPC mTLS kullanır —X-Client-ID’yi kabul etmeyen farklı bir güven modeli.
Sırada ne var
- Hatalar — 4xx/5xx’te yanıt şekli.
- Güvenlik → API anahtarları — rotation, iptal, bir secret sızarsa ne yapılacağı.
- Webhook’lar → İmza doğrulama —
farklı bir HMAC şeması kullanır (
X-Signature: sha256=…başlığı,X-Timestamp + "." + raw_bodyimzalar, artı 24 saatlik rotation kayma penceresinde opsiyonel birX-Signature-Prev). Şemaları karıştırmayın — hash algoritmasını paylaşırlar ama imzalanan baytlar ve secret ailesi (whsec_…vssk_…) farklıdır.