Invio Pagamento
Per Partner: Questa API richiede un Token API per l'autenticazione.
Se non hai ancora accesso: Richiedi accesso qui
Se hai già ricevuto le credenziali: Accedi al Partner Portal
Token fornito da PayGlobe per l'autenticazione
1000 = 10.00€
Elaborazione...

Risposta

                        
Cerca Ricevuta per UUID

Risultato

                        
Ultimo Stato Terminale

Risultato

                        
Lista Transazioni

Risultati

                        
PayByLink
PayByLink genera link di pagamento per transazioni con carta di credito remote. Il cliente riceve un QR code/link e inserisce i dati carta su una piattaforma di pagamento sicura.
Test PayByLink

Risposta

                            

API Reference

Request:
POST /api/v1/paybylink
Headers:
  API-Key: your-api-key-here
  Content-Type: application/json

Body:
{
  "amount": 50.00,
  "reason": "Purchase payment",
  "terminalID": "TML001",
  "customerEmail": "customer@example.com",
  "merchantReference": "ORDER-12345"
}
Response (Success):
{
  "status": "success",
  "txId": "abc123def456",
  "paymentId": "251292575100031926",
  "paymentUrl": "https://testapif.netsgroup.com/...",
  "qrCodeData": "https://testapif.netsgroup.com/...",
  "expiresAt": "2025-10-11T13:00:00",
  "terminalID": "TML001"
}
Response (Error):
{
  "status": "error",
  "message": "Invalid API Key"
}

Request:
GET /api/payment/status/abc123def456
Headers:
  API-Key: your-api-key-here
Response (Pending):
{
  "txId": "abc123def456",
  "status": "PENDING",
  "amount": 50.00,
  "reason": "Purchase payment",
  "createdAt": "2025-10-11T12:00:00",
  "expiresAt": "2025-10-11T13:00:00"
}
Response (Success):
{
  "txId": "abc123def456",
  "status": "SUCCESS",
  "amount": 50.00,
  "reason": "Purchase payment",
  "resultCode": "IGFS_000",
  "tranId": "TR123456",
  "authCode": "AUTH789",
  "maskedPan": "1234****5678",
  "cardBrand": "VISA",
  "payerName": "Mario",
  "payerLastName": "Rossi",
  "createdAt": "2025-10-11T12:00:00"
}

Status Descrizione
PENDING Link generato, in attesa di pagamento
SUCCESS Pagamento completato con successo
FAILED Pagamento rifiutato o errore
EXPIRED Link scaduto (1 ora senza pagamento)
IGFS Result Codes:
Code Descrizione
IGFS_000 Transazione completata con successo
IGFS_20002 Sessione scaduta (timeout)
IGFS_10001 Carta non autorizzata
IGFS_10002 Fondi insufficienti

JavaScript Example:
// 1. Crea payment link
async function createPaymentLink(amount, reason) {
  const response = await fetch('/api/v1/paybylink', {
    method: 'POST',
    headers: {
      'API-Key': 'your-api-key',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      amount: amount,
      reason: reason,
      terminalID: 'TML001',
      customerEmail: 'customer@example.com'
    })
  });

  const data = await response.json();
  return data; // { txId, paymentUrl, ... }
}

// 2. Mostra QR code con paymentUrl
function showQRCode(paymentUrl) {
  // Usa libreria QR code per generare QR
  // Mostra su schermo PayCC
}

