Documentazione

1Introduzione ai metodi di integrazione dei terminali

In genere esistono due modi per elaborare i pagamenti su un terminale:

  • Utilizzare il terminale in modalità autonoma, in cui il cassiere inserisce l'importo da addebitare sul terminale, oppure

  • collegare la cassa al terminale e consentire alla cassa di coordinare il pagamento sul terminale.

In modalità autonoma non è richiesta alcuna integrazione e il terminale può quindi essere utilizzato semplicemente. Le transazioni effettuate sul terminale compaiono nell'elenco delle transazioni una volta eseguite.

Se prevedete di integrare la vostra applicazione con il terminale, avete a disposizione le seguenti opzioni:

  • Collegarvi al terminale tramite un socket nella rete locale. Se siete interessati a questa integrazione, vi preghiamo di contattarci.

  • Collegarvi al terminale tramite un websocket. Il WebSocket utilizzerà un server dalla nostra parte per collegarsi al dispositivo terminale.

  • Collegarvi al terminale tramite una richiesta HTTP in long polling.

Il resto della documentazione si concentra sui due ultimi metodi di connessione. I metodi di connessione sono in generale molto simili:

  1. Assicuratevi che il terminale sia connesso a Internet. Questo può variare a seconda dell'hardware del terminale.

  2. Create una transazione con il Transaction Service. Utilizzate l'operazione create per creare una nuova transazione.

  3. Collegate la vostra cassa per inizializzare l'elaborazione del pagamento utilizzando WebSockets o il meccanismo di long polling.

La creazione della transazione avviene nello stesso modo di qualsiasi altra integrazione.

Se non siete sicuri di quale metodo utilizzare, abbiamo provato a elencare alcune proprietà dei diversi metodi:

  • Il long polling è più semplice da integrare, poiché il long polling tramite WebSockets utilizza semplicemente un'operazione di servizio web standard.

  • Il long polling non offre alcuna interazione con il cliente. Tali interazioni consentono una migliore esperienza per il cliente.

2Integrazione della cassa con Long Polling

Come primo passo dovete creare una transazione. A tale scopo potete utilizzare il Transaction Service e l’operazione creare.

Successivamente potete utilizzare l’operazione eseguire la transazione per avviare una transazione sul terminale. L’operazione perform transaction non risponde alla richiesta HTTP per circa 80 secondi al massimo. Durante questo tempo il terminale tenta di eseguire la transazione. Quando la transazione riesce o fallisce, l’operazione perform transaction restituisce immediatamente il risultato. Nel caso in cui il terminale abbia bisogno di più tempo, il metodo risponde con lo stato HTTP 543. In questo caso il metodo deve essere invocato nuovamente con gli stessi parametri.

Il seguente pseudocodice mostra come implementare questo schema:

function carryOutTransaction(spaceId, terminalId, transactionId) {
	for (i = 0; i < 10; i++) {
		try {
			paymentTerminalTillService.performTransaction(spaceId, transactionId, terminalId);
		}
		catch(Exception e) {
			// We log the exception but do not stop the processing. Generally
			// it is better not just to repeat with the status code 543 rather also
			// with any other error that can be caused by a connection issue.
			log(e);
		}
	}
}

Esistono due diverse operazioni perform transaction sul Payment Terminal Till Service:

  • Potete eseguire la transazione con l’ID del terminale oppure

  • Potete eseguire la transazione con l’identificativo del terminale.

L’identificativo del terminale è l’ID che vedete anche sulla ricevuta ecc. Lo schema è 3xxx xxxx. L’identificativo del terminale, invece, è un numero più corto visibile solo all’interno del portale.

3Integrazione della cassa con WebSocket

Poiché durante il processo di pagamento ci sono interazioni tra il cassiere e il terminale, è necessario utilizzare una tecnica che le supporti. In concreto, l’interazione richiede una comunicazione bidirezionale. I WebSocket consentono questo tipo di comunicazione.

All’interno del WebSocket viene utilizzato il protocollo STOMP per scambiare messaggi. Vedere https://stomp.github.io/stomp-specification-1.2.html

3.1Connessione

La connessione apre il canale e, di conseguenza, l’elaborazione della transazione sul terminale viene avviata. Tutti i dettagli della transazione, come l’importo ecc., vengono ripresi dall’oggetto transazione creato in precedenza con il Transaction Service tramite la consueta API REST.

Quando il WebSocket si interrompe a causa di un problema di rete (ad esempio in una rete mobile questo può accadere spesso), l’elaborazione del pagamento non si ferma. Il WebSocket può essere riaperto e il Connect può essere inviato di nuovo. Il sistema tenta di riprendere la transazione. Se il timeout è stato raggiunto, la transazione fallisce e di conseguenza il messaggio error viene inviato dal server. In questo caso deve essere avviata una nuova transazione.

3.2Messaggi WebSocket

I messaggi da visualizzare sulla cassa vengono trasmessi come semplici oggetti JavaScript e possono contenere i seguenti elementi.

3.2.1Notifica

La notifica contiene informazioni da visualizzare all’operatore sulla cassa.

{
	information: {
		elements: [ ... ],
		recipient: "CUSTOMER" or "MERCHANT"
	}
}

3.2.2Domanda

La domanda contiene informazioni da visualizzare all’operatore sulla cassa e opzioni tra cui deve scegliere.

