Mantıksal Terminaller
- 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.
Mantıksal terminal, ödeme kabul eden kimliktir: terminal kodu, POS üreticisi, üretici tarafındaki terminal kimlikleri ve bankalardaki üye işyeri ve terminal numaraları bu kayıtta durur. Fiziksel cihaz değişse de terminal ve banka bilgileri aynı kalır. → Temel kavramlar
Terminaller anahtarınızın ortamındadır: anahtar yalnız kendi ortamındaki terminalleri görür. Test anahtarı terminalleri yalnız okur; yazma istekleri 403 physical_pos.environment.test_key_read_only alır. → Ortamlar
| Yöntem | Yol | Kapsam |
|---|---|---|
GET | /api/v1/physical-pos/terminals | physical_pos:view |
POST | /api/v1/physical-pos/terminals | physical_pos:manage |
GET | /api/v1/physical-pos/terminals/{terminalId} | physical_pos:view |
PATCH | /api/v1/physical-pos/terminals/{terminalId} | physical_pos:manage |
POST | /api/v1/physical-pos/terminals/{terminalId}/close | physical_pos:manage |
GET | /api/v1/physical-pos/terminals/{terminalId}/audit | physical_pos:view |
Banka satırları: Banka Satırları · Cihaz bağı: Cihaz Bağı. cURL örnekleri imzayı lunixi-sign.sh ile hesaplar: Kimlik Doğrulama › İmza yardımcısı.
Terminal nesnesi
| Alan | Tip | Açıklama |
|---|---|---|
id | string (UUID) | Terminalin kimliği. |
terminalCode | string | Terminal kodu; büyük harfli, ortam içinde tekil. Oluşturulduktan sonra değişmez. |
displayName | string | Görünen ad. |
environment | string | TEST ya da LIVE; anahtarınızın ortamı. |
vendorCode | string | null | POS üreticisinin kodu (ör. PAVO). Atanmadıysa null. |
virtualSerial | string | null | Üreticinin bu terminale verdiği sanal seri numarası. |
vendorTerminalRef | string | null | Üreticinin sisteminde bu terminalin kimliği. |
ownershipStatus | string | UNVERIFIED: terminalin size ait olduğu henüz doğrulanmadı. VERIFIED: doğrulandı. |
terminalStatus | string | ACTIVE, SUSPENDED (geçici olarak durdurulmuş) ya da CLOSED (kapatılmış; geri alınamaz). |
linkedDevice | object | null | Terminale bağlı cihaz; bağlı cihaz yoksa null. Aşağıya bakın. |
rowVersion | integer | Eşzamanlılık sürümü. → rowVersion |
createdAt | string | Oluşturulma zamanı. |
updatedAt | string | Son değişiklik zamanı. |
closedAt | string | null | Kapatılma zamanı. |
linkedDevice
| Alan | Tip | Açıklama |
|---|---|---|
linkId | string (UUID) | Açık cihaz bağının kimliği. |
deviceId | string (UUID) | Bağlı cihazın kimliği. |
displayName | string | null | Cihazın görünen adı. |
serialNumber | string | Cihazın seri numarası. |
lifecycleStatus | string | Cihazın durumu: PENDING, ACTIVE, SUSPENDED, MAINTENANCE ya da RETIRED. |
linkedAt | string | Bağın açıldığı zaman. |
Terminalleri listeleme
GET /api/v1/physical-pos/terminals
| Sorgu parametresi | Tip | Açıklama |
|---|---|---|
status | string | ACTIVE, SUSPENDED ya da CLOSED. Gönderilmezse hepsi döner. Başka değer 400 physical_pos.input.filter_invalid. |
q | string | Terminal kodunun ya da görünen adın başıyla eşleşen kayıtlar, en çok 64 karakter. |
limit | integer | Sayfa başına kayıt, 1–100. Varsayılan 25. |
cursor | string | Önceki yanıttaki pageInfo.nextCursor. |
includeTotal | boolean | true ise pageInfo.totalCount doldurulur. |
source lunixi-sign.sh
REQ_PATH="/api/v1/physical-pos/terminals?status=ACTIVE&q=IST"
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"{
"status": "success",
"code": "SUCCESS",
"data": {
"items": [
{
"id": "00000000-0000-0000-0000-000000000301",
"terminalCode": "IST-KADIKOY-01",
"displayName": "Kadıköy Kasa 1",
"environment": "LIVE",
"vendorCode": "PAVO",
"virtualSerial": null,
"vendorTerminalRef": "PV-000123",
"ownershipStatus": "UNVERIFIED",
"terminalStatus": "ACTIVE",
"linkedDevice": null,
"rowVersion": 2,
"createdAt": "2026-01-01T07:20:00.000Z",
"updatedAt": "2026-01-02T08:00:00.000Z",
"closedAt": null
}
],
"pageInfo": { "hasMore": false, "nextCursor": null, "totalCount": null }
},
"pageInfo": { "hasMore": false, "nextCursor": null, "totalCount": null },
"statusCode": 200,
"requestId": "00000000-0000-0000-0000-000000000000"
}Terminal oluşturma
POST /api/v1/physical-pos/terminals · Idempotency-Key zorunlu
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
code | string | Evet | Terminal kodu: A-Z, 0-9, ., _, -; en çok 64 karakter. Büyük harfe çevrilir. Ortam içinde tekildir; kapatılmış terminaller de kodlarını korur. |
displayName | string | Evet | Görünen ad, en çok 120 karakter. Metin kurallarına tabidir. |
vendorCode | string | Koşullu | Katalogdaki etkin bir üreticinin kodu. virtualSerial ya da vendorTerminalRef gönderiyorsanız zorunludur. → Katalog › Üreticiler |
virtualSerial | string | Hayır | Üreticinin verdiği sanal seri: A-Z, 0-9; en çok 64 karakter. Büyük harfe çevrilir. |
vendorTerminalRef | string | Hayır | Üreticinin sistemindeki terminal kimliği: A-Z, a-z, 0-9, ., _, -; en çok 128 karakter. Büyük/küçük harf korunur. |
Gövdede environment gönderilmez; terminal anahtarınızın ortamında açılır. Yeni terminal terminalStatus: "ACTIVE" ve ownershipStatus: "UNVERIFIED" ile başlar.
source lunixi-sign.sh
REQ_PATH="/api/v1/physical-pos/terminals"
BODY='{"code":"ist-kadikoy-01","displayName":"Kadıköy Kasa 1","vendorCode":"PAVO","vendorTerminalRef":"PV-000123"}'
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-000000000003" \
--data-raw "$BODY"{
"status": "success",
"code": "SUCCESS",
"data": {
"terminal": {
"id": "00000000-0000-0000-0000-000000000301",
"terminalCode": "IST-KADIKOY-01",
"displayName": "Kadıköy Kasa 1",
"environment": "LIVE",
"vendorCode": "PAVO",
"virtualSerial": null,
"vendorTerminalRef": "PV-000123",
"ownershipStatus": "UNVERIFIED",
"terminalStatus": "ACTIVE",
"linkedDevice": null,
"rowVersion": 1,
"createdAt": "2026-01-01T07:20:00.000Z",
"updatedAt": "2026-01-01T07:20:00.000Z",
"closedAt": null
},
"replayed": false
},
"statusCode": 201,
"requestId": "00000000-0000-0000-0000-000000000000"
}| Engel | Hata |
|---|---|
| Aynı ortamda aynı kodla bir terminal var | 409 physical_pos.terminal.code_taken |
Aynı üretici ve vendorTerminalRef ile kapatılmamış bir terminaliniz var | 409 physical_pos.terminal.vendor_ref_taken |
Aynı virtualSerial ile kapatılmamış bir terminaliniz var | 409 physical_pos.terminal.virtual_serial_taken |
virtualSerial ya da vendorTerminalRef var, vendorCode yok | 400 physical_pos.terminal.vendor_required |
| Üretici katalogda yok ya da devre dışı | 400 physical_pos.device.vendor_unknown |
vendorTerminalRef ve virtualSerial tekilliği ortamdan bağımsızdır: aynı değeri bir test ve bir canlı terminalde aynı anda kullanamazsınız. Terminal kapatıldığında bu değerler serbest kalır.
Terminal ayrıntısı
GET /api/v1/physical-pos/terminals/{terminalId}
Terminal nesnesine ek olarak doğrulama bilgisi ve banka satırlarının ilk sayfası (en çok 100 satır) döner:
{
"status": "success",
"code": "SUCCESS",
"data": {
"terminal": {
"id": "00000000-0000-0000-0000-000000000301",
"terminalCode": "IST-KADIKOY-01",
"displayName": "Kadıköy Kasa 1",
"environment": "LIVE",
"vendorCode": "PAVO",
"virtualSerial": null,
"vendorTerminalRef": "PV-000123",
"ownershipStatus": "UNVERIFIED",
"terminalStatus": "ACTIVE",
"linkedDevice": null,
"rowVersion": 1,
"createdAt": "2026-01-01T07:20:00.000Z",
"updatedAt": "2026-01-01T07:20:00.000Z",
"closedAt": null,
"verifiedAt": null,
"verifiedVia": null
},
"acquirers": {
"items": [],
"pageInfo": { "hasMore": false, "nextCursor": null, "totalCount": null }
}
},
"statusCode": 200,
"requestId": "00000000-0000-0000-0000-000000000000"
}| Alan | Açıklama |
|---|---|
terminal.verifiedAt | Sahipliğin doğrulandığı zaman; doğrulanmadıysa null. |
terminal.verifiedVia | Doğrulamanın kaynağı: DEVICE, VENDOR_ACCOUNT ya da OPERATOR; doğrulanmadıysa null. |
acquirers | Banka satırlarının ilk sayfası. acquirers.pageInfo.hasMore true ise kalan satırları banka satırı listesinden cursor ile okuyun. |
Olmayan, başka bir organizasyona ya da diğer ortama ait terminal 404 physical_pos.terminal.not_found döner.
Terminal güncelleme ve üretici atama
PATCH /api/v1/physical-pos/terminals/{terminalId}
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
rowVersion | integer | Evet | Son okuduğunuz rowVersion. |
displayName | string | Hayır | Yeni görünen ad, en çok 120 karakter. |
vendorCode | string | Hayır | Üreticisiz oluşturulmuş terminale üretici atar. Aşağıya bakın. |
displayName ya da vendorCode alanlarından en az biri gönderilmelidir; ikisi de yoksa 400 physical_pos.input.empty_patch. Gönderilen değerler mevcut değerlerle aynıysa kayıt değişmez, rowVersion artmaz, değişiklik geçmişine olay yazılmaz ve 200 döner.
Üretici bir kez atanır. Üreticisi olmayan bir terminale vendorCode ile üretici atayabilirsiniz; atandıktan sonra değişmez:
- Terminalin henüz banka satırı olmamalıdır.
- Terminale bağlı bir cihaz varsa, atanan üretici cihazın üreticisiyle aynı olmalıdır; değilse
400 physical_pos.terminal.device_vendor_mismatch. - Üreticisi zaten olan terminale aynı kodu göndermek değişiklik sayılmaz. Farklı kod
409 physical_pos.record.field_immutablealır. - Banka satırı olan üreticisiz terminale atama da
409 physical_pos.record.field_immutablealır.
source lunixi-sign.sh
REQ_PATH="/api/v1/physical-pos/terminals/00000000-0000-0000-0000-000000000301"
BODY='{"rowVersion":1,"displayName":"Kadıköy Ana Kasa"}'
lunixi_sign PATCH "$REQ_PATH" "$BODY"
curl -X PATCH "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"Yanıt: { "terminal": { … } }. Kapatılmış terminal güncellenemez: 409 physical_pos.terminal.closed.
Terminali kapatma
POST /api/v1/physical-pos/terminals/{terminalId}/close
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
rowVersion | integer | Evet | Son okuduğunuz rowVersion. |
reasonCode | string | Evet | MERCHANT_REQUEST, CONTRACT_ENDED, BANK_TERMINATED, CREATED_IN_ERROR, DUPLICATE_RECORD, MIGRATED, OTHER. → Gerekçe kodları |
Kapatma geri alınamaz. Aynı işlemde terminalin etkin banka satırları DISABLED olur; terminalin bağlı cihazı varsa bağ kapanır. Kapatılmış terminal güncellenemez, banka satırı eklenemez ve cihaz bağlanamaz; kodu kullanımda kalır.
source lunixi-sign.sh
REQ_PATH="/api/v1/physical-pos/terminals/00000000-0000-0000-0000-000000000301/close"
BODY='{"rowVersion":4,"reasonCode":"CONTRACT_ENDED"}'
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"Yanıt: { "terminal": { … } }, terminalStatus: "CLOSED", closedAt dolu, linkedDevice: null. Terminal zaten kapalıysa 409 physical_pos.terminal.closed.
Değişiklik geçmişi
GET /api/v1/physical-pos/terminals/{terminalId}/audit — limit ve cursor alır. Terminalin kendi olaylarını ve banka satırlarının olaylarını birlikte döner:
{
"status": "success",
"code": "SUCCESS",
"data": {
"items": [
{
"id": "00000000-0000-0000-0000-000000000902",
"action": "physical_pos.audit.terminal_acquirer_added",
"entityType": "terminal_acquirer",
"entityId": "00000000-0000-0000-0000-000000000601",
"actorType": "API_KEY",
"actorId": "kid:mk_live_00000000",
"reasonCode": null,
"changes": {
"logicalTerminalId": "00000000-0000-0000-0000-000000000301",
"vendorAcquirerRef": "B01",
"acquirerNo": "0000",
"mappingStatus": "MAPPED",
"merchantNumber": "000000000000001",
"terminalNumber": "PS000001",
"currencyCount": 1,
"labelChanged": true,
"source": "MANUAL",
"verificationStatus": "UNVERIFIED",
"toStatus": "ACTIVE"
},
"environment": "LIVE",
"createdAt": "2026-01-01T07:30:00.000Z"
}
],
"pageInfo": { "hasMore": false, "nextCursor": null, "totalCount": null }
},
"pageInfo": { "hasMore": false, "nextCursor": null, "totalCount": null },
"statusCode": 200,
"requestId": "00000000-0000-0000-0000-000000000000"
}entityType | Olaylar (action) |
|---|---|
logical_terminal | physical_pos.audit.logical_terminal_created, …logical_terminal_updated, …logical_terminal_closed, …logical_terminal_device_changed, …logical_terminal_device_unlinked |
terminal_acquirer | physical_pos.audit.terminal_acquirer_added, …terminal_acquirer_updated, …terminal_acquirer_disabled (terminal kapatılırken) |
Alanların anlamı: Ortak Kurallar › Değişiklik geçmişi.
Hatalar
| HTTP | code | Ne zaman |
|---|---|---|
400 | physical_pos.idempotency.key_required / physical_pos.idempotency.key_invalid | Oluşturmada Idempotency-Key yok ya da biçim dışı. |
400 | physical_pos.input.code_invalid | code biçim dışı. |
400 | physical_pos.input.text_invalid | displayName kurala uymuyor. |
400 | physical_pos.input.filter_invalid | Liste süzgeci (status, q) geçersiz. |
400 | physical_pos.input.vendor_code_invalid | vendorCode biçim dışı. |
400 | physical_pos.input.virtual_serial_invalid | virtualSerial biçim dışı. |
400 | physical_pos.input.ref_invalid | vendorTerminalRef biçim dışı. |
400 | physical_pos.input.reason_code_invalid | reasonCode listede yok. |
400 | physical_pos.device.vendor_unknown | Üretici katalogda yok ya da devre dışı. |
400 | physical_pos.terminal.vendor_required | Üretici kimliği verildi ama vendorCode yok. |
400 | physical_pos.terminal.device_vendor_mismatch | Atanan üretici bağlı cihazın üreticisinden farklı. |
400 | physical_pos.input.empty_patch | Boş güncelleme. |
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. |
409 | physical_pos.terminal.code_taken | Kod bu ortamda kullanımda. |
409 | physical_pos.terminal.vendor_ref_taken | vendorTerminalRef açık bir terminalde kullanımda. |
409 | physical_pos.terminal.virtual_serial_taken | virtualSerial açık bir terminalde kullanımda. |
409 | physical_pos.terminal.closed | Kapatılmış terminal değiştirilmek istendi. |
409 | physical_pos.record.field_immutable | Üretici zaten atanmış ya da terminalin banka satırı var. |
409 | physical_pos.version_conflict | rowVersion güncel değil. |
409 | physical_pos.idempotency_mismatch | Aynı Idempotency-Key farklı bir istekle kullanılmış. |
429 | RATE_LIMITED | Terminal ailesi yazma sınırı aşıldı. → Oran sınırı |
Bütün kodlar: Hata Kodları.