// 3. Polling per verificare stato
async function pollPaymentStatus(txId) {
  const interval = setInterval(async () => {
    const response = await fetch(\`/api/payment/status/\${txId}\`, {
      headers: { 'API-Key': 'your-api-key' }
    });

    const status = await response.json();

    if (status.status === 'SUCCESS') {
      clearInterval(interval);
      showSuccessScreen(status);
    } else if (status.status === 'FAILED') {
      clearInterval(interval);
      showErrorScreen(status);
    }
  }, 2000); // Ogni 2 secondi
}
Features:
  • Link di pagamento sicuro con HMAC-SHA256
  • Doppia verifica: Webhook + Polling automatico ogni 30s
  • Scadenza automatica link dopo 1 ora
  • Supporto multi-merchant
  • Tracciamento completo transazioni
Barcode / QR Scanner
PayGlobe Scan Library - Invia un comando SCAN al terminale, attendi la scansione e ricevi il valore direttamente nel campo di testo. Timeout configurabile (default 2 minuti).
Max attesa scansione (10-600s)


Dettagli Scansione
Valore
Formato
UUID
Tempo

Integrazione nella tua pagina

Includi la libreria e collega a qualsiasi <input>:

<!-- 1. Includi la libreria -->
<script src="https://ricevute.payglobe.it/serverpos/js/payglobe-scan.js"></script>

<!-- 2. Il tuo campo input -->
<input type="text" id="barcode" placeholder="Scansiona...">

<!-- 3. Collega lo scanner -->
<script>
const scanner = new PayGlobeScan({
    apiBase:    'https://ricevute.payglobe.it/serverpos/api/v1',
    apiKey:     'YOUR_API_KEY',
    terminalId: '90011005',
    timeout:    120          // secondi (default 2 minuti)
});

// Opzione A: Crea bottone scan accanto all'input automaticamente
scanner.attachTo('#barcode');

// Opzione B: Programmatico (es. su click di un bottone custom)
document.getElementById('myBtn').onclick = async function() {
    try {
        const result = await scanner.scan();
        document.getElementById('barcode').value = result.scannedValue;
        console.log('Formato:', result.barcodeFormat);
    } catch (err) {
        if (err.code === 'TIMEOUT')   alert('Timeout scansione');
        if (err.code === 'CANCELLED') alert('Scansione annullata');
    }
};
</script>
Opzioni
ParametroTipoDefaultDescrizione
apiBaseString-URL base API (es. https://ricevute.payglobe.it/serverpos/api/v1)
apiKeyString-API Token partner
terminalIdString-ID terminale POS
timeoutNumber120Timeout in secondi
pollIntervalNumber2000Intervallo polling in ms
onScanStartFunction-Callback avvio scansione
onScanResultFunction-Callback risultato OK
onScanErrorFunction-Callback errore
onScanTimeoutFunction-Callback timeout
onScanCancelFunction-Callback annullamento utente
onProgressFunction-Callback progresso (elapsedMs, timeoutMs)
Oggetto Risultato
{
  "scannedValue":  "8001234567890",   // Valore barcode/QR
  "barcodeFormat": "EAN_13",          // Formato codice
  "scanResult":    "OK",              // OK | CANCELLED | ERROR
  "uuid":          "abc-123-...",     // UUID correlazione
  "elapsed":       3500               // Tempo totale in ms
}
API Documentation
Partner Portal Available!
Manage your API Keys, view statistics, and access personalized documentation.
Access Portal
Architettura del Sistema

Il sistema ServerPOS funge da gateway tra i partner e i terminali di pagamento fisici, gestendo la comunicazione con le banche attraverso protocolli bancari standard.

┌─────────────────────────────────────────────────────────────────────┐
│                         FLUSSO PAGAMENTO                            │
└─────────────────────────────────────────────────────────────────────┘

 ┌─────────────┐                                   ┌─────────────┐
 │   PARTNER   │                                   │   BANCHE    │
 │  (Cliente)  │                                   │  (Acquirer) │
 └──────┬──────┘                                   └──────▲──────┘
        │                                                 │
        │ 1. POST /api/v1/{terminalId}/pay                │ 6. Autorizzazione
        │    + API Token                                  │    Bancaria
        │    + Amount                                     │
        │    + UUID                                       │
        ▼                                                 │
 ┌──────────────────────────────────────────────────┐    │
 │         API ServerPOS (Spring Boot)              │    │
 │                                                  │    │
 │  • Autentica Partner (API-Key)               │    │
 │  • Valida Richiesta                             │    │
 │  • Salva in Redis (TTL 60s)                     │    │
 │  • Invia a Terminale (WebSocket/Polling)        │    │
 └──────────────────┬───────────────────────────────┘    │
                    │                                    │
                    │ 2. WebSocket/HTTP Push             │
                    │    Pagamento al Terminale          │
                    ▼                                    │
        ┌───────────────────────┐                        │
        │   TERMINAL POS        │                        │
        │   (Android/Hardware)  │                        │
        │                       │                        │
        │  • Riceve Richiesta   │                        │
        │  • Mostra su Display  │                        │
        │  • Carta Inserita     │                        │
        └───────────┬───────────┘                        │
                    │                                    │
                    │ 3. Protocollo Bancario             │
                    │    (Connessione Sicura)            │
                    │                                    │
                    └────────────────────────────────────┘

 ┌─────────────────────────────────────────────────────────────┐
 │              VERIFICA STATO (ASINCRONO)                     │
 └─────────────────────────────────────────────────────────────┘

 ┌─────────────┐
 │   PARTNER   │
 │  (Polling)  │
 └──────┬──────┘
        │
        │ Ogni 3-5 secondi:
        │
        │ GET /status/{terminalId}
        │     + API Token
        │
        │ GET /uuid/{uuid}
        │     + API Token
        ▼
 ┌──────────────────────────────────────┐
 │      API ServerPOS (DB)              │
 │                                      │
 │  • Restituisce Stato Transazione    │
 │    - OK (approvata)                 │
 │    - KO (rifiutata)                 │
 │    - no_content (non ancora pronta) │
 │  • Dettagli: authCode, PAN, ecc.   │
 └──────────────────────────────────────┘

RESPONSABILITÀ:

0️⃣  /api/v1/{terminalId}/connection - CHECK (Prima di inviare)
   ↳ Verifica se il terminale è connesso e raggiungibile
   ↳ Se connectionStatus: "ONLINE" → procedi con il pagamento
   ↳ Se connectionStatus: "OFFLINE" → NON inviare, terminale spento/disconnesso
   ↳ Se connectionStatus: "NEVER_CONNECTED" → Terminale mai connesso al sistema

1️⃣  /api/v1/{terminalId}/pay - SINCRONO (Partner invia richiesta)
   ↳ Il partner invia la richiesta di pagamento
   ↳ L'API conferma la ricezione (HTTP 200)
   ↳ Il pagamento viene inviato al terminale

2️⃣  /api/v1/{terminalId}/status e /api/v1/{terminalId}/uuid/{uuid} - ASINCRONO (Partner verifica)
   ↳ Il PARTNER deve fare polling ogni 3-5 secondi
   ↳ L'API restituisce lo stato aggiornato della transazione
   ↳ Quando status = "OK" o "KO", il partner può fermare il polling
   ↳ Se no_content (data: null), la transazione non è ancora pronta

⚠️  IMPORTANTE:
Il partner è RESPONSABILE del polling per verificare lo stato del pagamento.
Il sistema NON invia callback/webhook automatici (solo WebSocket per terminali).

Endpoint API Principali

Descrizione: Invia una richiesta di pagamento al terminale specificato.

Autenticazione: Header API-Key (Token API fornito da PayGlobe)

Request:
POST /api/v1/90011004/pay
Headers:
  API-Key: your-api-token-here
  Content-Type: application/json

Body:
{
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "amount": 1050,
  "service": "PAYCC",
  "cardType": 0
}
Parametri:
  • uuid - ID univoco transazione (generato dal partner)
  • amount - Importo in centesimi (1050 = 10.50€)
  • service - Tipo servizio: PAYCC (Carta), PAYBP (Buono), PAYSAT (Satispay)
  • cardType opzionale - Tipo carta accettata:
    • 0 = Automatico (default) - il POS accetta qualsiasi carta
    • 1 = Solo Debito (PagoBancomat)
    • 2 = Solo Credito (Visa/Mastercard/Amex)
    Se omesso, equivale a 0 (retrocompatibile).
Esempi cardType:
// Pagamento automatico (default)
{
  "uuid": "trx-001",
  "amount": 2000,
  "service": "PAYCC",
  "cardType": 0
}

// Solo Debito (PagoBancomat)
{
  "uuid": "trx-002",
  "amount": 2000,
  "service": "PAYCC",
  "cardType": 1
}

// Solo Credito (Visa/MC/Amex)
{
  "uuid": "trx-003",
  "amount": 2000,
  "service": "PAYCC",
  "cardType": 2
}

// Senza cardType (retrocompatibile, equivale a 0)
{
  "uuid": "trx-004",
  "amount": 2000,
  "service": "PAYCC"
}
Response (Success):
{
  "status": "ok",
  "message": "Payment request sent to terminal 90011004"
}
Response (Error):
{
  "status": "error",
  "message": "Invalid API Key"
}
⚠️ NOTA: La risposta HTTP 200 indica solo che la richiesta è stata ricevuta e inviata al terminale. Per verificare l'esito del pagamento, usa /status o /uuid con polling.

Descrizione: Verifica se il terminale è connesso via WebSocket e pronto a ricevere comandi di pagamento.

Autenticazione: Header API-Key

💡 Consiglio: Chiamare PRIMA di POST /pay per verificare che il terminale sia raggiungibile. La verifica controlla che esista una sessione WebSocket attiva con ping recente (entro 2 minuti). Se il POS è spento o non risponde, viene restituito OFFLINE anche se la sessione WS non è ancora stata chiusa.
Request:
GET /api/v1/90011004/connection
Headers:
  API-Key: your-api-token-here
Response (Terminale ONLINE):
{
  "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"
  }
}
Response (Terminale OFFLINE):
{
  "status": "ok",
  "data": {
    "terminalId": "90011004",
    "connectionStatus": "OFFLINE",
    "connected": false,
    "sessions": 0,
    "lastSeen": "2026-02-10T08:45:00Z"
  }
}
Response (Terminale MAI CONNESSO):
{
  "status": "ok",
  "data": {
    "terminalId": "99999999",
    "connectionStatus": "NEVER_CONNECTED",
    "connected": false,
    "sessions": 0,
    "message": "Terminal has never connected to the system"
  }
}
Valori connectionStatus:
ValoreDescrizioneAzione
ONLINESessione WS attiva + ping recente (<2 min)Procedere con POST /pay
OFFLINETerminale disconnesso (era connesso in passato)NON inviare pagamenti
NEVER_CONNECTEDTerminale mai connesso al sistemaVerificare configurazione terminale

Descrizione: Restituisce l'ultima transazione elaborata dal terminale.

Autenticazione: Header API-Key

Request:
GET /api/v1/90011004/status
Headers:
  API-Key: your-api-token-here
Response (Transazione Approvata):
{
  "status": "ok",
  "data": {
    "uuid": "550e8400-e29b-41d4-a716-446655440000",
    "createdAt": "2025-10-26T14:30:00",
    "method": "CARD",
    "status": "OK",
    "amountCents": 1050,
    "currency": "EUR",
    "terminalId": "90011004",
    "message": "Transazione approvata",
    "auth": {
      "authCode": "123456",
      "stan": "000123"
    },
    "card": {
      "brand": "VISA",
      "maskedPan": "4242****4242",
      "entry": "ICC"
    }
  }
}
Response (Nessuna Transazione):
{
  "status": "ok",
  "data": null
}
💡 POLLING: Effettua una richiesta GET ogni 3-5 secondi fino a quando data non è null e status è "OK" o "KO".

Descrizione: Cerca una transazione specifica tramite UUID.

Autenticazione: Header API-Key

Request:
GET /api/v1/550e8400-e29b-41d4-a716-446655440000/uuid
Headers:
  API-Key: your-api-token-here
Response (Trovata):
{
  "status": "ok",
  "data": {
    "uuid": "550e8400-e29b-41d4-a716-446655440000",
    "status": "OK",
    "amountCents": 1050,
    ...
  }
}
Response (Non Trovata):
{
  "status": "error",
  "message": "Transaction not found"
}
💡 QUANDO USARE: Preferisci /uuid quando conosci l'UUID specifico della transazione. Usa /status se vuoi l'ultima transazione indipendentemente dall'UUID.

Descrizione: Invia un comando di scansione barcode/QR al terminale. L'app Android apre la fotocamera, scansiona il codice e restituisce il valore scansionato.

Autenticazione: Header API-Key

💡 Flusso: Il partner invia il comando SCAN → il terminale apre la fotocamera → l'utente scansiona → il risultato viene salvato e recuperabile via GET /{uuid}/uuid.
Request:
POST /api/v1/91010001/scan
Headers:
  API-Key: your-api-token-here
  Content-Type: application/json

Body:
{
  "uuid": "scan-abc-12345"
}
Parametri:
  • uuid opzionale - ID univoco richiesta (auto-generato se omesso)
Response (Comando inviato):
{
  "status": "ok",
  "data": {
    "terminalID": "91010001",
    "uuid": "scan-abc-12345",
    "service": "SCAN",
    "message": "Scan request sent to terminal 91010001"
  }
}

Comando ricevuto dal terminale (via polling/WebSocket):
{
  "uuid": "scan-abc-12345",
  "service": "SCAN",
  "amount": 0,
  "terminalId": "91010001"
}

Risposta terminale (via POST /receipt) - Successo:
{
  "uuid": "scan-abc-12345",
  "service": "SCAN",
  "result": "OK",
  "scannedValue": "8001234567890",
  "barcodeFormat": "EAN_13",
  "timestamp": "2026-02-18T14:30:45.123Z",
  "terminalId": "91010001",
  "appVersion": "x.x.x",
  "deviceModel": "Ingenico APOS A8"
}
Risposta terminale - Annullamento:
{
  "uuid": "scan-abc-12345",
  "service": "SCAN",
  "result": "CANCELLED",
  "scannedValue": null,
  "barcodeFormat": null,
  "timestamp": "2026-02-18T14:30:50.000Z",
  "terminalId": "91010001"
}
Campi risposta:
CampoTipoDescrizione
uuidStringStesso UUID della richiesta (correlazione)
serviceStringSempre "SCAN"
resultStringOK = scansione riuscita, CANCELLED = annullata, ERROR = errore camera
scannedValueString/nullValore in chiaro del codice scansionato
barcodeFormatString/nullFormato del codice (vedi tabella sotto)
timestampStringISO 8601
terminalIdStringTID che ha eseguito lo scan
Formati barcode supportati:
FormatoDescrizione
QR_CODEQR Code
EAN_13EAN-13 (codici a barre prodotti)
EAN_8EAN-8
CODE_128Code 128
CODE_39Code 39
DATA_MATRIXData Matrix
PDF_417PDF-417
UPC_AUPC-A
ITFInterleaved 2 of 5
AZTECAztec

Recupero risultato (polling):
GET /api/v1/scan-abc-12345/uuid
Headers:
  API-Key: your-api-token-here

// Response:
{
  "status": "ok",
  "data": {
    "uuid": "scan-abc-12345",
    "createdAt": "2026-02-18T14:30:45",
    "method": "SCAN",
    "status": "OK",
    "amountCents": 0,
    "scan": {
      "scannedValue": "8001234567890",
      "barcodeFormat": "EAN_13",
      "scanResult": "OK"
    }
  }
}

Diagramma di flusso:
  Partner                     ServerPOS                    Terminal POS
    │                             │                             │
    │  POST /scan {uuid}          │                             │
    │────────────────────────────►│                             │
    │                             │  Redis + WebSocket push     │
    │  ◄── 200 OK (uuid) ────────│────────────────────────────►│
    │                             │                             │
    │                             │                  Apre fotocamera
    │                             │                  Scansiona barcode
    │                             │                             │
    │                             │  ◄── POST /receipt ─────────│
    │                             │  {result:"OK",              │
    │                             │   scannedValue:"800123..."}│
    │  GET /{uuid}/uuid           │                             │
    │────────────────────────────►│                             │
    │  ◄── {method:"SCAN",       │                             │
    │       scan:{scannedValue}} │                             │
    │                             │                             │
⚠️ TIMEOUT: Impostare un timeout di 60 secondi dalla spedizione del comando SCAN. Se non arriva risposta entro 60s, considerare la richiesta scaduta.
Esempio integrazione JavaScript:
async function scanBarcode(terminalId) {
  // 1. Invia comando SCAN
  const response = await fetch(`${API_BASE}/${terminalId}/scan`, {
    method: 'POST',
    headers: {
      'API-Key': API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({})
  });

  const { data } = await response.json();
  const uuid = data.uuid;

  // 2. Polling risultato (timeout 60s)
  return new Promise((resolve, reject) => {
    const startTime = Date.now();
    const interval = setInterval(async () => {
      // Timeout check
      if (Date.now() - startTime > 60000) {
        clearInterval(interval);
        reject(new Error('Scan timeout (60s)'));
        return;
      }

      const res = await fetch(`${API_BASE}/${uuid}/uuid`, {
        headers: { 'API-Key': API_KEY }
      });
      const result = await res.json();

      if (result.data && result.data.scan) {
        clearInterval(interval);
        if (result.data.scan.scanResult === 'OK') {
          resolve(result.data.scan); // { scannedValue, barcodeFormat }
        } else {
          reject(new Error('Scan ' + result.data.scan.scanResult));
        }
      }
    }, 2000);
  });
}

Descrizione: Invia testo formattato al terminale per la stampa su stampante termica integrata.

Autenticazione: Header API-Key

Request - Stampa Testo:
POST /api/v1/91010001/print
Headers:
  API-Key: your-api-token-here
  Content-Type: application/json

Body:
{
  "uuid": "print-abc-12345",
  "text": "===== RICEVUTA =====\nArticolo 1       10.00\nArticolo 2        5.50\n--------------------\nTOTALE           15.50\n\nGrazie per l'acquisto!"
}
Request - Stampa QR Code:
POST /api/v1/91010001/print
Headers:
  API-Key: your-api-token-here
  Content-Type: application/json

Body:
{
  "uuid": "print-qr-67890",
  "type": "qr",
  "text": "https://payglobe.co/pay/abc123",
  "label": "Scansiona per pagare"
}
Parametri:
CampoTipoObbligatorioDescrizione
uuidStringNoID univoco richiesta (auto-generato se omesso)
typeStringNo"qr" per QR code, omettere o "text" per stampa testo
textStringContenuto da stampare (testo) o da codificare nel QR code
labelStringNoEtichetta stampata sopra il QR code (solo per type:"qr")
Response (Comando inviato):
{
  "status": "ok",
  "data": {
    "terminalID": "91010001",
    "uuid": "print-abc-12345",
    "service": "PRINT",
    "message": "Print request sent to terminal 91010001"
  }
}

Risposta terminale (via POST /receipt) - Successo:
{
  "uuid": "print-abc-12345",
  "service": "PRINT",
  "result": "OK",
  "terminalId": "91010001"
}
Risposta terminale - Errore:
{
  "uuid": "print-abc-12345",
  "service": "PRINT",
  "result": "KO",
  "errorDescription": "Carta finita",
  "terminalId": "91010001"
}
Campi risposta:
CampoTipoDescrizione
uuidStringStesso UUID della richiesta
serviceStringSempre "PRINT"
resultStringOK = stampato, KO = errore
errorDescriptionString/nullDescrizione errore (es. "Carta finita", "Stampante offline")

Recupero risultato (polling):
GET /api/v1/print-abc-12345/uuid
Headers:
  API-Key: your-api-token-here

// Response (OK):
{
  "status": "ok",
  "data": {
    "uuid": "print-abc-12345",
    "createdAt": "2026-02-18T14:35:00",
    "method": "PRINT",
    "status": "OK",
    "amountCents": 0,
    "print": {
      "printResult": "OK",
      "errorDescription": null
    }
  }
}

// Response (KO):
{
  "status": "ok",
  "data": {
    "uuid": "print-abc-12345",
    "createdAt": "2026-02-18T14:35:00",
    "method": "PRINT",
    "status": "KO",
    "amountCents": 0,
    "print": {
      "printResult": "KO",
      "errorDescription": "Carta finita"
    }
  }
}
⚠️ TIMEOUT: Impostare un timeout di 30 secondi. La stampa è normalmente rapida (<5s).
Esempio integrazione JavaScript:
async function printText(terminalId, text) {
  // 1. Invia comando PRINT
  const response = await fetch(`${API_BASE}/${terminalId}/print`, {
    method: 'POST',
    headers: {
      'API-Key': API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ text: text })
  });

  const { data } = await response.json();
  const uuid = data.uuid;

  // 2. Polling risultato (timeout 30s)
  return new Promise((resolve, reject) => {
    const startTime = Date.now();
    const interval = setInterval(async () => {
      if (Date.now() - startTime > 30000) {
        clearInterval(interval);
        reject(new Error('Print timeout (30s)'));
        return;
      }

      const res = await fetch(`${API_BASE}/${uuid}/uuid`, {
        headers: { 'API-Key': API_KEY }
      });
      const result = await res.json();

      if (result.data && result.data.print) {
        clearInterval(interval);
        if (result.data.print.printResult === 'OK') {
          resolve(result.data.print);
        } else {
          reject(new Error(result.data.print.errorDescription || 'Print failed'));
        }
      }
    }, 2000);
  });
}

// Uso - Stampa testo:
await printText('91010001', '===== RICEVUTA =====\nTotale: 15.50 EUR');

// Uso - Stampa QR Code:
async function printQR(terminalId, url, label) {
  const response = await fetch(`${API_BASE}/${terminalId}/print`, {
    method: 'POST',
    headers: {
      'API-Key': API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ type: 'qr', text: url, label: label })
  });
  // ... stesso polling di printText()
}

await printQR('91010001', 'https://payglobe.co/pay/abc123', 'Scansiona per pagare');

JavaScript Example (Node.js / Browser):
const API_BASE = 'https://ricevute.payglobe.it/serverpos/api/v1';
const API_KEY = 'your-api-token-here';
const TERMINAL_ID = '90011004';

// 1. Invia pagamento
async function sendPayment(amount) {
  const uuid = generateUUID(); // Genera UUID univoco

  const response = await fetch(`${API_BASE}/${TERMINAL_ID}/pay`, {
    method: 'POST',
    headers: {
      'API-Key': API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      uuid: uuid,
      amount: amount, // in centesimi
      service: 'PAYCC'
    })
  });

  if (!response.ok) {
    throw new Error('Errore invio pagamento');
  }

  console.log('Pagamento inviato:', uuid);
  return uuid;
}

// 2. Polling stato pagamento
async function pollPaymentStatus(uuid) {
  return new Promise((resolve, reject) => {
    const interval = setInterval(async () => {
      try {
        const response = await fetch(`${API_BASE}/${uuid}/uuid`, {
          headers: { 'API-Key': API_KEY }
        });

        const result = await response.json();

        if (result.status === 'ok' && result.data) {
          const txStatus = result.data.status; // "OK" o "KO"

          if (txStatus === 'OK') {
            clearInterval(interval);
            resolve(result.data); // Pagamento approvato
          } else if (txStatus === 'KO') {
            clearInterval(interval);
            reject(new Error(result.data.message)); // Pagamento rifiutato
          }
          // Se ancora PENDING, continua il loop
        }
      } catch (error) {
        clearInterval(interval);
        reject(error);
      }
    }, 3000); // Polling ogni 3 secondi

    // Timeout dopo 5 minuti
    setTimeout(() => {
      clearInterval(interval);
      reject(new Error('Timeout: pagamento non completato'));
    }, 300000);
  });
}

// 3. Esempio utilizzo completo
async function processPayment(amount) {
  try {
    // Invia richiesta pagamento
    const uuid = await sendPayment(amount);
    console.log('In attesa di conferma pagamento...');

    // Attendi risultato tramite polling
    const result = await pollPaymentStatus(uuid);
    console.log('Pagamento completato!', result);

    // Mostra scontrino / conferma all'utente
    showReceipt(result);
  } catch (error) {
    console.error('Errore:', error);
    // Mostra errore all'utente
    showError(error.message);
  }
}

// Genera UUID v4
function generateUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
    const r = Math.random() * 16 | 0;
    return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
  });
}
✅ BEST PRACTICES:
  • Implementa un timeout (es. 5 minuti) per evitare polling infinito
  • Intervallo polling consigliato: 3-5 secondi (non troppo frequente per non sovraccaricare il server)
  • Genera UUID univoci per ogni transazione (usa UUID v4)
  • Gestisci errori di rete (retry con exponential backoff)
  • Salva l'UUID nel tuo database per tracciamento

Documentazione Interattiva OpenAPI/Swagger

Accedi alla documentazione completa e interattiva di tutte le API con esempi, schemi di autenticazione e possibilità di testare gli endpoint direttamente dal browser.

Apri Swagger UI OpenAPI JSON

Transaction Schema - Unified API
Tutti gli endpoint (/transactions, /status, /uuid) utilizzano lo stesso schema JSON normalizzato.
Schema Base
{
  "status": "ok",
  "data": {
    "uuid": "string",
    "createdAt": "2025-10-04T09:21:54",
    "method": "CARD | SATISPAY | VOUCHER | RECEIPT | UNKNOWN",
    "status": "OK | KO",
    "amountCents": 1000,
    "currency": "EUR",
    "terminalId": "12300001",
    "merchantId": "12345678",
    "message": "Transazione approvata",

    "auth": { ... },      // dettagli autenticazione
    "card": { ... },      // dettagli carta (solo CARD)
    "satispay": { ... },  // dettagli Satispay (solo SATISPAY)
    "provider": { ... },  // dettagli provider/device
    "voucher": { ... },   // dettagli voucher (solo VOUCHER)
    "receipt": { ... }    // dettagli scontrino (solo RECEIPT)
  },
  "error": null
}
Campi Principali
Campo Tipo Descrizione
uuid string Identificativo univoco transazione
method enum CARD, SATISPAY, VOUCHER, RECEIPT
status enum OK (approvata), KO (rifiutata)
amountCents integer Importo in centesimi (1000 = 10.00€)
currency string Valuta (default: EUR)
terminalId string ID terminale
message string Messaggio esito transazione
Auth Details (auth)
"auth": {
  "authCode": "70928",
  "stan": "000030",
  "actionCode": "000"
}
Card Details (card)
"card": {
  "brand": "VISA",
  "maskedPan": "424242******4242",
  "entry": "MAN"  // MAN, ICC, NFC
}
Satispay Details (satispay)
"satispay": {
  "paymentId": "0199ae86-0f4f-7596-8907-5d2ab4983b82",
  "status": "ACCEPTED",
  "outcome": "OK",
  "store": "STORE001",
  "codeIdentifier": "S6Y-PAY--0199AE86..."
}
Provider Details (provider)
"provider": {
  "name": "VISA",
  "model": "A920Pro",
  "clientVersion": "1.1"
}
Esempio: Pagamento CARD Approvato
{
  "status": "ok",
  "data": {
    "uuid": "pg-mgc2cy5g-egan",
    "createdAt": "2025-10-04T09:21:54",
    "method": "CARD",
    "status": "OK",
    "amountCents": 1000,
    "currency": "EUR",
    "terminalId": "12300001",
    "merchantId": "12345678",
    "message": "Transazione approvata",
    "auth": {
      "authCode": "70928",
      "stan": "000030",
      "actionCode": "000"
    },
    "card": {
      "brand": "VISA",
      "maskedPan": "424242******4242",
      "entry": "MAN"
    },
    "provider": {
      "name": "VISA",
      "model": "A920Pro",
      "clientVersion": "1.1"
    }
  }
}
Esempio: Pagamento SATISPAY Approvato
{
  "status": "ok",
  "data": {
    "uuid": "pg-mgc2byoj-7d3w",
    "createdAt": "2025-10-04T09:15:32",
    "method": "SATISPAY",
    "status": "OK",
    "amountCents": 100,
    "currency": "EUR",
    "terminalId": "12300001",
    "message": "ACCEPTED",
    "satispay": {
      "paymentId": "0199ae86-0f4f-7596-8907-5d2ab4983b82",
      "status": "ACCEPTED",
      "outcome": "OK",
      "store": "STORE001"
    },
    "provider": {
      "name": "SATISPAY",
      "model": "A920Pro"
    }
  }
}
Endpoint che Usano Questo Schema
Endpoint Descrizione
GET /api/v1/{uuid}/uuid Cerca transazione per UUID
GET /api/v1/{terminalId}/status Ultima transazione del terminale
GET /api/v1/{terminalId}/transactions Lista transazioni con filtri
Best Practices
Controllo Campi Opzionali:
// ✅ CORRETTO
const authCode = transaction.auth?.authCode || 'N/A';

// ❌ SBAGLIATO
const authCode = transaction.auth.authCode; // può crashare
Formattazione Importi:
const euros = transaction.amountCents / 100;
const formatted = new Intl.NumberFormat('it-IT', {
  style: 'currency',
  currency: 'EUR'
}).format(euros); // "10,00 €"
TypeScript Definitions
enum PaymentMethod {
  CARD = 'CARD',
  SATISPAY = 'SATISPAY',
  VOUCHER = 'VOUCHER',
  RECEIPT = 'RECEIPT'
}

enum TransactionStatus {
  OK = 'OK',
  KO = 'KO'
}

interface TransactionItem {
  uuid: string;
  createdAt: string;
  method: PaymentMethod;
  status: TransactionStatus;
  amountCents: number;
  currency: string;
  terminalId?: string;
  merchantId?: string;
  message?: string;
  auth?: AuthDetails;
  card?: CardDetails;
  satispay?: SatispayDetails;
  provider?: ProviderDetails;
}
Versione Schema: 2.0 | Data Rilascio: 2025-10-04