{
	information: {
		elements: [ ... ],
		recipient: "CUSTOMER" or "MERCHANT"
	},
	options: [
		{
			identifier: "option-1",
			text: "First option",
			primary: true
		},
		{
			identifier: "option-2",
			text: "Second option",
			primary: false
		}
	]
}

3.2.3Errore

Gli errori relativi alle richieste WebSocket contengono le seguenti informazioni.

{
	id: "ab-1234567 (2000-01-01T00:00:00.000Z)",
	date: "2000-01-01T00:00:00.000",
	message: "Translated error message",
	defaultMessage: "English error message",
	type: "END_USER_ERROR" or "CONFIGURATION_ERROR" or "DEVELOPER_ERROR" or "SERVER_ERROR"
}

3.3Elementi

Paragrafo

Il paragrafo rappresenta un blocco di testo.

Esempio

Ridiculus metus pulvinar morbi natoque sem etiam dictum, hac ipsum placerat risus orci est ante, fames tellus felis erat elit gravida. Euismod facilisis gravida sollicitudin nisi pellentesque tincidunt enim fusce dictum sit, odio magna feugiat interdum varius himenaeos diam venenatis sociis.

{
	text: "Ridiculus metus pulvinar morbi natoque sem etiam dictum, hac ipsum placerat risus orci est ante, fames tellus felis erat elit gravida. Euismod facilisis gravida sollicitudin nisi pellentesque tincidunt enim fusce dictum sit, odio magna feugiat interdum varius himenaeos diam venenatis sociis.",
	type: "PARAGRAPH"
}

Lista ordinata

La lista ordinata rappresenta un elenco numerato di voci:

Esempio
  1. First

  2. Second

  3. Third

{
	items: [
		{ text: "First" },
		{ text: "Second" },
		{ text: "Third" }
	],
	type: "ORDERED_LIST"
}

Lista non ordinata

La lista non ordinata rappresenta un elenco di voci con punti elenco.

Esempio
  • First

  • Second

  • Third

{
	items: [
		{ text: "First" },
		{ text: "Second" },
		{ text: "Third" }
	],
	type: "UNORDERED_LIST"
}

Lista descrittiva

La lista ordinata rappresenta un elenco di voci con descrizione.

Esempio
First

The first element

Second

The second element

Third

The third element

{
	items: [
		{
			description: "First",
			text: "The first element"
		},
		{
			description: "Second",
			text: "The second element"
		},
		{
			description: "Third",
			text: "The third element"
		}
	],
	type: "DESCRIPTION_LIST"
}

Tabella

Table 1. Esempio
Text Number Amount

First

1

USD1.00

Second

2

CHF2.00

Third

3

EUR3.00

{
	columns: [
		{
			identifier: "text",
			text: "Text",
			type: "TEXT"
		},
		{
			identifier: "number",
			text: "Number",
			type: "NUMBER"
		},
		{
			identifier: "amount",
			text: "Amount",
			type: "AMOUNT"
		}
	],
	rows: [
		{ cells: [
			{ column: "text", text: "First" },
			{ column: "number", text: "1" },
			{ column: "amount", text: "USD1.00" }
		] },
		{ cells: [
			{ column: "text", text: "Second" },
			{ column: "number", text: "2" },
			{ column: "amount", text: "CHF2.00" }
		] },
		{ cells: [
			{ column: "text", text: "Third" },
			{ column: "number", text: "3" },
			{ column: "amount", text: "EUR3.00" }
		] },
	],
	type: "TABLE"
}

4SDK JavaScript

Per collegare la vostra cassa tramite un WebSocket utilizzando JavaScript, consigliamo di utilizzare la nostra utility JavaScript TerminalTillConnection.

  1. Includete il file JavaScript dell’utility.

    <script src="https://staging-wallee.com/assets/payment/terminal-till-connection.js" type="text/javascript"></script>
  2. Create una nuova istanza di TerminalTillConnection passando come opzioni l’URL del WebSocket e le credenziali di connessione.

    var tillConnection = new TerminalTillConnection({
    	url: "wss://staging-wallee.com/terminal-websocket",
    	token: "[connection-credentials]"
    });
  3. Sottoscrivete gli eventi per gestire i messaggi provenienti dal terminale.

    tillConnection.subscribe("notification", function(payload){
    	// Display the information on the till.
    });
    
    tillConnection.subscribe("question", function(payload, callback){
    	// Display the question on the till and allow the attendant to chose one of the options.
    	// Call the callback method with the chosen option's identifier as argument.
    	callback(optionIdentifier);
    });
    
    tillConnection.subscribe("charged", function(){
    	// The transaction has been successfully charged.
    });
    
    tillConnection.subscribe("canceled", function(){
    	// The payment was canceled.
    });
    
    tillConnection.subscribe("error", function(error){
    	// An error occurred during the process of a WebSocket request.
    });
    
    tillConnection.subscribe("connected", function(){
    	// The connection has been established.
    });
    
    tillConnection.subscribe("disconnected", function(){
    	// The connection has been disconnected or lost.
    });
  4. Stabilite la connessione.

    tillConnection.connect();
  5. Utilizzate il metodo cancel per annullare il pagamento.

    tillConnection.cancel();
Staging 2.218.1