Passa al contenuto principale

NoPos Pay - Webhook

NoPos Pay fornisce notifiche webhook per gli eventi di pagamento, permettendoti di ricevere aggiornamenti in tempo reale sui cambiamenti di stato dei pagamenti.

Payload del Webhook

Quando si verifica un evento di pagamento, NoPos Pay invierà una richiesta POST al tuo URL webhook con il seguente payload:

Struttura TransactionEvent

interface TransactionEvent {
type: string; // Tipo di evento di transazione
id: string; // ID univoco dell'evento
created: number; // Timestamp Unix di creazione dell'evento
data: {
id: string; // ID della transazione
amount: number; // Importo in centesimi
currency: string; // Codice valuta (es. "eur")
status: TransactionStatus; // Stato standardizzato
description: string; // Descrizione della transazione
state?: string; // Parametro personalizzato passato dal client
provider: string; // ID del provider utilizzato per il pagamento
};
clientId: string; // Il tuo client ID
}

Valori di Stato della Transazione

NoPos Pay fornisce stati di transazione standardizzati:

StatoDescrizione
completedTransazione completata con successo
failedTransazione fallita
canceledTransazione annullata
newNuova transazione creata
pendingTransazione in corso o in attesa di azione

Esempio di Payload Webhook

{
"type": "transaction.succeeded",
"id": "evt_1ABC123def456GHI",
"created": 1640995200,
"data": {
"id": "txn_1ABC123def456GHI",
"amount": 2000,
"currency": "eur",
"status": "completed",
"description": "Transazione per ordine #12345",
"state": "order_12345",
"provider": "stripe"
},
"clientId": "client_abc123def456"
}

Verifica del Webhook

Verifica della Firma HMAC

NoPos Pay firma tutte le richieste webhook utilizzando HMAC-SHA256 con il tuo client secret. Verifica la firma per assicurarti che il webhook sia autentico.

Header della Firma

La firma viene inviata nell'header X-Pay-Signature:

X-Pay-Signature: sha256=abc123def456...

Processo di Verifica

  1. Estrai la firma dall'header X-Pay-Signature
  2. Crea la firma attesa utilizzando HMAC-SHA256 con il tuo client secret
  3. Confronta le firme utilizzando un confronto a tempo costante

Esempio di Implementazione

const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, clientSecret) {
const expectedSignature = crypto
.createHmac('sha256', clientSecret)
.update(JSON.stringify(payload))
.digest('hex');

return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expectedSignature, 'hex')
);
}

// Nel tuo gestore webhook
app.post('/webhooks/transactions', express.json(), (req, res) => {
const signature = req.headers['x-signature'];
const payload = req.body;

if (!verifyWebhookSignature(payload, signature, CLIENT_SECRET)) {
return res.status(401).send('Firma non valida');
}

// Elabora il webhook
console.log('Evento di transazione:', payload);
res.status(200).send('OK');
});

Best Practice per i Webhook

1. Verifica Sempre le Firme

Non elaborare mai i webhook senza verificare la firma HMAC. Questo previene l'invio di eventi webhook falsi da parte di attori malintenzionati.

2. Gestisci Eventi Duplicati

I provider di pagamento potrebbero inviare eventi webhook duplicati. Implementa l'idempotenza memorizzando gli ID degli eventi elaborati:

const processedEvents = new Set();

app.post('/webhooks/transactions', (req, res) => {
const { id } = req.body;

if (processedEvents.has(id)) {
return res.status(200).send('Già elaborato');
}

// Elabora il webhook
processedEvents.add(id);
res.status(200).send('OK');
});

3. Rispondi Rapidamente

Rispondi alle richieste webhook entro 30 secondi. Se l'elaborazione richiede più tempo, conferma il webhook ed elabora in modo asincrono:

app.post('/webhooks/transactions', (req, res) => {
// Conferma immediatamente
res.status(200).send('OK');

// Elabora in modo asincrono
setImmediate(() => {
processTransactionEvent(req.body);
});
});

4. Gestisci gli Errori con Grazia

Implementa logica di retry e gestione degli errori:

async function processTransactionEvent(event) {
try {
// Elabora l'evento di transazione
await updateOrderStatus(event.data.id, event.data.status);
} catch (error) {
console.error('Errore nell\'elaborazione dell\'evento di transazione:', error);
// Implementa logica di retry o coda di messaggi morti
}
}

