Kimlik Doğrulama ve Kapsamlar
- Taban yol
/api/v1/physical-pos- Kimlik
- Her istekte Ed25519 istek imzası —
X-Key-Id,X-Date,X-Nonce,X-Signature; gövdeli isteklerde ayrıcaDigest. Zaman penceresi ±5 dk, nonce tek kullanımlık. Bearer jetonu ya da panel oturumu bu uçlarda kabul edilmez. - Yetki
- Anahtarınız Fiziksel POS ürününü (
PHYSICAL_POS) ve bu sayfadaki uçların kapsamını taşımalıdır:physical_pos:view·physical_pos:manage. Ürünü olmayan anahtar403 PRODUCT_NOT_ENABLED, kapsamı olmayan anahtar403 API_INSUFFICIENT_SCOPEalır. Bkz. Kimlik Doğrulama ve Kapsamlar. - Çapraz yüzey
- Bu uçlar s2s yüzeyindedir; kendi sunucunuzdan imzalı istekle çağırırsınız. Aynı kayıtların panelde ekranları var, ama panel uçları API anahtarıyla çağrılamaz; bu uçlar da panel oturumuyla çağrılamaz.
Fiziksel POS yönetim uçlarını kendi sunucunuzdan, API anahtarınızla imzaladığınız isteklerle çağırırsınız. Her istekte üç şey sırayla denetlenir: imza, ürün ve kapsam.
İstek imzası
Her istek API anahtarınızla imzalanır. Authorization: Bearer jetonu ve panel oturumu bu uçlarda kimlik yerine geçmez; imza başlıkları olmayan istek 401 alır.
| Başlık | Değer |
|---|---|
X-Key-Id | Anahtarınızın kimliği: test için mk_test_…, canlı için mk_live_… |
X-Date | ISO 8601 zaman damgası; sunucu saatine göre ±5 dakika içinde |
X-Nonce | İstek başına benzersiz değer; tek kullanımlık |
Digest | Yalnız gövdeli isteklerde (POST, PATCH): gövdenin SHA-256 özeti, SHA-256=<base64> biçiminde |
X-Signature | Kanonik dizinin Base64 Ed25519 imzası |
Kanonik dizi YÖNTEM, tam yol (sorgu dizesi dahil), X-Date:…, X-Nonce:… ve gövde varsa Digest:… satırlarının \n ile birleşimidir. Gövdesiz isteklerde Digest satırı hiç yazılmaz. Kuralların tamamı ve anahtar yönetimi: Kimlik Doğrulama › Kanonik dize · Digest başlığının biçimi.
İmzalanan yol sorgu dizesini de içerir ve gönderdiğiniz yolla birebir aynı olmalıdır: GET /api/v1/physical-pos/stores?status=ACTIVE&limit=50 imzalanırken ikinci satır /api/v1/physical-pos/stores?status=ACTIVE&limit=50 olur.
İmza yardımcısı
Bu bölümdeki cURL örnekleri imzayı aşağıdaki kabuk fonksiyonuyla hesaplar (OpenSSL 3.0 veya üstü gerekir). Gövde verirseniz Digest de hesaplanır:
# lunixi-sign.sh — Kullanım:
# source lunixi-sign.sh
# lunixi_sign GET "/api/v1/physical-pos/stores"
# lunixi_sign POST "/api/v1/physical-pos/stores" "$BODY"
LUNIXI_KEY_ID="mk_test_..."
LUNIXI_KEY_FILE="lunixi-signing.key"
lunixi_sign() {
local method="$1" req_path="$2" body="$3"
DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
NONCE=$(openssl rand -hex 16)
if [ -n "$body" ]; then
DIGEST="SHA-256=$(printf '%s' "$body" | openssl dgst -sha256 -binary | base64)"
printf '%s\n%s\nX-Date:%s\nX-Nonce:%s\nDigest:%s' "$method" "$req_path" "$DATE" "$NONCE" "$DIGEST" > canonical.txt
else
DIGEST=""
printf '%s\n%s\nX-Date:%s\nX-Nonce:%s' "$method" "$req_path" "$DATE" "$NONCE" > canonical.txt
fi
SIGNATURE=$(openssl pkeyutl -sign -inkey "$LUNIXI_KEY_FILE" -rawin -in canonical.txt | base64 | tr -d '\n')
}Digest, kompakt JSON gövdeden hesaplanır. Sunucu gövdeyi ayrıştırıp kompakt biçimde yeniden yazar ve özeti bu metinden hesaplar. Gövdeyi boşluksuz, ASCII dışı karakterleri kaçışlamadan ("Kadıköy", "Kad\u0131k\u00f6y" değil) ve / işaretini kaçışlamadan gönderin; özeti aynı metnin UTF-8 baytlarından hesaplayın. Başka biçimdeki gövde 401 INVALID_DIGEST alır. Ayrıntı: Kimlik Doğrulama › Digest başlığının biçimi.
Gövdeyi kendi kodunuzda üretirken:
// Node.js
const body = JSON.stringify(payload);# Python
body = json.dumps(payload, separators=(",", ":"), ensure_ascii=False)// PHP
$body = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);Okuma isteği örneği:
source lunixi-sign.sh
REQ_PATH="/api/v1/physical-pos/overview"
lunixi_sign GET "$REQ_PATH"
curl "https://api-gateway.lunixi.com$REQ_PATH" \
-H "X-Key-Id: $LUNIXI_KEY_ID" \
-H "X-Date: $DATE" \
-H "X-Nonce: $NONCE" \
-H "X-Signature: $SIGNATURE"Gövdeli istek örneği:
source lunixi-sign.sh
REQ_PATH="/api/v1/physical-pos/stores"
BODY='{"code":"IST-KADIKOY","name":"Kadıköy Mağazası"}'
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: $(uuidgen)" \
--data-raw "$BODY"Ürün
İmza doğrulandıktan sonra anahtarınızda Fiziksel POS ürününün (PHYSICAL_POS) tanımlı olup olmadığına bakılır. Tanımlı değilse istek 403 PRODUCT_NOT_ENABLED alır. → Hata Yönetimi › PRODUCT_NOT_ENABLED
Kapsamlar
Ürün denetiminden sonra anahtarın, ucun istediği kapsamı taşıması gerekir. Taşımıyorsa istek 403 API_INSUFFICIENT_SCOPE alır.
| Kapsam | Verdiği yetki | Uçlar |
|---|---|---|
physical_pos:view | Okuma | Bütün GET uçları: katalog, mağaza ve kasa listeleri ve ayrıntıları, değişiklik geçmişleri, terminaller, banka satırları, cihazlar, atama ve bağ geçmişleri, genel bakış sayaçları |
physical_pos:manage | Yazma | Bütün POST ve PATCH uçları: mağaza ve kasa oluşturma, güncelleme, arşivleme ve yeniden açma; terminal oluşturma, güncelleme ve kapatma; banka satırı ekleme ve güncelleme; cihaz kaydetme, güncelleme, atama, depoya alma ve emeklilik; cihaz bağını değiştirme ve çözme |
physical_pos:identity | Cihaz kimliği işlemleri | Bu bölümde anlatılan uçların hiçbiri bu kapsamı istemez. |
physical_pos:manage okuma yetkisi içermez. Hem okuyup hem yazacak bir entegrasyonun anahtarında iki kapsam da bulunmalıdır. Örneğin bir terminali güncellemeden önce güncel rowVersion değerini okumanız gerekir; bunun için physical_pos:view şarttır.
Kapsamlar panelde API anahtarınızın yetki ayarlarında, Fiziksel POS grubunda listelenir; anahtar başına ekleyip kaldırabilirsiniz. Bir anahtara yalnız işinin gerektirdiği kapsamları verin: yalnız raporlama yapan bir entegrasyona physical_pos:view yeterlidir.
Ortamı (test ya da canlı) anahtarınız belirler; kapsamlar iki ortamda da aynı anlamı taşır. Test anahtarı bütün kayıtları yalnız okur; yazma istekleri 403 physical_pos.environment.test_key_read_only alır. → Ortamlar
Kimlik ve kiracı
İsteğin hangi organizasyon adına yapıldığı ve ortamı yalnız imzalı anahtarınızdan çözülür. Gövdede ya da sorguda organizationId, merchantId ya da environment gönderilmez: organizationId ve merchantId 400 VALIDATION_ERROR, environment 400 physical_pos.input.environment_invalid alır. Başka bir organizasyona ait kayıt, olmayan kayıtla aynı 404 cevabını alır.
Sıradaki adım
- Test ve canlı ortam farkları: Ortamlar
- Sayfalama,
Idempotency-Key,rowVersionve yanıt biçimi: Ortak Kurallar