Invio Pagamento
• Se non hai ancora accesso: Richiedi accesso qui
• Se hai già ricevuto le credenziali: Accedi al Partner Portal
Risposta
Cerca Ricevuta per UUID
Risultato
Ultimo Stato Terminale
Risultato
Lista Transazioni
Risultati
PayByLink
Risposta
API Reference
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"
}
GET /api/payment/status/abc123def456 Headers: API-Key: your-api-key-hereResponse (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) |
| Code | Descrizione |
|---|---|
IGFS_000 |
Transazione completata con successo |
IGFS_20002 |
Sessione scaduta (timeout) |
IGFS_10001 |
Carta non autorizzata |
IGFS_10002 |
Fondi insufficienti |
// 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
}
- 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
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
| Parametro | Tipo | Default | Descrizione |
|---|---|---|---|
apiBase | String | - | URL base API (es. https://ricevute.payglobe.it/serverpos/api/v1) |
apiKey | String | - | API Token partner |
terminalId | String | - | ID terminale POS |
timeout | Number | 120 | Timeout in secondi |
pollInterval | Number | 2000 | Intervallo polling in ms |
onScanStart | Function | - | Callback avvio scansione |
onScanResult | Function | - | Callback risultato OK |
onScanError | Function | - | Callback errore |
onScanTimeout | Function | - | Callback timeout |
onScanCancel | Function | - | Callback annullamento utente |
onProgress | Function | - | 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
Manage your API Keys, view statistics, and access personalized documentation.
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)
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)cardTypeopzionale - Tipo carta accettata:0= Automatico (default) - il POS accetta qualsiasi carta1= Solo Debito (PagoBancomat)2= Solo Credito (Visa/Mastercard/Amex)
0(retrocompatibile).
// 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"
}
/status o /uuid con polling.
Descrizione: Verifica se il terminale è connesso via WebSocket e pronto a ricevere comandi di pagamento.
Autenticazione: Header API-Key
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.
GET /api/v1/90011004/connection Headers: API-Key: your-api-token-hereResponse (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:
| Valore | Descrizione | Azione |
|---|---|---|
ONLINE | Sessione WS attiva + ping recente (<2 min) | Procedere con POST /pay |
OFFLINE | Terminale disconnesso (era connesso in passato) | NON inviare pagamenti |
NEVER_CONNECTED | Terminale mai connesso al sistema | Verificare configurazione terminale |
Descrizione: Restituisce l'ultima transazione elaborata dal terminale.
Autenticazione: Header API-Key
GET /api/v1/90011004/status Headers: API-Key: your-api-token-hereResponse (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
}
data non è null
e status è "OK" o "KO".
Descrizione: Cerca una transazione specifica tramite UUID.
Autenticazione: Header API-Key
GET /api/v1/550e8400-e29b-41d4-a716-446655440000/uuid Headers: API-Key: your-api-token-hereResponse (Trovata):
{
"status": "ok",
"data": {
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"status": "OK",
"amountCents": 1050,
...
}
}
Response (Non Trovata):
{
"status": "error",
"message": "Transaction not found"
}
/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
GET /{uuid}/uuid.
POST /api/v1/91010001/scan
Headers:
API-Key: your-api-token-here
Content-Type: application/json
Body:
{
"uuid": "scan-abc-12345"
}
Parametri:
uuidopzionale - ID univoco richiesta (auto-generato se omesso)
{
"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:
| Campo | Tipo | Descrizione |
|---|---|---|
uuid | String | Stesso UUID della richiesta (correlazione) |
service | String | Sempre "SCAN" |
result | String | OK = scansione riuscita, CANCELLED = annullata, ERROR = errore camera |
scannedValue | String/null | Valore in chiaro del codice scansionato |
barcodeFormat | String/null | Formato del codice (vedi tabella sotto) |
timestamp | String | ISO 8601 |
terminalId | String | TID che ha eseguito lo scan |
| Formato | Descrizione |
|---|---|
QR_CODE | QR Code |
EAN_13 | EAN-13 (codici a barre prodotti) |
EAN_8 | EAN-8 |
CODE_128 | Code 128 |
CODE_39 | Code 39 |
DATA_MATRIX | Data Matrix |
PDF_417 | PDF-417 |
UPC_A | UPC-A |
ITF | Interleaved 2 of 5 |
AZTEC | Aztec |
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}} │ │
│ │ │
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
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:
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
uuid | String | No | ID univoco richiesta (auto-generato se omesso) |
type | String | No | "qr" per QR code, omettere o "text" per stampa testo |
text | String | Sì | Contenuto da stampare (testo) o da codificare nel QR code |
label | String | No | Etichetta stampata sopra il QR code (solo per type:"qr") |
{
"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:
| Campo | Tipo | Descrizione |
|---|---|---|
uuid | String | Stesso UUID della richiesta |
service | String | Sempre "PRINT" |
result | String | OK = stampato, KO = errore |
errorDescription | String/null | Descrizione 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"
}
}
}
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');
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);
});
}
- 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 JSONTransaction Schema - Unified API
/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
// ✅ CORRETTO const authCode = transaction.auth?.authCode || 'N/A'; // ❌ SBAGLIATO const authCode = transaction.auth.authCode; // può crashare
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;
}