5. Registra gli Eventi Webhook

Registra tutti gli eventi webhook per debug e audit:

app.post('/webhooks/transactions', (req, res) => {
console.log('Webhook ricevuto:', {
type: req.body.type,
transactionId: req.body.data.id,
status: req.body.data.status,
timestamp: new Date().toISOString()
});

// Elabora il webhook...
});

Test dei Webhook

Utilizzo di ngrok per lo Sviluppo Locale

  1. Installa ngrok: npm install -g ngrok
  2. Avvia il tuo server locale: npm start
  3. Esponi il tuo server locale: ngrok http 3000
  4. Usa l'URL ngrok come URL webhook: https://abc123.ngrok.io/webhooks/transactions

Strumenti per il Test dei Webhook

  • Postman: Crea richieste di test webhook
  • Script di test personalizzati: Invia payload webhook di test
  • Strumenti del provider di pagamento: Usa strumenti di test specifici del provider

Gestione degli Errori

Problemi Comuni

  1. Firma Non Valida: Verifica di utilizzare il client secret corretto
  2. Timeout: Assicurati che il tuo endpoint webhook risponda entro 30 secondi
  3. Eventi Duplicati: Implementa la gestione dell'idempotenza
  4. Payload Malformato: Valida la struttura del payload webhook

Codici di Stato HTTP

  • 200 OK: Webhook elaborato con successo
  • 400 Bad Request: Payload webhook non valido
  • 401 Unauthorized: Firma non valida
  • 500 Internal Server Error: Errore del server durante l'elaborazione

Considerazioni di Sicurezza

  1. Usa HTTPS: Utilizza sempre HTTPS per gli endpoint webhook
  2. Verifica le Firme: Non saltare mai la verifica della firma
  3. Valida i Payload: Controlla la struttura del payload e i campi richiesti
  4. Rate Limiting: Implementa rate limiting per prevenire abusi
  5. Whitelist IP: Considera di aggiungere alla whitelist gli indirizzi IP del server NoPos Pay

Comunicazione in Tempo Reale con PostMessage

Oltre ai webhook, NoPos Pay utilizza l'API postMessage per comunicare immediatamente il risultato del pagamento quando viene utilizzato in popup o iframe.

Eventi PostMessage

Quando un pagamento viene completato, NoPos Pay invia un messaggio postMessage con le seguenti informazioni:

interface PaymentCompleteMessage {
target: 'payment_complete';
transactionId: string; // ID univoco della transazione
status: string; // Stato del pagamento
}

Implementazione del Listener PostMessage

// Ascolta i messaggi dal popup/iframe di NoPos Pay
window.addEventListener('message', function(event) {
// Verifica l'origine per sicurezza
if (event.origin !== 'https://app.nopos.it') {
return;
}

// Controlla se è un messaggio di completamento pagamento
if (event.data.target === 'payment_complete') {
const { transactionId, status } = event.data;

// Gestisci il risultato del pagamento
handlePaymentComplete(transactionId, status);
}
});

function handlePaymentComplete(transactionId, status) {
console.log('Pagamento completato:', { transactionId, status });

// Aggiorna l'interfaccia utente
updatePaymentStatus(status);

// Chiudi il popup se necessario
if (window.opener) {
window.close();
}
}

Differenze tra Webhook e PostMessage

CaratteristicaWebhookPostMessage
TimingAsincrono (può avere ritardi)Immediato
AffidabilitàGarantito (con retry)Dipende dalla connessione
SicurezzaFirma HMACVerifica origine
UsoServer-sideClient-side
ScenariTuttiSolo popup/iframe

Best Practice per PostMessage

  1. Verifica sempre l'origine: Controlla che event.origin sia https://app.nopos.it
  2. Gestisci errori di connessione: Implementa fallback per quando postMessage non funziona
  3. Pulisci i listener: Rimuovi i listener quando non più necessari
  4. Combina con webhook: Usa postMessage per UX immediata e webhook per affidabilità

Supporto

Per problemi o domande relative ai webhook:

  • Consulta la documentazione delle API
  • Rivedi la guida alla risoluzione dei problemi
  • Contatta il supporto a support@nopos.it