{"openapi":"3.0.1","info":{"title":"PayGlobe ServerPOS API (Internal)","description":"# ServerPOS API - Documentazione Interna\n\n**RISERVATO - Non condividere con terze parti**\n\nServerPOS è un sistema unificato per la gestione di:\n- **Pagamenti POS** (CARD, SATISPAY, VOUCHER)\n- **Ricevute fiscali** (A-Cube)\n- **PayByLink** tramite IGFS\n- **Gestione Partner** con autenticazione API Key\n\n## Autenticazione\n\n### Basic Authentication (Terminali POS)\nPer endpoint terminal:\n- `/{terminalId}/pay` - Invio pagamento\n- `/{terminalId}/get` - Polling dati\n- `/{terminalId}/receipt` - Salvataggio ricevuta\n\n### API Key (Partner/PayByLink)\nHeader: `API-Key: pk_live_xxxxx`\n\n## WebSocket STOMP\n- Endpoint: `/ws`\n- Topics: `/topic/terminal/{terminalId}`\n","contact":{"name":"PayGlobe Support","url":"https://www.payglobe.co","email":"support@payglobe.co"},"license":{"name":"Proprietary","url":"https://www.payglobe.co/terms"},"version":"1.0.0"},"servers":[{"url":"https://ricevute.payglobe.it/serverpos","description":"Production Server"},{"url":"http://localhost:9700","description":"Development Server"}],"security":[{"basicAuth":[],"apiKey":[]}],"tags":[{"name":"App Auto-Update","description":"Public API for Android POS app auto-update system"},{"name":"Partner Portal","description":"Partner self-service APIs"},{"name":"PayByLink API","description":"API per la creazione di link di pagamento tramite IGFS di N&TS S.p.A.\n\n**Autenticazione richiesta:** API Key (header `API-Key`)\n\nIl sistema supporta configurazioni multi-partner, ognuno con credenziali IGFS dedicate.\n"},{"name":"Terminal API","description":"API per gestione pagamenti e ricevute dei terminali POS"},{"name":"Partner Management API","description":"API per la gestione dei partner e delle loro API Key.\n\n**Autenticazione richiesta:** Basic Auth (credenziali amministrative)\n\nOgni partner ha:\n- Username e password per accesso admin\n- API Key per autenticazione API PayByLink\n- Credenziali IGFS dedicate (TML, API Key, Secret Key)\n- Flag enabled/disabled\n"},{"name":"Logs","description":"Endpoint per ricevere log dai terminali"},{"name":"App Version Management","description":"Admin API for managing app versions and deployments"},{"name":"Admin API","description":"API per amministrazione e monitoring del sistema ServerPOS.\n\n**Autenticazione richiesta:** Basic Auth (credenziali amministrative)\n\nFornisce:\n- Statistiche dashboard\n- Lista terminali attivi\n- Gestione sessioni Redis\n- Gestione ricevute\n- Monitoring WebSocket\n- Monitoring ZVT ECR Listener\n"}],"paths":{"/admin/api/partners/{id}":{"get":{"tags":["Partner Management API"],"operationId":"getPartner","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]},"put":{"tags":["Partner Management API"],"operationId":"updatePartner","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiPartner"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]},"delete":{"tags":["Partner Management API"],"operationId":"deletePartner","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]}},"/serverpos/pay":{"post":{"tags":["deprecated-endpoints-controller"],"operationId":"deprecatedPayEndpoint","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/pay":{"post":{"tags":["deprecated-endpoints-controller"],"operationId":"deprecatedPayEndpoint_1","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/v1/{terminalId}/scan":{"post":{"tags":["Terminal API"],"summary":"Invia richiesta di scansione barcode/QR","description":"Invia un comando SCAN al terminale. L'app Android apre la fotocamera,\nscansiona un barcode/QR e restituisce il valore tramite POST /receipt.\n\nIl partner può recuperare il risultato tramite polling su GET /{uuid}/uuid.\nTimeout consigliato: 60 secondi.\n","operationId":"scan","parameters":[{"name":"terminalId","in":"path","description":"ID univoco del terminale POS","required":true,"schema":{"type":"string"},"example":91010001}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/serverpos/api/v1/{terminalId}/scan":{"post":{"tags":["Terminal API"],"summary":"Invia richiesta di scansione barcode/QR","description":"Invia un comando SCAN al terminale. L'app Android apre la fotocamera,\nscansiona un barcode/QR e restituisce il valore tramite POST /receipt.\n\nIl partner può recuperare il risultato tramite polling su GET /{uuid}/uuid.\nTimeout consigliato: 60 secondi.\n","operationId":"scan_1","parameters":[{"name":"terminalId","in":"path","description":"ID univoco del terminale POS","required":true,"schema":{"type":"string"},"example":91010001}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/api/v1/{terminalId}/receipt":{"post":{"tags":["Terminal API"],"operationId":"receipt","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseString"}}}}},"security":[{"basicAuth":[]}]}},"/serverpos/api/v1/{terminalId}/receipt":{"post":{"tags":["Terminal API"],"operationId":"receipt_1","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseString"}}}}},"security":[{"basicAuth":[]}]}},"/api/v1/{terminalId}/print":{"post":{"tags":["Terminal API"],"summary":"Invia richiesta di stampa testo","description":"Invia un comando PRINT al terminale con testo formattato.\nL'app Android stampa il testo sulla stampante termica integrata\ne restituisce l'esito tramite POST /receipt.\n\nIl partner può recuperare il risultato tramite polling su GET /{uuid}/uuid.\nTimeout consigliato: 30 secondi.\n","operationId":"print","parameters":[{"name":"terminalId","in":"path","description":"ID univoco del terminale POS","required":true,"schema":{"type":"string"},"example":91010001}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/serverpos/api/v1/{terminalId}/print":{"post":{"tags":["Terminal API"],"summary":"Invia richiesta di stampa testo","description":"Invia un comando PRINT al terminale con testo formattato.\nL'app Android stampa il testo sulla stampante termica integrata\ne restituisce l'esito tramite POST /receipt.\n\nIl partner può recuperare il risultato tramite polling su GET /{uuid}/uuid.\nTimeout consigliato: 30 secondi.\n","operationId":"print_1","parameters":[{"name":"terminalId","in":"path","description":"ID univoco del terminale POS","required":true,"schema":{"type":"string"},"example":91010001}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/api/v1/{terminalId}/paybylink":{"post":{"tags":["Terminal API"],"operationId":"payByLink","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/serverpos/api/v1/{terminalId}/paybylink":{"post":{"tags":["Terminal API"],"operationId":"payByLink_1","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/serverpos/api/v1/{terminalId}/paybpe":{"post":{"tags":["Terminal API"],"operationId":"payBpe","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/api/v1/{terminalId}/paybpe":{"post":{"tags":["Terminal API"],"operationId":"payBpe_1","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/serverpos/api/v1/{terminalId}/pay":{"post":{"tags":["Terminal API"],"summary":"Invio richiesta di pagamento","description":"Endpoint principale per l'invio di richieste di pagamento dal terminale POS.\n\nSupporta tutti i tipi di pagamento:\n- **CARD**: Pagamento con carta (contactless, chip, banda magnetica)\n- **SATISPAY**: Pagamento tramite Satispay\n- **VOUCHER**: Buoni pasto elettronici\n- **RECEIPT**: Emissione ricevuta fiscale\n\n**Campo opzionale `cardType`** (solo per pagamenti CARD):\n- `0` = Automatico (default) - il POS sceglie il circuito\n- `1` = Solo Debito (PagoBancomat)\n- `2` = Solo Credito (Visa/Mastercard/Amex)\n- Se omesso, equivale a `0` (retrocompatibile)\n\nIl payload viene temporaneamente salvato su Redis e reso disponibile per il polling\ntramite l'endpoint GET /{terminalId}/get.\n\n**Protezioni:**\n- Rate limiting: max 10 req/sec per IP\n- Controllo UUID duplicati\n- Basic Authentication richiesta\n","operationId":"pay","parameters":[{"name":"terminalId","in":"path","description":"ID univoco del terminale POS","required":true,"schema":{"type":"string"},"example":"PG001"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"},"description":"Payload del pagamento (formato JSON flessibile)"}}},"required":true},"responses":{"400":{"description":"UUID duplicato - richiesta già processata","content":{"application/json":{"example":{"status":"error","error":"Duplicate payment request - UUID already processed"}}}},"401":{"description":"Autenticazione fallita","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}},"429":{"description":"Rate limit superato","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}},"200":{"description":"Pagamento accettato e salvato in Redis","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"},"example":{"status":"ok","data":{"terminalID":"PG001","received":{"uuid":"550e8400-e29b-41d4-a716-446655440000","amount":1500,"type":"CARD","cardType":0}}}}}}},"security":[{"basicAuth":[]}]}},"/api/v1/{terminalId}/pay":{"post":{"tags":["Terminal API"],"summary":"Invio richiesta di pagamento","description":"Endpoint principale per l'invio di richieste di pagamento dal terminale POS.\n\nSupporta tutti i tipi di pagamento:\n- **CARD**: Pagamento con carta (contactless, chip, banda magnetica)\n- **SATISPAY**: Pagamento tramite Satispay\n- **VOUCHER**: Buoni pasto elettronici\n- **RECEIPT**: Emissione ricevuta fiscale\n\n**Campo opzionale `cardType`** (solo per pagamenti CARD):\n- `0` = Automatico (default) - il POS sceglie il circuito\n- `1` = Solo Debito (PagoBancomat)\n- `2` = Solo Credito (Visa/Mastercard/Amex)\n- Se omesso, equivale a `0` (retrocompatibile)\n\nIl payload viene temporaneamente salvato su Redis e reso disponibile per il polling\ntramite l'endpoint GET /{terminalId}/get.\n\n**Protezioni:**\n- Rate limiting: max 10 req/sec per IP\n- Controllo UUID duplicati\n- Basic Authentication richiesta\n","operationId":"pay_1","parameters":[{"name":"terminalId","in":"path","description":"ID univoco del terminale POS","required":true,"schema":{"type":"string"},"example":"PG001"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"},"description":"Payload del pagamento (formato JSON flessibile)"}}},"required":true},"responses":{"400":{"description":"UUID duplicato - richiesta già processata","content":{"application/json":{"example":{"status":"error","error":"Duplicate payment request - UUID already processed"}}}},"401":{"description":"Autenticazione fallita","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}},"429":{"description":"Rate limit superato","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}},"200":{"description":"Pagamento accettato e salvato in Redis","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"},"example":{"status":"ok","data":{"terminalID":"PG001","received":{"uuid":"550e8400-e29b-41d4-a716-446655440000","amount":1500,"type":"CARD","cardType":0}}}}}}},"security":[{"basicAuth":[]}]}},"/api/v1/{terminalId}/disconnect":{"post":{"tags":["Terminal API"],"summary":"Segnala disconnessione terminale","description":"Endpoint che il POS chiama quando l'app si sta chiudendo (onDestroy/onStop).\nRimuove immediatamente il heartbeat Redis → il terminale risulta OFFLINE istantaneamente.\n\n**Uso:** Chiamare da `onDestroy()` o `onStop()` dell'Activity Android.\n","operationId":"disconnect","parameters":[{"name":"terminalId","in":"path","description":"ID univoco del terminale POS","required":true,"schema":{"type":"string"},"example":90011004}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/serverpos/api/v1/{terminalId}/disconnect":{"post":{"tags":["Terminal API"],"summary":"Segnala disconnessione terminale","description":"Endpoint che il POS chiama quando l'app si sta chiudendo (onDestroy/onStop).\nRimuove immediatamente il heartbeat Redis → il terminale risulta OFFLINE istantaneamente.\n\n**Uso:** Chiamare da `onDestroy()` o `onStop()` dell'Activity Android.\n","operationId":"disconnect_1","parameters":[{"name":"terminalId","in":"path","description":"ID univoco del terminale POS","required":true,"schema":{"type":"string"},"example":90011004}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/serverpos/api/v1/pay":{"post":{"tags":["Terminal API"],"operationId":"payWithTerminalInBody","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"},"description":"Payload con terminalId nel body JSON"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/api/v1/pay":{"post":{"tags":["Terminal API"],"operationId":"payWithTerminalInBody_1","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"},"description":"Payload con terminalId nel body JSON"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/api/v1/{terminalId}/logs":{"get":{"tags":["Logs"],"summary":"Recupera log di un terminale (Admin)","operationId":"getLogs","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Logs"],"summary":"Ricevi log da terminale Android","operationId":"receiveLogs","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Terminal-ID","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Device-Model","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-App-Version","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Device-Serial","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Android-Version","in":"header","required":false,"schema":{"type":"string"}},{"name":"X-Manufacturer","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"delete":{"tags":["Logs"],"summary":"Elimina log di un terminale (Admin)","operationId":"deleteLogs","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/v1/payment/verify/{txId}":{"post":{"tags":["PayByLink API"],"operationId":"verifyPayment","parameters":[{"name":"API-Key","in":"header","required":false,"schema":{"type":"string"}},{"name":"txId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string"}}}}},"security":[{"apiKey":[]}]}},"/api/v1/paybylink":{"post":{"tags":["PayByLink API"],"summary":"Crea link di pagamento PayByLink","description":"Crea un link di pagamento tramite IGFS per consentire pagamenti remoti con carta.\n\n**Autenticazione:**\nRichiede header `API-Key` valido. Ogni partner ha credenziali IGFS dedicate.\n\n**Flusso:**\n1. Il sistema valida l'API Key e recupera le credenziali IGFS del partner\n2. Crea una richiesta di pagamento su IGFS\n3. IGFS restituisce l'URL del payment link\n4. Il sistema salva la transazione nel database locale\n5. Restituisce l'URL al client\n\n**Notifiche:**\n- Webhook IGFS: `/api/igfs/notify` (chiamato da IGFS dopo il pagamento)\n- Il sistema verifica automaticamente lo stato del pagamento\n\n**Grace Period:**\nSe il webhook non arriva, il sistema verifica lo stato dopo 5 minuti.\n","operationId":"createPaymentLink","parameters":[{"name":"API-Key","in":"header","description":"API Key per autenticazione partner","required":true,"schema":{"type":"string"},"example":"pk_live_abcd1234..."}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayByLinkRequest"}}},"required":true},"responses":{"200":{"description":"Link di pagamento creato con successo","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayByLinkResponse"},"example":{"status":"ok","txId":"PBL_20250113_123456_ABC","paymentUrl":"https://paymentgateway.igfspg.com/v2/ui/index.html?id=...","amount":"15.00","currency":"EUR","terminalID":"PG001","description":"Acquisto prodotti","createdAt":"2025-01-13T15:30:00"}}}},"400":{"description":"Richiesta non valida o errore IGFS","content":{"application/json":{"example":{"status":"error","error":"Invalid request parameters"}}}},"500":{"description":"Errore interno del server o IGFS non disponibile","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PayByLinkResponse"}}}},"401":{"description":"API Key non valida o mancante","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PayByLinkResponse"}}}}},"security":[{"apiKey":[]}]}},"/api/v1/igfs/notify":{"post":{"tags":["PayByLink API"],"operationId":"handleIgfsNotification","parameters":[{"name":"merId","in":"query","required":false,"schema":{"type":"string"}},{"name":"txId","in":"query","required":true,"schema":{"type":"string"}},{"name":"paymentId","in":"query","required":false,"schema":{"type":"string"}},{"name":"signature","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}},"security":[{"apiKey":[]}]}},"/api/v1/app/install-log":{"post":{"tags":["App Auto-Update"],"summary":"Log install completion","description":"L'app Android chiama questo endpoint dopo aver completato (o fallito) l'installazione\ndi una nuova versione. Usato per tracking adozione versioni e analytics.\n","operationId":"logInstall","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseString"}}}}}}},"/api/partner/regenerate-key":{"post":{"tags":["Partner Portal"],"summary":"Regenerate API Key for current partner","operationId":"regenerateApiKey","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]}},"/api/partner/payglobe-credentials":{"get":{"tags":["Partner Portal"],"summary":"Get partner's PayGlobe credentials","operationId":"getPayGlobeCredentials","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"basicAuth":[]}]},"post":{"tags":["Partner Portal"],"summary":"Create/update partner's PayGlobe credential","operationId":"savePayGlobeCredential","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"basicAuth":[]}]}},"/api/partner/payglobe-credentials/test":{"post":{"tags":["Partner Portal"],"summary":"Test PayGlobe credential","operationId":"testPayGlobeCredential","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"basicAuth":[]}]}},"/api/partner/origins":{"post":{"tags":["Partner Portal"],"summary":"Update allowed origins for API Key restriction","operationId":"updateOrigins","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]}},"/admin/zvt/config":{"post":{"tags":["Admin API"],"summary":"Update ZVT configuration","description":"Aggiorna la configurazione del listener ZVT.\n\n**NOTA:** Per applicare le modifiche è necessario riavviare l'applicazione.\n\nParametri configurabili:\n- enabled: Abilita/Disabilita listener\n- port: Porta TCP (default: 40007)\n- timeoutSeconds: Timeout operazioni (secondi)\n- maxConnections: Max connessioni simultanee\n- loggingLevel: Livello log (DEBUG, INFO, WARN, ERROR)\n- logRawBytes: Log byte raw (true/false)\n","operationId":"updateZvtConfig","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/terminal/{terminalId}/command":{"post":{"tags":["Admin API"],"summary":"Invia comando a terminale (HTTP polling fallback)","description":"Inserisce un comando in coda per il terminale specificato.\n\nIl terminale riceverà il comando al prossimo GET polling.\n\nPayload esempio:\n{\n  \"uuid\": \"LOG_TEST_001\",\n  \"service\": \"LOGCAT\",\n  \"amount\": 0\n}\n\nUsato come fallback quando WebSocket non è disponibile.\n","operationId":"sendCommandToTerminal","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/terminal-groups":{"get":{"tags":["Admin API"],"summary":"Get all terminal groups","description":"Returns all configured multi-TID terminal groups","operationId":"getAllTerminalGroups","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListTerminalGroup"}}}}},"security":[{"basicAuth":[]}]},"post":{"tags":["Admin API"],"summary":"Create/Update terminal group","description":"Create or update a multi-TID terminal group configuration","operationId":"saveTerminalGroup","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TerminalGroupRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseTerminalGroup"}}}}},"security":[{"basicAuth":[]}]}},"/admin/terminal-groups/test":{"post":{"tags":["Admin API"],"summary":"Test terminal group","description":"Test if a terminal can manage another terminal ID","operationId":"testTerminalGroup","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TerminalGroupTestRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/subscription-rules":{"get":{"tags":["Admin API"],"summary":"Lista regole whitelist subscription","description":"Restituisce tutte le regole di whitelist per le sottoscrizioni WebSocket STOMP.\n\nOgni regola definisce quali topic un terminalId può sottoscrivere:\n- ANY: Permette sottoscrizione a qualsiasi topic (default)\n- LIST: Lista esplicita CSV di terminalId autorizzati\n- REGEX: Pattern regex per matching terminalId\n","operationId":"getAllSubscriptionRules","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListTerminalSubscriptionRule"}}}}},"security":[{"basicAuth":[]}]},"post":{"tags":["Admin API"],"summary":"Crea/aggiorna regola whitelist","description":"Crea o aggiorna una regola di whitelist per un terminalId.\n\nPayload esempio - Lista esplicita:\n{\n  \"terminalId\": \"90011005\",\n  \"ruleType\": \"LIST\",\n  \"ruleValue\": \"90011005,90011006,90011007\",\n  \"enabled\": true,\n  \"notes\": \"Multi-device POS\"\n}\n\nPayload esempio - Pattern regex:\n{\n  \"terminalId\": \"90011005\",\n  \"ruleType\": \"REGEX\",\n  \"ruleValue\": \"9001100[5-7]\",\n  \"enabled\": true,\n  \"notes\": \"Device family 5-7\"\n}\n\nPayload esempio - Permetti tutto:\n{\n  \"terminalId\": \"90011005\",\n  \"ruleType\": \"ANY\",\n  \"enabled\": true,\n  \"notes\": \"Admin terminal\"\n}\n","operationId":"createOrUpdateSubscriptionRule","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TerminalSubscriptionRule"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseTerminalSubscriptionRule"}}}}},"security":[{"basicAuth":[]}]}},"/admin/subscription-rules/test":{"post":{"tags":["Admin API"],"summary":"Testa validazione subscription","description":"Testa se un terminalId può sottoscrivere un topic specifico.\n\nPayload esempio:\n{\n  \"authenticatedTerminalId\": \"90011005\",\n  \"topicDestination\": \"/topic/terminal/90011006\"\n}\n\nRisposta:\n{\n  \"allowed\": true,\n  \"authenticatedTerminalId\": \"90011005\",\n  \"topicDestination\": \"/topic/terminal/90011006\",\n  \"targetTerminalId\": \"90011006\"\n}\n","operationId":"testSubscription","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/redis-sessions/clear":{"post":{"tags":["Admin API"],"operationId":"clearRedisSessions","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseString"}}}}},"security":[{"basicAuth":[]}]}},"/admin/receipts/clean":{"post":{"tags":["Admin API"],"operationId":"cleanOldReceipts","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":90}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringInteger"}}}}},"security":[{"basicAuth":[]}]}},"/admin/payglobe-credentials":{"get":{"tags":["Admin API"],"operationId":"getAllPayGlobeCredentials","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]},"post":{"tags":["Admin API"],"operationId":"savePayGlobeCredential_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayGlobeCredentialRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]}},"/admin/payglobe-credentials/test":{"post":{"tags":["Admin API"],"operationId":"testPayGlobeCredential_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayGlobeCredentialRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]}},"/admin/cloud-configs":{"get":{"tags":["Admin API"],"operationId":"getCloudConfigs","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListTerminalCloudConfig"}}}}},"security":[{"basicAuth":[]}]},"post":{"tags":["Admin API"],"operationId":"saveCloudConfig","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TerminalCloudConfig"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseTerminalCloudConfig"}}}}},"security":[{"basicAuth":[]}]}},"/admin/app-versions":{"get":{"tags":["App Version Management"],"summary":"List all versions","description":"Ritorna lista di tutte le versioni app (attive e non) ordinate per versionCode DESC.","operationId":"listVersions","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListAppVersion"}}}}},"security":[{"basicAuth":[]}]},"post":{"tags":["App Version Management"],"summary":"Create new version","description":"Crea nuova versione app nel database. Il file APK deve essere caricato separatamente\ntramite endpoint /admin/app-versions/{id}/upload-apk.\n\napkUrl viene generato automaticamente usando serverpos.public.url da application.properties.\n","operationId":"createVersion","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseAppVersion"}}}}},"security":[{"basicAuth":[]}]}},"/admin/app-versions/{versionId}/upload-apk":{"post":{"tags":["App Version Management"],"summary":"Upload APK file","description":"Carica file APK per una versione specifica. Il file viene salvato nella directory\nconfigurata in serverpos.apk.storage.path (default: /opt/serverPOS/apk-files/).\n\nViene calcolato automaticamente MD5 e dimensione file.\n","operationId":"uploadApk","parameters":[{"name":"versionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseString"}}}}},"security":[{"basicAuth":[]}]}},"/admin/app-versions/{versionId}/push-update":{"post":{"tags":["App Version Management"],"summary":"Push update via WebSocket","description":"Invia notifica FORCE_UPDATE ai terminal tramite WebSocket STOMP.\n\n- Se terminalId è specificato: push solo a quel terminal\n- Se terminalId è null: push a TUTTI i terminal connessi (broadcast)\n\nIl messaggio WebSocket contiene URL download APK configurabile dal server.\nL'app Android deve sempre usare l'URL ricevuto dal server, mai hardcodato.\n","operationId":"pushUpdate","parameters":[{"name":"versionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushUpdateRequest"}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/app-versions/{versionId}/deploy-terminal":{"post":{"tags":["App Version Management"],"summary":"Deploy to specific terminal","description":"Crea deploy di una versione per un terminal specifico.\nQuesto terminal riceverà questa versione ignorando deploy globali o per merchant.\n","operationId":"deployToTerminal","parameters":[{"name":"versionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeployRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseAppDeployment"}}}}},"security":[{"basicAuth":[]}]}},"/admin/app-versions/{versionId}/deploy-merchant":{"post":{"tags":["App Version Management"],"summary":"Deploy to specific merchant","description":"Crea deploy di una versione per tutti i terminal di un merchant specifico.\nTutti i terminal di questo merchant riceveranno questa versione.\n","operationId":"deployToMerchant","parameters":[{"name":"versionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeployRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseAppDeployment"}}}}},"security":[{"basicAuth":[]}]}},"/admin/app-versions/{versionId}/deploy-global":{"post":{"tags":["App Version Management"],"summary":"Deploy globally","description":"Crea deploy globale di una versione per TUTTI i terminal.\nQuesta versione verrà offerta a tutti i terminal che non hanno deploy specifici.\n","operationId":"deployGlobal","parameters":[{"name":"versionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseAppDeployment"}}}}},"security":[{"basicAuth":[]}]}},"/admin/api/partners":{"get":{"tags":["Partner Management API"],"operationId":"listPartners","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]},"post":{"tags":["Partner Management API"],"summary":"Crea nuovo partner","description":"Crea un nuovo partner con credenziali IGFS dedicate.\n\n**Cosa viene generato automaticamente:**\n- Password casuale (restituita nella risposta, da comunicare al partner)\n- API Key univoca per le chiamate API PayByLink\n- Hash BCrypt della password per sicurezza\n\n**Campi richiesti:**\n- username: Nome utente univoco\n- igfsTml: TML (Terminal Merchant Location) IGFS\n- igfsApiKey: API Key IGFS\n- igfsSecretKey: Secret Key IGFS\n\n**Nota di sicurezza:**\nLa password in chiaro viene restituita SOLO in questa risposta.\nAssicurati di salvarla e comunicarla al partner in modo sicuro.\n","operationId":"createPartner","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiPartner"}}},"required":true},"responses":{"400":{"description":"Username già esistente o dati non validi","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}},"201":{"description":"Partner creato con successo","content":{"application/json":{"example":{"status":"ok","data":{"id":1,"username":"partner_xyz","apiKey":"pk_live_abc123...","igfsTml":"12345678","enabled":true},"generatedPassword":"X7k9mP2n","message":"Partner creato con successo"}}}},"401":{"description":"Autenticazione admin fallita","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]}},"/admin/api/partners/{id}/reset-password":{"post":{"tags":["Partner Management API"],"operationId":"resetPassword","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]}},"/admin/api/partners/{id}/generate-api-key":{"post":{"tags":["Partner Management API"],"summary":"Genera/Rigenera API Key","description":"Genera una nuova API Key per un partner esistente.\n\n**Importante:**\n- L'API Key precedente viene invalidata immediatamente\n- Tutte le richieste con la vecchia API Key falliranno\n- Comunicare la nuova API Key al partner prima di invalidare la vecchia\n\n**Formato API Key:**\n- Prefisso: `pk_live_`\n- Lunghezza totale: ~40 caratteri\n- Generazione sicura tramite SecureRandom\n\n**Use case:**\n- Rotazione periodica delle credenziali\n- Compromissione della API Key\n- Onboarding iniziale se non generata in fase di creazione\n","operationId":"generateApiKey","parameters":[{"name":"id","in":"path","description":"ID del partner","required":true,"schema":{"type":"integer","format":"int64"},"example":1}],"responses":{"200":{"description":"API Key generata con successo","content":{"application/json":{"example":{"status":"ok","apiKey":"pk_live_xyz789abc456...","message":"API Key generata con successo"}}}},"400":{"description":"Partner non trovato","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}},"401":{"description":"Autenticazione admin fallita","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]}},"/admin/app-versions/{versionId}":{"delete":{"tags":["App Version Management"],"summary":"Delete version","description":"Elimina versione e tutti i deploy associati (CASCADE).\nElimina anche il file APK fisico dal filesystem.\n","operationId":"deleteVersion","parameters":[{"name":"versionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseString"}}}}},"security":[{"basicAuth":[]}]},"patch":{"tags":["App Version Management"],"summary":"Update version fields","description":"Modifica campi di una versione esistente.\n\nCampi modificabili:\n- versionCode (Integer)\n- versionName (String)\n- mandatory (Boolean)\n- releaseNotes (String)\n\nI campi non specificati nel body rimangono invariati.\n","operationId":"updateVersion","parameters":[{"name":"versionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseAppVersion"}}}}},"security":[{"basicAuth":[]}]}},"/admin/app-versions/{versionId}/active":{"patch":{"tags":["App Version Management"],"summary":"Activate/deactivate version","description":"Abilita o disabilita una versione. Versioni disabilitate non vengono offerte ai terminal.","operationId":"setActive","parameters":[{"name":"versionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"boolean"}}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseString"}}}}},"security":[{"basicAuth":[]}]}},"/admin/api/partners/{id}/toggle":{"patch":{"tags":["Partner Management API"],"operationId":"toggleEnabled","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]}},"/uuid/{uuid}":{"get":{"tags":["deprecated-endpoints-controller"],"operationId":"deprecatedUuidEndpoint","parameters":[{"name":"uuid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/serverpos/uuid/{uuid}":{"get":{"tags":["deprecated-endpoints-controller"],"operationId":"deprecatedUuidEndpoint_1","parameters":[{"name":"uuid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/status":{"get":{"tags":["deprecated-endpoints-controller"],"operationId":"deprecatedStatusEndpoint","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/serverpos/status":{"get":{"tags":["deprecated-endpoints-controller"],"operationId":"deprecatedStatusEndpoint_1","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/v1/{uuid}/uuid":{"get":{"tags":["Terminal API"],"operationId":"getByUuid","parameters":[{"name":"uuid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseTransactionItem"}}}}},"security":[{"basicAuth":[]}]}},"/serverpos/api/v1/{uuid}/uuid":{"get":{"tags":["Terminal API"],"operationId":"getByUuid_1","parameters":[{"name":"uuid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseTransactionItem"}}}}},"security":[{"basicAuth":[]}]}},"/api/v1/{terminalId}/transactions":{"get":{"tags":["Terminal API"],"summary":"Lista transazioni del terminale","description":"Restituisce la lista delle transazioni normalizzate per un terminale.\n\n**Fonti Dati:**\n- Transazioni POS salvate nel database MySQL (tabella receipts)\n- Pagamenti PayByLink da IGFS (tabella igfs_payments)\n\n**Normalizzazione:**\nTutte le transazioni vengono normalizzate in un formato standard indipendentemente\ndalla fonte (POS, IGFS, ecc.)\n\n**Filtri disponibili:**\n- **date**: Data specifica (formato YYYY-MM-DD)\n- **from/to**: Range di date\n- **type**: Tipo di pagamento (CARD, SATISPAY, VOUCHER, RECEIPT, PAYBYLINK, ALL)\n- **status**: Stato transazione (OK, KO, ALL)\n- **limit**: Numero massimo di risultati (max 500, default 100)\n- **offset**: Offset per paginazione (default 0)\n\n**Nota:** Con status=ALL, le transazioni KO vengono escluse per ridurre il rumore.\nPer vedere anche le transazioni fallite, usare status=KO esplicitamente.\n","operationId":"transactions","parameters":[{"name":"terminalId","in":"path","description":"ID univoco del terminale POS","required":true,"schema":{"type":"string"},"example":"PG001"},{"name":"date","in":"query","description":"Data specifica (YYYY-MM-DD)","required":false,"schema":{"type":"string"},"example":"2025-01-15"},{"name":"from","in":"query","description":"Data inizio range (YYYY-MM-DD)","required":false,"schema":{"type":"string"},"example":"2025-01-01"},{"name":"to","in":"query","description":"Data fine range (YYYY-MM-DD)","required":false,"schema":{"type":"string"},"example":"2025-01-31"},{"name":"type","in":"query","description":"Tipo pagamento","required":false,"schema":{"type":"string","enum":["ALL","CARD","SATISPAY","VOUCHER","RECEIPT","PAYBYLINK"]},"example":"CARD"},{"name":"status","in":"query","description":"Stato transazione","required":false,"schema":{"type":"string","enum":["ALL","OK","KO"]},"example":"OK"},{"name":"limit","in":"query","description":"Limite risultati (max 500)","required":false,"schema":{"type":"integer","format":"int32","default":100},"example":100},{"name":"offset","in":"query","description":"Offset per paginazione","required":false,"schema":{"type":"integer","format":"int32","default":0},"example":0}],"responses":{"401":{"description":"Autenticazione fallita","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}},"200":{"description":"Lista transazioni recuperata con successo","content":{"application/json":{}}}},"security":[{"basicAuth":[]}]}},"/serverpos/api/v1/{terminalId}/transactions":{"get":{"tags":["Terminal API"],"summary":"Lista transazioni del terminale","description":"Restituisce la lista delle transazioni normalizzate per un terminale.\n\n**Fonti Dati:**\n- Transazioni POS salvate nel database MySQL (tabella receipts)\n- Pagamenti PayByLink da IGFS (tabella igfs_payments)\n\n**Normalizzazione:**\nTutte le transazioni vengono normalizzate in un formato standard indipendentemente\ndalla fonte (POS, IGFS, ecc.)\n\n**Filtri disponibili:**\n- **date**: Data specifica (formato YYYY-MM-DD)\n- **from/to**: Range di date\n- **type**: Tipo di pagamento (CARD, SATISPAY, VOUCHER, RECEIPT, PAYBYLINK, ALL)\n- **status**: Stato transazione (OK, KO, ALL)\n- **limit**: Numero massimo di risultati (max 500, default 100)\n- **offset**: Offset per paginazione (default 0)\n\n**Nota:** Con status=ALL, le transazioni KO vengono escluse per ridurre il rumore.\nPer vedere anche le transazioni fallite, usare status=KO esplicitamente.\n","operationId":"transactions_1","parameters":[{"name":"terminalId","in":"path","description":"ID univoco del terminale POS","required":true,"schema":{"type":"string"},"example":"PG001"},{"name":"date","in":"query","description":"Data specifica (YYYY-MM-DD)","required":false,"schema":{"type":"string"},"example":"2025-01-15"},{"name":"from","in":"query","description":"Data inizio range (YYYY-MM-DD)","required":false,"schema":{"type":"string"},"example":"2025-01-01"},{"name":"to","in":"query","description":"Data fine range (YYYY-MM-DD)","required":false,"schema":{"type":"string"},"example":"2025-01-31"},{"name":"type","in":"query","description":"Tipo pagamento","required":false,"schema":{"type":"string","enum":["ALL","CARD","SATISPAY","VOUCHER","RECEIPT","PAYBYLINK"]},"example":"CARD"},{"name":"status","in":"query","description":"Stato transazione","required":false,"schema":{"type":"string","enum":["ALL","OK","KO"]},"example":"OK"},{"name":"limit","in":"query","description":"Limite risultati (max 500)","required":false,"schema":{"type":"integer","format":"int32","default":100},"example":100},{"name":"offset","in":"query","description":"Offset per paginazione","required":false,"schema":{"type":"integer","format":"int32","default":0},"example":0}],"responses":{"401":{"description":"Autenticazione fallita","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}},"200":{"description":"Lista transazioni recuperata con successo","content":{"application/json":{}}}},"security":[{"basicAuth":[]}]}},"/serverpos/api/v1/{terminalId}/status":{"get":{"tags":["Terminal API"],"operationId":"status","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseTransactionItem"}}}}},"security":[{"basicAuth":[]}]}},"/api/v1/{terminalId}/status":{"get":{"tags":["Terminal API"],"operationId":"status_1","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseTransactionItem"}}}}},"security":[{"basicAuth":[]}]}},"/serverpos/api/v1/{terminalId}/get":{"get":{"tags":["Terminal API"],"summary":"Polling dati pagamento","description":"Endpoint per il polling dei dati di pagamento da parte dell'applicazione PayCC.\n\n**Comportamento:**\n- Se ci sono dati disponibili su Redis per il terminale, li restituisce e li rimuove (GET + DELETE atomico)\n- Se non ci sono dati, ritorna una risposta vuota (204 No Content)\n- Traccia l'attività del terminale e salva le informazioni del dispositivo\n\n**Device Info:**\nL'interceptor estrae automaticamente informazioni dal dispositivo:\n- User-Agent\n- IP Address\n- Device fingerprint\n\n**Rate Limiting:**\n- Max 100 req/sec per IP\n","operationId":"get","parameters":[{"name":"terminalId","in":"path","description":"ID univoco del terminale POS","required":true,"schema":{"type":"string"},"example":"PG001"}],"responses":{"401":{"description":"Autenticazione fallita","content":{"*/*":{"schema":{"type":"object"}}}},"429":{"description":"Rate limit superato","content":{"*/*":{"schema":{"type":"object"}}}},"204":{"description":"Nessun dato disponibile per il terminale","content":{"*/*":{"schema":{"type":"object"}}}},"200":{"description":"Dati trovati e restituiti","content":{"application/json":{"example":{"uuid":"550e8400-e29b-41d4-a716-446655440000","amount":1500,"type":"CARD","description":"Acquisto prodotti"}}}}},"security":[{"basicAuth":[]}]}},"/api/v1/{terminalId}/get":{"get":{"tags":["Terminal API"],"summary":"Polling dati pagamento","description":"Endpoint per il polling dei dati di pagamento da parte dell'applicazione PayCC.\n\n**Comportamento:**\n- Se ci sono dati disponibili su Redis per il terminale, li restituisce e li rimuove (GET + DELETE atomico)\n- Se non ci sono dati, ritorna una risposta vuota (204 No Content)\n- Traccia l'attività del terminale e salva le informazioni del dispositivo\n\n**Device Info:**\nL'interceptor estrae automaticamente informazioni dal dispositivo:\n- User-Agent\n- IP Address\n- Device fingerprint\n\n**Rate Limiting:**\n- Max 100 req/sec per IP\n","operationId":"get_1","parameters":[{"name":"terminalId","in":"path","description":"ID univoco del terminale POS","required":true,"schema":{"type":"string"},"example":"PG001"}],"responses":{"401":{"description":"Autenticazione fallita","content":{"*/*":{"schema":{"type":"object"}}}},"429":{"description":"Rate limit superato","content":{"*/*":{"schema":{"type":"object"}}}},"204":{"description":"Nessun dato disponibile per il terminale","content":{"*/*":{"schema":{"type":"object"}}}},"200":{"description":"Dati trovati e restituiti","content":{"application/json":{"example":{"uuid":"550e8400-e29b-41d4-a716-446655440000","amount":1500,"type":"CARD","description":"Acquisto prodotti"}}}}},"security":[{"basicAuth":[]}]}},"/api/v1/{terminalId}/connection":{"get":{"tags":["Terminal API"],"summary":"Verifica connessione terminale","description":"Verifica se il terminale è connesso via WebSocket e pronto a ricevere comandi.\n\n**Uso consigliato:** Chiamare PRIMA di inviare un pagamento (POST /pay) per assicurarsi\nche il terminale sia raggiungibile.\n\nControlla la connessione WebSocket su entrambi i server (pgbe e pgbe2).\nVerifica che il POS sia effettivamente attivo controllando il lastPingAt della sessione.\n\n**Valori `connectionStatus`:**\n- `ONLINE` - Terminale connesso e raggiungibile\n- `OFFLINE` - Terminale non connesso (era connesso in passato)\n- `OFFLINE` - Terminale mai connesso al sistema (nessuna sessione precedente)\n\n**Valori `connectionType` (presente solo quando ONLINE):**\n- `WEBSOCKET` - Connesso via WebSocket STOMP (sessione attiva con ping recente)\n- `POLLING` - Connesso via REST polling (nessuna sessione WS ma il POS sta facendo polling attivo)\n","operationId":"getTerminalStatus","parameters":[{"name":"terminalId","in":"path","description":"ID univoco del terminale POS","required":true,"schema":{"type":"string"},"example":90011004}],"responses":{"200":{"description":"Stato connessione del terminale","content":{"application/json":{"examples":{"Online":{"description":"Online","value":{"status":"ok","data":{"terminalId":"90011004","connectionStatus":"ONLINE","connected":true,"sessions":1,"lastActivity":"2026-02-10T10:56:03Z","connectedSince":"2026-02-10T09:30:00Z","server":"pgbesrv01"}}},"Offline":{"description":"Offline","value":{"status":"ok","data":{"terminalId":"90011004","connectionStatus":"OFFLINE","connected":false,"sessions":0,"lastSeen":"2026-02-10T08:45:00Z"}}},"Never Connected":{"description":"Never Connected","value":{"status":"ok","data":{"terminalId":"99999999","connectionStatus":"OFFLINE","connected":false,"sessions":0,"message":"Terminal has never connected to the system"}}}}}}}},"security":[{"basicAuth":[]}]}},"/serverpos/api/v1/{terminalId}/connection":{"get":{"tags":["Terminal API"],"summary":"Verifica connessione terminale","description":"Verifica se il terminale è connesso via WebSocket e pronto a ricevere comandi.\n\n**Uso consigliato:** Chiamare PRIMA di inviare un pagamento (POST /pay) per assicurarsi\nche il terminale sia raggiungibile.\n\nControlla la connessione WebSocket su entrambi i server (pgbe e pgbe2).\nVerifica che il POS sia effettivamente attivo controllando il lastPingAt della sessione.\n\n**Valori `connectionStatus`:**\n- `ONLINE` - Terminale connesso e raggiungibile\n- `OFFLINE` - Terminale non connesso (era connesso in passato)\n- `OFFLINE` - Terminale mai connesso al sistema (nessuna sessione precedente)\n\n**Valori `connectionType` (presente solo quando ONLINE):**\n- `WEBSOCKET` - Connesso via WebSocket STOMP (sessione attiva con ping recente)\n- `POLLING` - Connesso via REST polling (nessuna sessione WS ma il POS sta facendo polling attivo)\n","operationId":"getTerminalStatus_1","parameters":[{"name":"terminalId","in":"path","description":"ID univoco del terminale POS","required":true,"schema":{"type":"string"},"example":90011004}],"responses":{"200":{"description":"Stato connessione del terminale","content":{"application/json":{"examples":{"Online":{"description":"Online","value":{"status":"ok","data":{"terminalId":"90011004","connectionStatus":"ONLINE","connected":true,"sessions":1,"lastActivity":"2026-02-10T10:56:03Z","connectedSince":"2026-02-10T09:30:00Z","server":"pgbesrv01"}}},"Offline":{"description":"Offline","value":{"status":"ok","data":{"terminalId":"90011004","connectionStatus":"OFFLINE","connected":false,"sessions":0,"lastSeen":"2026-02-10T08:45:00Z"}}},"Never Connected":{"description":"Never Connected","value":{"status":"ok","data":{"terminalId":"99999999","connectionStatus":"OFFLINE","connected":false,"sessions":0,"message":"Terminal has never connected to the system"}}}}}}}},"security":[{"basicAuth":[]}]}},"/api/status/ping/{terminalId}":{"get":{"tags":["status-controller"],"operationId":"pingTerminal","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/serverpos/api/status/ping/{terminalId}":{"get":{"tags":["status-controller"],"operationId":"pingTerminal_1","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/serverpos/api/status/ping-pos/{terminalId}":{"get":{"tags":["status-controller"],"operationId":"pingPos","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/status/ping-pos/{terminalId}":{"get":{"tags":["status-controller"],"operationId":"pingPos_1","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/v1/payment/status/{txId}":{"get":{"tags":["PayByLink API"],"summary":"Ottieni stato pagamento PayByLink","description":"Recupera lo stato corrente di un pagamento PayByLink dal database locale.\n\n**Autenticazione:**\nRichiede header `API-Key` valido.\n\n**Stati possibili:**\n- **PENDING**: Pagamento in attesa (link non ancora utilizzato)\n- **SUCCESS**: Pagamento completato con successo\n- **FAILED**: Pagamento fallito\n- **EXPIRED**: Link di pagamento scaduto\n\n**Utilizzo:**\nQuesto endpoint può essere utilizzato per il polling dello stato da parte\ndell'applicazione PayCC o di sistemi esterni.\n","operationId":"getPaymentStatus","parameters":[{"name":"API-Key","in":"header","description":"API Key per autenticazione","required":true,"schema":{"type":"string"}},{"name":"txId","in":"path","description":"ID transazione PayByLink","required":true,"schema":{"type":"string"},"example":"PBL_20250113_123456_ABC"}],"responses":{"404":{"description":"Pagamento non trovato","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaymentStatusResponse"}}}},"401":{"description":"API Key non valida","content":{"*/*":{"schema":{"$ref":"#/components/schemas/PaymentStatusResponse"}}}},"200":{"description":"Stato pagamento recuperato con successo","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentStatusResponse"}}}}},"security":[{"apiKey":[]}]}},"/api/v1/app/version":{"get":{"tags":["App Auto-Update"],"summary":"Check app version","description":"Controlla se è disponibile una versione più recente dell'app per questo terminal.\n\nRitorna 200 con dati versione se aggiornamento disponibile.\nRitorna 204 No Content se app già aggiornata.\n\nSupporta deploy selettivi per terminal/merchant specifici.\n","operationId":"checkVersion","parameters":[{"name":"terminalId","in":"query","description":"Terminal ID (OBBLIGATORIO)","required":true,"schema":{"type":"string"}},{"name":"currentVersionCode","in":"query","description":"Versione corrente installata (versionCode)","required":false,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/api/v1/app/download/{filename}":{"get":{"tags":["App Auto-Update"],"summary":"Download APK file","description":"Scarica file APK per installazione app. File servito direttamente dal filesystem.","operationId":"downloadApk","parameters":[{"name":"filename","in":"path","description":"Nome file APK (es: pos-app-v1.3.0.apk)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}}}}},"/api/terminal/cloud-config":{"get":{"tags":["terminal-cloud-config-controller"],"operationId":"getCloudConfig","parameters":[{"name":"activationCode","in":"query","required":false,"schema":{"type":"string"}},{"name":"deviceId","in":"query","required":false,"schema":{"type":"string"}},{"name":"androidId","in":"query","required":false,"schema":{"type":"string"}},{"name":"appVersion","in":"query","required":false,"schema":{"type":"string"}},{"name":"model","in":"query","required":false,"schema":{"type":"string"}},{"name":"manufacturer","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string"}}}}}}},"/api/partner/stats":{"get":{"tags":["Partner Portal"],"summary":"Get partner usage statistics","operationId":"getStats","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]}},"/api/partner/me":{"get":{"tags":["Partner Portal"],"summary":"Get current partner information (supports Basic Auth or API-Key)","operationId":"getCurrentPartner","parameters":[{"name":"API-Key","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]}},"/admin/zvt/stats":{"get":{"tags":["Admin API"],"summary":"ZVT Listener statistics","description":"Restituisce statistiche del listener ZVT ECR.\n\nInclude:\n- Stato listener (enabled/running)\n- Porta TCP\n- Sessioni ECR attive\n- Totale connessioni\n- Totale comandi processati\n","operationId":"getZvtStats","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseZvtStats"}}}}},"security":[{"basicAuth":[]}]}},"/admin/zvt/sessions":{"get":{"tags":["Admin API"],"summary":"Active ZVT ECR sessions","description":"Restituisce lista delle sessioni ECR attive connesse via ZVT.\n\nPer ogni sessione:\n- Terminal ID (dalla password ZVT)\n- Indirizzo IP remoto\n- Timestamp connessione\n- Ultima attività\n- Stato autenticazione\n","operationId":"getZvtSessions","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/websocket/terminal/{terminalId}":{"get":{"tags":["Admin API"],"operationId":"getWebSocketSessionsByTerminal","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListSessionInfo"}}}}},"security":[{"basicAuth":[]}]}},"/admin/websocket/stats":{"get":{"tags":["Admin API"],"operationId":"getWebSocketStats","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseWebSocketStats"}}}}},"security":[{"basicAuth":[]}]}},"/admin/websocket/sessions":{"get":{"tags":["Admin API"],"operationId":"getWebSocketSessions","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListSessionInfo"}}}}},"security":[{"basicAuth":[]}]}},"/admin/websocket/sessions/all":{"get":{"tags":["Admin API"],"operationId":"getAllWebSocketSessions","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/terminals":{"get":{"tags":["Admin API"],"operationId":"getTerminals","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/terminal/{terminalId}":{"get":{"tags":["Admin API"],"operationId":"getTerminalDetails","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/terminal-groups/{mainTerminalId}":{"get":{"tags":["Admin API"],"summary":"Get terminal group","description":"Get terminal group configuration by main terminal ID","operationId":"getTerminalGroup","parameters":[{"name":"mainTerminalId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseTerminalGroup"}}}}},"security":[{"basicAuth":[]}]}},"/admin/system/logs":{"get":{"tags":["Admin API"],"operationId":"getLogFiles","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/system/logs/{filename}":{"get":{"tags":["Admin API"],"operationId":"readLogFile","parameters":[{"name":"filename","in":"path","required":true,"schema":{"type":"string"}},{"name":"lines","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":500}},{"name":"tail","in":"query","required":false,"schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]},"delete":{"tags":["Admin API"],"operationId":"deleteLogFile","parameters":[{"name":"filename","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/system/logs/{filename}/download":{"get":{"tags":["Admin API"],"operationId":"downloadLogFile","parameters":[{"name":"filename","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}}},"security":[{"basicAuth":[]}]}},"/admin/system/backups":{"get":{"tags":["Admin API"],"summary":"Lista backup JAR","description":"Restituisce lista dei file JAR (backup e versione corrente) in /opt/serverPOS/","operationId":"getBackupFiles","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/subscription-rules/{terminalId}":{"get":{"tags":["Admin API"],"summary":"Ottieni regola whitelist per terminalId","description":"Restituisce la regola di whitelist configurata per un terminalId specifico","operationId":"getSubscriptionRuleByTerminalId","parameters":[{"name":"terminalId","in":"path","description":"Terminal ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseTerminalSubscriptionRule"}}}}},"security":[{"basicAuth":[]}]}},"/admin/stats":{"get":{"tags":["Admin API"],"summary":"Statistiche dashboard","description":"Restituisce statistiche aggregate per la dashboard amministrativa.\n\nInclude:\n- Numero totale di transazioni\n- Totale importi processati\n- Numero terminali attivi\n- Statistiche per metodo di pagamento\n- Tassi di successo/fallimento\n","operationId":"getStats_1","parameters":[{"name":"Authorization","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseDashboardStats"}}}}},"security":[{"basicAuth":[]}]}},"/admin/server/info":{"get":{"tags":["Admin API"],"summary":"Server information","description":"Restituisce informazioni sul server corrente.\n\nUtile per identificare su quale istanza stanno girando le connessioni\nin un setup con load balancer.\n\nInclude:\n- Hostname del server\n- IP interno (preferenza 172.16.x.x)\n- Tutti gli IP disponibili\n","operationId":"getServerInfo","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/s3/status":{"get":{"tags":["Admin API"],"operationId":"getS3Status","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/s3/backups":{"get":{"tags":["Admin API"],"operationId":"getS3Backups","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]},"delete":{"tags":["Admin API"],"operationId":"deleteS3Backup","parameters":[{"name":"key","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/s3/backups/download":{"get":{"tags":["Admin API"],"operationId":"downloadS3Backup","parameters":[{"name":"key","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/s3/apk":{"get":{"tags":["Admin API"],"operationId":"getS3Apk","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/redis/info":{"get":{"tags":["Admin API"],"summary":"Informazioni dual Redis cluster","description":"Restituisce informazioni su entrambe le istanze Redis in cluster mode.\n\nInclude:\n- Redis LOCALE (storage, cache, Pub/Sub listening)\n- Redis REMOTO (solo Pub/Sub publishing cross-server)\n- Statistiche connessione e latency per entrambi\n","operationId":"getRedisInfo","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/redis-sessions":{"get":{"tags":["Admin API"],"operationId":"getRedisSessions","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/receipts":{"get":{"tags":["Admin API"],"operationId":"getReceipts","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":50}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListReceipt"}}}}},"security":[{"basicAuth":[]}]}},"/admin/payglobe-credentials/{id}":{"get":{"tags":["Admin API"],"operationId":"getPayGlobeCredentialById","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]},"delete":{"tags":["Admin API"],"operationId":"deletePayGlobeCredential_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}},"security":[{"basicAuth":[]}]}},"/admin/ingenico/stats":{"get":{"tags":["Admin API"],"summary":"Ingenico Listener statistics","description":"Restituisce statistiche del listener Ingenico ECR Proto 17.\n\nInclude:\n- Stato listener (enabled/running)\n- Porta TCP\n- Sessioni ECR attive\n- Totale connessioni\n- Totale comandi processati\n","operationId":"getIngenicoStats","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseIngenicoStats"}}}}},"security":[{"basicAuth":[]}]}},"/admin/ingenico/sessions":{"get":{"tags":["Admin API"],"summary":"Active Ingenico ECR sessions","description":"Restituisce lista delle sessioni ECR attive connesse via Ingenico Proto 17.\n\nPer ogni sessione:\n- Terminal ID\n- Indirizzo IP remoto\n- Timestamp connessione\n","operationId":"getIngenicoSessions","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/cloudwatch/tail":{"get":{"tags":["Admin API"],"operationId":"tailCloudWatchLogs","parameters":[{"name":"streamName","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":100}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/cloudwatch/streams":{"get":{"tags":["Admin API"],"operationId":"getCloudWatchStreams","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/cloudwatch/status":{"get":{"tags":["Admin API"],"operationId":"getCloudWatchStatus","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/cloudwatch/logs":{"get":{"tags":["Admin API"],"operationId":"queryCloudWatchLogs","parameters":[{"name":"streamName","in":"query","required":false,"schema":{"type":"string"}},{"name":"filter","in":"query","required":false,"schema":{"type":"string"}},{"name":"startTime","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"endTime","in":"query","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":500}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/cloud-configs/{terminalId}":{"get":{"tags":["Admin API"],"operationId":"getCloudConfig_1","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseTerminalCloudConfig"}}}}},"security":[{"basicAuth":[]}]}},"/admin/cloud-configs/{terminalId}/preview":{"get":{"tags":["Admin API"],"operationId":"previewCloudConfig","parameters":[{"name":"terminalId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"string"}}}}},"security":[{"basicAuth":[]}]}},"/admin/app-versions/{versionId}/terminals":{"get":{"tags":["App Version Management"],"summary":"Get terminals with specific version","description":"Ottiene lista dei terminali che hanno installato questa versione.\n\nQuery parameter:\n- days: numero di giorni da considerare (default: 7)\n\nResponse:\n[\n  {\n    \"terminalId\": \"99019101\",\n    \"lastCheck\": \"2025-01-19T10:30:00\",\n    \"ipAddress\": \"1.2.3.4\",\n    \"userAgent\": \"Android 10 / App 3.0\"\n  },\n  ...\n]\n","operationId":"getTerminalsWithVersion","parameters":[{"name":"versionId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":7}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/app-versions/deployments":{"get":{"tags":["App Version Management"],"summary":"List all deployments","description":"Ritorna lista di tutti i deploy attivi.","operationId":"listDeployments","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListAppDeployment"}}}}},"security":[{"basicAuth":[]}]}},"/admin/app-versions/analytics/install-success":{"get":{"tags":["App Version Management"],"summary":"Install success rate analytics","description":"Ritorna tasso di successo installazioni per ciascuna versione.","operationId":"getInstallSuccessRates","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/app-versions/analytics/adoption":{"get":{"tags":["App Version Management"],"summary":"Version adoption analytics","description":"Ritorna statistiche adozione versioni: quanti terminal hanno installato ciascuna versione.\nBasato su check updates degli ultimi 7 giorni.\n","operationId":"getAdoptionStats","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseListMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/api/partner/payglobe-credentials/{id}":{"delete":{"tags":["Partner Portal"],"summary":"Delete partner's PayGlobe credential","operationId":"deletePayGlobeCredential","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}},"security":[{"basicAuth":[]}]}},"/admin/terminal-groups/{id}":{"delete":{"tags":["Admin API"],"summary":"Delete terminal group","description":"Delete a multi-TID terminal group configuration","operationId":"deleteTerminalGroup","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseString"}}}}},"security":[{"basicAuth":[]}]}},"/admin/system/backups/{filename}":{"delete":{"tags":["Admin API"],"operationId":"deleteBackupFile","parameters":[{"name":"filename","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/subscription-rules/{id}":{"delete":{"tags":["Admin API"],"summary":"Elimina regola whitelist","description":"Elimina una regola di whitelist. Dopo l'eliminazione, il terminalId userà il default (ANY).","operationId":"deleteSubscriptionRule","parameters":[{"name":"id","in":"path","description":"Rule ID","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/ingenico/sessions/{terminalId}":{"delete":{"tags":["Admin API"],"summary":"Close Ingenico ECR session","description":"Forcefully closes an active ECR session by terminal ID","operationId":"closeIngenicoSession","parameters":[{"name":"terminalId","in":"path","description":"Terminal ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseMapStringObject"}}}}},"security":[{"basicAuth":[]}]}},"/admin/cloud-configs/{id}":{"delete":{"tags":["Admin API"],"operationId":"deleteCloudConfig","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseString"}}}}},"security":[{"basicAuth":[]}]}},"/admin/app-versions/deployments/{deploymentId}":{"delete":{"tags":["App Version Management"],"summary":"Delete deployment","description":"Elimina un deploy specifico. La versione rimane attiva ma non verrà più offerta secondo questo deploy.","operationId":"deleteDeployment","parameters":[{"name":"deploymentId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"$ref":"#/components/schemas/ApiResponseString"}}}}},"security":[{"basicAuth":[]}]}}},"components":{"schemas":{"ApiPartner":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"username":{"type":"string"},"password":{"type":"string"},"apiKey":{"type":"string"},"enabled":{"type":"boolean"},"partnerName":{"type":"string"},"email":{"type":"string"},"roles":{"type":"string"},"maxRequestsPerDay":{"type":"integer","format":"int32"},"allowedTerminals":{"type":"string"},"allowedOrigins":{"type":"string"},"igfsKeyId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"},"notes":{"type":"string"}},"description":"Dati del partner da creare"},"ApiResponseMapStringObject":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","additionalProperties":{"type":"object"}},"error":{"type":"string"}}},"ApiResponseString":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"string"},"error":{"type":"string"}}},"ApiResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"error":{"type":"string"}}},"PayByLinkRequest":{"required":["amount","terminalID"],"type":"object","properties":{"amount":{"minimum":0.01,"exclusiveMinimum":false,"type":"number"},"reason":{"maxLength":500,"minLength":0,"type":"string"},"terminalID":{"maxLength":50,"minLength":1,"type":"string"},"customerEmail":{"maxLength":75,"minLength":0,"type":"string"},"returnUrl":{"maxLength":500,"minLength":0,"type":"string"},"merchantReference":{"maxLength":100,"minLength":0,"type":"string"}},"description":"Dati richiesta PayByLink"},"PayByLinkResponse":{"type":"object","properties":{"status":{"type":"string"},"txId":{"type":"string"},"paymentId":{"type":"string"},"paymentUrl":{"type":"string"},"qrCodeData":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"terminalID":{"type":"string"},"message":{"type":"string"}}},"TerminalGroupRequest":{"type":"object","properties":{"mainTerminalId":{"type":"string"},"managedTerminalIds":{"type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"},"notes":{"type":"string"}}},"ApiResponseTerminalGroup":{"type":"object","properties":{"status":{"type":"string"},"data":{"$ref":"#/components/schemas/TerminalGroup"},"error":{"type":"string"}}},"TerminalGroup":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"mainTerminalId":{"type":"string"},"managedTerminalIds":{"type":"string"},"enabled":{"type":"boolean"},"notes":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"},"managedTerminalIdsList":{"type":"array","items":{"type":"string"}}}},"TerminalGroupTestRequest":{"type":"object","properties":{"mainTerminalId":{"type":"string"},"targetTerminalId":{"type":"string"}}},"TerminalSubscriptionRule":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"terminalId":{"type":"string"},"ruleType":{"type":"string","enum":["ANY","LIST","REGEX"]},"ruleValue":{"type":"string"},"enabled":{"type":"boolean"},"notes":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"}}},"ApiResponseTerminalSubscriptionRule":{"type":"object","properties":{"status":{"type":"string"},"data":{"$ref":"#/components/schemas/TerminalSubscriptionRule"},"error":{"type":"string"}}},"ApiResponseMapStringInteger":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","additionalProperties":{"type":"integer","format":"int32"}},"error":{"type":"string"}}},"PayGlobeCredentialRequest":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"credentialName":{"type":"string"},"secretKey":{"type":"string"},"baseUrl":{"type":"string"},"environment":{"type":"string"},"isActive":{"type":"boolean"},"notes":{"type":"string"}}},"TerminalCloudConfig":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"terminalId":{"type":"string"},"activationCode":{"type":"string"},"merchantId":{"type":"string"},"configJson":{"type":"string"},"enabled":{"type":"boolean"},"notes":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"}}},"ApiResponseTerminalCloudConfig":{"type":"object","properties":{"status":{"type":"string"},"data":{"$ref":"#/components/schemas/TerminalCloudConfig"},"error":{"type":"string"}}},"VersionRequest":{"type":"object","properties":{"versionCode":{"type":"integer","format":"int32"},"versionName":{"type":"string"},"apkFilename":{"type":"string"},"mandatory":{"type":"boolean"},"releaseNotes":{"type":"string"}}},"ApiResponseAppVersion":{"type":"object","properties":{"status":{"type":"string"},"data":{"$ref":"#/components/schemas/AppVersion"},"error":{"type":"string"}}},"AppVersion":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"versionCode":{"type":"integer","format":"int32"},"versionName":{"type":"string"},"apkFilename":{"type":"string"},"apkUrl":{"type":"string"},"apkSizeBytes":{"type":"integer","format":"int64"},"apkMd5":{"type":"string"},"mandatory":{"type":"boolean"},"minApiLevel":{"type":"integer","format":"int32"},"releaseNotes":{"type":"string"},"active":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"}}},"PushUpdateRequest":{"type":"object","properties":{"terminalId":{"type":"string"},"mandatory":{"type":"boolean"}}},"DeployRequest":{"type":"object","properties":{"terminalId":{"type":"string"},"merchantId":{"type":"string"},"notes":{"type":"string"}}},"ApiResponseAppDeployment":{"type":"object","properties":{"status":{"type":"string"},"data":{"$ref":"#/components/schemas/AppDeployment"},"error":{"type":"string"}}},"AppDeployment":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"version":{"$ref":"#/components/schemas/AppVersion"},"terminalId":{"type":"string"},"merchantId":{"type":"string"},"enabled":{"type":"boolean"},"notes":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"},"globalDeployment":{"type":"boolean"},"terminalDeployment":{"type":"boolean"},"merchantDeployment":{"type":"boolean"}}},"ApiResponseTransactionItem":{"type":"object","properties":{"status":{"type":"string"},"data":{"$ref":"#/components/schemas/TransactionItem"},"error":{"type":"string"}}},"AuthDetails":{"type":"object","properties":{"authCode":{"type":"string"},"stan":{"type":"string"},"actionCode":{"type":"string"}}},"CardDetails":{"type":"object","properties":{"brand":{"type":"string"},"maskedPan":{"type":"string"},"entry":{"type":"string"}}},"PayByLinkDetails":{"type":"object","properties":{"txId":{"type":"string"},"paymentId":{"type":"string"},"tranId":{"type":"string"},"payerName":{"type":"string"},"payerLastName":{"type":"string"},"email":{"type":"string"},"resultCode":{"type":"string"},"errDescription":{"type":"string"}}},"PrintDetails":{"type":"object","properties":{"printResult":{"type":"string"},"errorDescription":{"type":"string"}}},"ProviderDetails":{"type":"object","properties":{"name":{"type":"string"},"model":{"type":"string"},"clientVersion":{"type":"string"}}},"SatispayDetails":{"type":"object","properties":{"paymentId":{"type":"string"},"status":{"type":"string"},"outcome":{"type":"string"},"store":{"type":"string"},"codeIdentifier":{"type":"string"}}},"ScanDetails":{"type":"object","properties":{"scannedValue":{"type":"string"},"barcodeFormat":{"type":"string"},"scanResult":{"type":"string"}}},"TransactionItem":{"type":"object","properties":{"uuid":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"method":{"type":"string","enum":["CARD","VOUCHER","SATISPAY","RECEIPT","PAYBYLINK","SCAN","PRINT","UNKNOWN"]},"status":{"type":"string","enum":["OK","KO"]},"amountCents":{"type":"integer","format":"int32"},"currency":{"type":"string"},"terminalId":{"type":"string"},"merchantId":{"type":"string"},"message":{"type":"string"},"auth":{"$ref":"#/components/schemas/AuthDetails"},"card":{"$ref":"#/components/schemas/CardDetails"},"satispay":{"$ref":"#/components/schemas/SatispayDetails"},"provider":{"$ref":"#/components/schemas/ProviderDetails"},"voucher":{"type":"object","additionalProperties":{"type":"object"}},"receipt":{"type":"object","additionalProperties":{"type":"object"}},"paybylink":{"$ref":"#/components/schemas/PayByLinkDetails"},"scan":{"$ref":"#/components/schemas/ScanDetails"},"print":{"$ref":"#/components/schemas/PrintDetails"},"raw":{"type":"object","additionalProperties":{"type":"object"}}}},"PaymentStatusResponse":{"type":"object","properties":{"txId":{"type":"string"},"status":{"type":"string"},"amount":{"type":"number"},"reason":{"type":"string"},"resultCode":{"type":"string"},"errDescription":{"type":"string"},"tranId":{"type":"string"},"authCode":{"type":"string"},"maskedPan":{"type":"string"},"cardBrand":{"type":"string"},"payerName":{"type":"string"},"payerLastName":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}}},"ApiResponseZvtStats":{"type":"object","properties":{"status":{"type":"string"},"data":{"$ref":"#/components/schemas/ZvtStats"},"error":{"type":"string"}}},"ZvtStats":{"type":"object","properties":{"enabled":{"type":"boolean"},"port":{"type":"integer","format":"int32"},"running":{"type":"boolean"},"startedAt":{"type":"string","format":"date-time"},"activeSessions":{"type":"integer","format":"int32"},"maxConnections":{"type":"integer","format":"int32"},"totalConnections":{"type":"integer","format":"int32"},"totalCommands":{"type":"integer","format":"int32"}}},"ApiResponseListMapStringObject":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"array","items":{"type":"object","additionalProperties":{"type":"object"}}},"error":{"type":"string"}}},"ApiResponseListSessionInfo":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/SessionInfo"}},"error":{"type":"string"}}},"SessionInfo":{"type":"object","properties":{"sessionId":{"type":"string"},"terminalId":{"type":"string"},"clientIp":{"type":"string"},"connectedAt":{"type":"string","format":"date-time"},"lastPingAt":{"type":"string","format":"date-time"},"serverHostname":{"type":"string"},"serverIp":{"type":"string"},"managedTerminals":{"type":"array","items":{"type":"string"}},"durationSeconds":{"type":"integer","format":"int64"}}},"ApiResponseWebSocketStats":{"type":"object","properties":{"status":{"type":"string"},"data":{"$ref":"#/components/schemas/WebSocketStats"},"error":{"type":"string"}}},"WebSocketStats":{"type":"object","properties":{"activeConnections":{"type":"integer","format":"int32"},"totalConnections":{"type":"integer","format":"int64"},"totalDisconnections":{"type":"integer","format":"int64"},"totalMessagesSent":{"type":"integer","format":"int64"},"totalBytesSent":{"type":"integer","format":"int64"},"uniqueTerminals":{"type":"integer","format":"int64"},"serverHostname":{"type":"string"},"serverIp":{"type":"string"}}},"ApiResponseListTerminalGroup":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/TerminalGroup"}},"error":{"type":"string"}}},"ApiResponseListTerminalSubscriptionRule":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/TerminalSubscriptionRule"}},"error":{"type":"string"}}},"ApiResponseDashboardStats":{"type":"object","properties":{"status":{"type":"string"},"data":{"$ref":"#/components/schemas/DashboardStats"},"error":{"type":"string"}}},"DashboardStats":{"type":"object","properties":{"totalReceipts":{"type":"integer","format":"int64"},"todayReceipts":{"type":"integer","format":"int64"},"activeTerminals":{"type":"integer","format":"int64"},"redisKeys":{"type":"integer","format":"int32"},"receiptsByMethod":{"type":"object","additionalProperties":{"type":"integer","format":"int64"}},"receiptsByStatus":{"type":"object","additionalProperties":{"type":"integer","format":"int64"}},"receiptsByHour":{"type":"object","additionalProperties":{"type":"integer","format":"int64"}},"totalAmountToday":{"type":"number","format":"double"},"successRate":{"type":"integer","format":"int64"},"logsTerminalsCount":{"type":"integer","format":"int32"},"logsTotalLines":{"type":"integer","format":"int64"},"logsTotalSizeMB":{"type":"number","format":"double"},"logsByTerminal":{"type":"object","additionalProperties":{"type":"integer","format":"int32"}},"redisMode":{"type":"string"},"redisHost":{"type":"string"},"redisUsedMemoryMB":{"type":"integer","format":"int64"},"redisTotalKeys":{"type":"integer","format":"int32"}}},"ApiResponseListReceipt":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Receipt"}},"error":{"type":"string"}}},"Receipt":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"terminalId":{"type":"string"},"uuid":{"type":"string"},"data":{"type":"object","additionalProperties":{"type":"object"}},"createdAt":{"type":"string","format":"date-time"}}},"ApiResponseIngenicoStats":{"type":"object","properties":{"status":{"type":"string"},"data":{"$ref":"#/components/schemas/IngenicoStats"},"error":{"type":"string"}}},"IngenicoStats":{"type":"object","properties":{"enabled":{"type":"boolean"},"port":{"type":"integer","format":"int32"},"running":{"type":"boolean"},"startedAt":{"type":"string","format":"date-time"},"activeSessions":{"type":"integer","format":"int32"},"maxConnections":{"type":"integer","format":"int32"},"totalConnections":{"type":"integer","format":"int32"},"totalCommands":{"type":"integer","format":"int32"}}},"ApiResponseListTerminalCloudConfig":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/TerminalCloudConfig"}},"error":{"type":"string"}}},"ApiResponseListAppVersion":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/AppVersion"}},"error":{"type":"string"}}},"ApiResponseListAppDeployment":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/AppDeployment"}},"error":{"type":"string"}}}},"securitySchemes":{"basicAuth":{"type":"http","description":"Basic Authentication per terminali POS","scheme":"basic"},"apiKey":{"type":"apiKey","description":"API Key per autenticazione Partner","name":"API-Key","in":"header"}}}}