Cihaz Bağı
- 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.
Cihaz bağı, bir mantıksal terminalin hangi fiziksel cihazda çalıştığını gösterir. Cihaz değiştiğinde terminal, terminal kodu ve banka satırları aynı kalır; yalnız bağ değişir. → Temel kavramlar
- Bir terminalin aynı anda en çok bir bağlı cihazı olur; bir cihaz aynı anda en çok bir terminale bağlıdır.
- Her bağın bir başlangıcı (
validFrom) ve kapandığında bir bitişi (validTo) vardır; eski bağlar silinmez, bağ geçmişinde kalır. - Terminal ve cihaz aynı ortamda olmalıdır. Bağ işlemleri terminalin
rowVersiondeğerini ister ve başarılı her işlem bu değeri artırır. - Cihaz emekliye ayrıldığında bağı da kapanır.
- Test anahtarı bu uçlarda yalnız bağ geçmişini okur; yazma istekleri
403 physical_pos.environment.test_key_read_onlyalır.
| Yöntem | Yol | Kapsam |
|---|---|---|
POST | /api/v1/physical-pos/terminals/{terminalId}/device-link | physical_pos:manage |
POST | /api/v1/physical-pos/terminals/{terminalId}/device-link/close | physical_pos:manage |
GET | /api/v1/physical-pos/terminals/{terminalId}/links | physical_pos:view |
cURL örnekleri imzayı lunixi-sign.sh ile hesaplar: Kimlik Doğrulama › İmza yardımcısı.
Bağ nesnesi
| Alan | Tip | Açıklama |
|---|---|---|
id | string (UUID) | Bağın kimliği. |
terminalId | string (UUID) | Terminal. |
deviceId | string (UUID) | Cihaz. |
validFrom | string | Bağın açıldığı zaman. |
validTo | string | null | Bağın kapandığı zaman; açık bağda null. |
reasonCode | string | Bağı açan işlemin gerekçe kodu. |
createdByType | string | Bağı açan: USER, API_KEY, OPERATOR ya da SYSTEM. |
createdById | string | Bağı açanın kimliği; API anahtarında kid:<anahtar kimliği>. |
createdAt | string | Kaydın oluşturulma zamanı. |
Cihaz bağlama ve değiştirme
POST /api/v1/physical-pos/terminals/{terminalId}/device-link
Terminale bir cihaz bağlar. Terminalin açık bir bağı varsa eski bağ kapanır ve yenisi açılır; ikisi tek işlemde yapılır.
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
rowVersion | integer | Evet | Terminalin son okuduğunuz rowVersion değeri. |
deviceId | string (UUID) | Evet | Bağlanacak cihazın kimliği: cihaz listesindeki ya da ayrıntısındaki id. Cihaz terminalle aynı ortamda olmalıdır. |
reasonCode | string | Evet | Aşağıdaki tabloya bakın. |
| Durum | Kabul edilen reasonCode |
|---|---|
| Terminalin bağlı cihazı yok (ilk bağlama) | INITIAL_SETUP, RELOCATION, CORRECTION, OTHER |
| Terminalin bağlı cihazı var (değiştirme) | DEVICE_REPLACEMENT, DEVICE_FAULT, DEVICE_LOST, DEVICE_STOLEN, RELOCATION, CORRECTION, OTHER |
Duruma uymayan kod (ör. değiştirmede INITIAL_SETUP) 400 physical_pos.input.reason_code_invalid alır.
source lunixi-sign.sh
REQ_PATH="/api/v1/physical-pos/terminals/00000000-0000-0000-0000-000000000301/device-link"
BODY='{"rowVersion":3,"deviceId":"00000000-0000-0000-0000-000000000402","reasonCode":"DEVICE_FAULT"}'
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"{
"status": "success",
"code": "SUCCESS",
"data": {
"terminal": {
"id": "00000000-0000-0000-0000-000000000301",
"terminalCode": "IST-KADIKOY-01",
"terminalStatus": "ACTIVE",
"linkedDevice": {
"linkId": "00000000-0000-0000-0000-000000000502",
"deviceId": "00000000-0000-0000-0000-000000000402",
"displayName": "Kasa 1 POS (yedek)",
"serialNumber": "SN0000000002",
"lifecycleStatus": "ACTIVE",
"linkedAt": "2026-01-10T10:00:00.000Z"
},
"rowVersion": 4
},
"link": {
"id": "00000000-0000-0000-0000-000000000502",
"terminalId": "00000000-0000-0000-0000-000000000301",
"deviceId": "00000000-0000-0000-0000-000000000402",
"validFrom": "2026-01-10T10:00:00.000Z",
"validTo": null,
"reasonCode": "DEVICE_FAULT",
"createdByType": "API_KEY",
"createdById": "kid:mk_live_00000000",
"createdAt": "2026-01-10T10:00:00.000Z"
},
"previousLinkId": "00000000-0000-0000-0000-000000000501"
},
"statusCode": 200,
"requestId": "00000000-0000-0000-0000-000000000000"
}Örnekte terminal nesnesi kısaltılmıştır; yanıt bütün alanları içerir. previousLinkId kapanan eski bağın kimliğidir; ilk bağlamada null.
| Engel | Hata |
|---|---|
| Cihaz yok, size ait değil ya da diğer ortamda | 404 physical_pos.device.not_found |
| Cihaz zaten bu terminale bağlı | 409 physical_pos.terminal.device_already_linked |
| Cihaz başka bir terminale bağlı | 409 physical_pos.terminal.link_conflict — önce o terminalin bağını çözün. |
Cihaz emekliye ayrılmış (RETIRED) | 409 physical_pos.device.retired |
| Terminalin üreticisi cihazın üreticisinden farklı | 400 physical_pos.terminal.device_vendor_mismatch |
| Terminal kapatılmış | 409 physical_pos.terminal.closed |
Bu uç Idempotency-Key kullanmaz; tekrarları terminalin rowVersion değeri korur. Zaman aşımından sonra isteği yinelemeden önce terminali okuyun: linkedDevice.deviceId yeni cihazı gösteriyorsa işlem tamamlanmıştır.
Cihaz bağını çözme
POST /api/v1/physical-pos/terminals/{terminalId}/device-link/close · Idempotency-Key zorunlu
Terminalin açık bağını kapatır. Terminal açık kalır; banka satırları değişmez. Daha sonra yeni bir cihaz bağlayabilirsiniz.
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
rowVersion | integer | Evet | Terminalin son okuduğunuz rowVersion değeri. |
reasonCode | string | Evet | DEVICE_REPLACEMENT, DEVICE_FAULT, DEVICE_LOST, DEVICE_STOLEN, RELOCATION, CORRECTION, OTHER. |
source lunixi-sign.sh
REQ_PATH="/api/v1/physical-pos/terminals/00000000-0000-0000-0000-000000000301/device-link/close"
BODY='{"rowVersion":4,"reasonCode":"DEVICE_LOST"}'
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: 4f9b2c1e-0000-4000-8000-000000000005" \
--data-raw "$BODY"{
"status": "success",
"code": "SUCCESS",
"data": {
"terminal": {
"id": "00000000-0000-0000-0000-000000000301",
"terminalCode": "IST-KADIKOY-01",
"terminalStatus": "ACTIVE",
"linkedDevice": null,
"rowVersion": 5
},
"link": {
"id": "00000000-0000-0000-0000-000000000502",
"terminalId": "00000000-0000-0000-0000-000000000301",
"deviceId": "00000000-0000-0000-0000-000000000402",
"validFrom": "2026-01-10T10:00:00.000Z",
"validTo": "2026-02-01T12:00:00.000Z",
"reasonCode": "DEVICE_FAULT",
"createdByType": "API_KEY",
"createdById": "kid:mk_live_00000000",
"createdAt": "2026-01-10T10:00:00.000Z"
},
"replayed": false
},
"statusCode": 200,
"requestId": "00000000-0000-0000-0000-000000000000"
}link kapanan bağdır; reasonCode bağı açan işlemin kodudur, çözme gerekçesi terminalin değişiklik geçmişine yazılır. Aynı Idempotency-Key ve aynı gövdeyle tekrar replayed: true döner. Terminalin bağlı cihazı yoksa 409 physical_pos.terminal.device_not_linked.
Bağ geçmişi
GET /api/v1/physical-pos/terminals/{terminalId}/links
| Sorgu parametresi | Tip | Açıklama |
|---|---|---|
limit | integer | Sayfa başına bağ, 1–100. Varsayılan 25. |
cursor | string | Önceki yanıttaki pageInfo.nextCursor. |
Yanıt: { "items": [ <bağ nesnesi> ], "pageInfo": { … } }, en yeni bağ önce.
Hatalar
| HTTP | code | Ne zaman |
|---|---|---|
400 | VALIDATION_ERROR | deviceId UUID değil; tanımsız gövde alanı. |
400 | physical_pos.idempotency.key_required / physical_pos.idempotency.key_invalid | Bağ çözmede Idempotency-Key yok ya da biçim dışı. |
400 | physical_pos.input.reason_code_invalid | reasonCode listede yok ya da işleme uymuyor. |
400 | physical_pos.terminal.device_vendor_mismatch | Terminal ile cihazın üreticileri farklı. |
400 | physical_pos.cursor.invalid | Bozuk imleç. |
403 | physical_pos.environment.test_key_read_only | Yazma isteği test anahtarıyla yapıldı. |
404 | physical_pos.terminal.not_found | Terminal yok, size ait değil ya da diğer ortamda. |
404 | physical_pos.device.not_found | Cihaz yok, size ait değil ya da diğer ortamda. |
409 | physical_pos.terminal.closed | Terminal kapatılmış. |
409 | physical_pos.terminal.device_already_linked | Cihaz zaten bu terminale bağlı. |
409 | physical_pos.terminal.link_conflict | Cihaz başka bir terminale bağlı. |
409 | physical_pos.terminal.device_not_linked | Çözülecek bağ yok. |
409 | physical_pos.device.retired | Cihaz emekliye ayrılmış. |
409 | physical_pos.version_conflict | Terminalin rowVersion değeri güncel değil. |
409 | physical_pos.idempotency_mismatch | Aynı Idempotency-Key farklı bir istekle kullanılmış. |
429 | RATE_LIMITED | Yazma sınırı aşıldı. → Oran sınırı |
Bütün kodlar: Hata Kodları.