Tapaya
Accettazione in presenzaGuida all'integrazioneCloud Accept APIBeta

Cloud Accept API

Beta

Avvii pagamenti in presenza su un dispositivo Tapaya associato dal Suo ECR o dal backend POS.

La Cloud Accept API consente al Suo registratore di cassa elettronico (ECR) o al backend POS di avviare un pagamento su un dispositivo Tapaya tramite il cloud. Il Suo sistema non comunica mai direttamente con il dispositivo: invia una richiesta di pagamento a Tapaya, Tapaya avvisa il dispositivo associato e il dispositivo mostra al cliente la schermata di pagamento. L'avanzamento Le viene comunicato tramite webhook, oppure può interrogarlo periodicamente (polling).

Scegliere come associare i dispositivi

Ogni dispositivo a cui invia pagamenti richiede un externalDeviceId: il nome con cui il Suo sistema lo identifica, ad esempio till-01. Può assegnarlo in uno dei due modi seguenti:

Prima di iniziare

  1. Ottenga il Suo Server Secret Token dalla pagina API Keys. Più avanti lo scambierà con un token di accesso limitato all'esercente (consulti Autenticazione della Platform API).
  2. Registri l'esercente e conservi il relativo merchantToken. Consulti Registrare un nuovo esercente.
  3. Prepari ogni dispositivo con l'app Tapaya in cui è stato effettuato l'accesso per quell'esercente, così che possa essere associato e ricevere richieste.

Un token, un esercente

Ogni chiamata alla Cloud Accept API è limitata a un solo esercente. Per servire più esercenti, scambi un token di accesso separato per ciascuno.

Associare un dispositivo

L'associazione assegna un externalDeviceId a un dispositivo Tapaya, così può trovarlo quando elenca i dispositivi e indicarlo come destinazione quando avvia un pagamento.

Assegnare dalla Sua app

La Sua applicazione chiama una funzione dell'Accept SDK sul dispositivo per assegnarne l'externalDeviceId. Usi lo stesso identificatore in ogni chiamata alla Cloud Accept API per quel dispositivo.

Scansionare un codice QR

L'esercente apre la procedura di associazione nella Tapaya Platform, che mostra un codice QR per l'externalDeviceId da assegnare. L'esercente lo scansiona con l'app Tapaya per esercenti sul dispositivo di destinazione e l'app completa l'associazione.

Ottenere un token di accesso

Scambi il Suo Server Secret Token e il merchantToken dell'esercente con un token di accesso tramite POST /ecr/auth. merchantToken viene inviato solo qui; tutte le chiamate successive inviano soltanto Authorization: Bearer <accessToken>.

curl -X 'POST' 'https://api.tapaya.com/ecr/auth' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer REPLACE_ME' \
-d '{
        "merchantToken": "unique_merchant_id_from_your_db"
    }'
200 OK
{
    "accessToken": "...",
    "tokenType": "Bearer",
    "expiresAt": "2026-01-13T16:30:59Z"
}
CodiceDescrizione
401Token API non valido o scaduto.
403L'accesso all'esercente non è consentito.

Rinnovi prima di expiresAt. Chiami POST /ecr/auth/refresh con l'accessToken attuale, ancora valido, nell'header Authorization. Restituisce lo stesso corpo con un nuovo token; lo salvi e da quel momento usi quello.

curl -X 'POST' 'https://api.tapaya.com/ecr/auth/refresh' \
-H 'Authorization: Bearer ACCESS_TOKEN'
CodiceDescrizione
401Il token di accesso non è valido, è scaduto o è stato revocato. Ne ottenga uno nuovo tramite POST /ecr/auth.
403Non ha più accesso all'esercente. Non viene emesso alcun nuovo token.

Trovare un dispositivo pronto

Elenchi i dispositivi dell'esercente con GET /ecr/devices. Aggiunga ?connected=true per escludere i dispositivi disconnessi, oppure recuperi un singolo dispositivo con GET /ecr/devices/{externalDeviceId}.

curl 'https://api.tapaya.com/ecr/devices/till-01' \
-H 'Authorization: Bearer ACCESS_TOKEN'
200 OK
{
    "externalDeviceId": "till-01",
    "name": "Front counter",
    "connected": true,
    "availability": "ready",
    "lastSeenAt": "2026-01-13T16:30:59Z",
    "updatedAt": "2026-01-13T16:30:59Z"
}

Invii pagamenti solo a un dispositivo con availability pari a ready. L'elenco è un'istantanea: la disponibilità viene verificata di nuovo al momento dell'invio, quindi anche un dispositivo ready può rifiutare una richiesta. Consulti Disponibilità del dispositivo.

Inviare una richiesta di pagamento

Invii l'importo a un dispositivo con POST /ecr/payment-requests. Tapaya salva la richiesta e avvisa il dispositivo, che mostra la schermata di pagamento.

curl -X 'POST' 'https://api.tapaya.com/ecr/payment-requests' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Idempotency-Key: order-1042-attempt-1' \
-d '{
        "externalDeviceId": "till-01",
        "amount": 12500,
        "tipAmount": 500,
        "currency": "CZK"
    }'

Parametri:

CampoTipoObbligatorioDescrizione
externalDeviceIdstring✓Il dispositivo associato che deve mostrare il pagamento.
amountinteger✓Importo nell'unità minore della valuta (12500 corrisponde a 125,00 Kč).
tipAmountintegerMancia nell'unità minore della valuta.
currencystring✓Codice valuta ISO 4217.
paymentTokenstringUn pagamento esistente a cui associare la richiesta.
202 Accepted
{
    "requestId": "...",
    "status": "pending",
    "paymentToken": null,
    "expiresAt": "2026-01-13T16:30:59Z"
}

202 non è un esito del pagamento

202 Accepted significa che Tapaya ha salvato la richiesta. Non significa che il dispositivo l'abbia ricevuta né che il cliente abbia pagato. Qualsiasi errore successivo Le arriva come cambio di stato.

Renda sicuri i nuovi tentativi. L'header Idempotency-Key è obbligatorio. Riutilizzare una chiave con lo stesso corpo restituisce la richiesta originale invece di avviare un secondo pagamento; riutilizzarla con un corpo diverso restituisce 409 idempotency_conflict. Leghi la chiave alla vendita e al tentativo, come in order-1042-attempt-1.

Seguire il risultato

Segua la richiesta attraverso i suoi stati con i webhook, oppure interroghi periodicamente GET /ecr/payment-requests/{requestId}. Quando raggiunge payment_created, la risposta contiene il paymentToken e gli eventi payment.updated riportano l'avanzamento del pagamento stesso.

Per ricevere i webhook, registri il Suo endpoint HTTPS con POST /ecr/webhook-subscriptions, oppure imposti l'URL di callback e i tipi di evento per l'esercente nella Tapaya Platform.

curl -X 'POST' 'https://api.tapaya.com/ecr/webhook-subscriptions' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-d '{
        "url": "https://integrator.example.com/webhooks/tapaya",
        "events": ["payment_request.updated", "payment.updated"]
    }'
201 Created
{
    "subscriptionId": "...",
    "url": "https://integrator.example.com/webhooks/tapaya",
    "events": ["payment_request.updated", "payment.updated"],
    "signingSecret": "..."
}

Conservi il signing secret

signingSecret viene restituito solo alla creazione della sottoscrizione. Lo conservi in modo sicuro; Le serve per verificare la firma dei webhook in arrivo.

Una sottoscrizione appartiene all'integratore e all'esercente, non a un token di accesso, quindi resta valida anche dopo il rinnovo del token. Risponda a ogni evento con un 2xx dopo averlo accettato.

Verifichi prima di chiudere la vendita

I webhook sono notifiche, non prove di pagamento, e un webhook può arrivare in ritardo o non arrivare affatto. Non chiuda mai una vendita basandosi solo su un webhook:

  • Quando arriva un webhook, confermi il risultato finale tramite l'API, ad esempio con Recuperare i dettagli del pagamento.
  • Quando non arriva alcun webhook entro un timeout adatto al Suo flusso di checkout, e comunque non oltre l'expiresAt della richiesta, chiami GET /ecr/payment-requests/{requestId} per leggerne lo stato attuale, quindi confermi il pagamento tramite l'API come indicato sopra.

Riferimento

Endpoint

MetodoEndpointDescrizione
POST/ecr/authScambia il Suo token API e un merchantToken con un token di accesso.
POST/ecr/auth/refreshRinnova un token di accesso ancora valido.
GET/ecr/devicesElenca i dispositivi dell'esercente. Filtro facoltativo connected=true.
GET/ecr/devices/{externalDeviceId}Restituisce un dispositivo e la sua disponibilità attuale.
POST/ecr/payment-requestsSalva una richiesta di pagamento e avvisa il dispositivo. Richiede Idempotency-Key.
GET/ecr/payment-requests/{requestId}Restituisce lo stato della richiesta, l'eventuale motivo del rifiuto e il paymentToken.
POST/ecr/webhook-subscriptionsRegistra un URL HTTPS e i tipi di evento. Restituisce il signing secret (chiave di firma) una sola volta.
GET/ecr/webhook-subscriptionsElenca le Sue sottoscrizioni per l'esercente, senza signing secret.
DELETE/ecr/webhook-subscriptions/{subscriptionId}Rimuove una sottoscrizione.

Disponibilità del dispositivo

Entrambi gli endpoint dei dispositivi restituiscono externalDeviceId, name, connected, availability, lastSeenAt e updatedAt.

ValoreDescrizione
readyConnesso e in grado di ricevere e mostrare una richiesta.
busySta elaborando un pagamento o ha una richiesta attiva.
unavailableDisconnesso, senza una sessione valida o non in grado di mostrare la schermata di pagamento.

Stati della richiesta

StatoDescrizione
pendingSalvata e in attesa che il dispositivo la accetti.
acknowledgedIl dispositivo l'ha ricevuta; il pagamento potrebbe non esistere ancora.
payment_createdEsistono un pagamento e il relativo paymentToken. Segua l'ulteriore avanzamento sul pagamento.
rejectedIl dispositivo o Tapaya ha rifiutato la richiesta.

Errori

CodiceMotivoDescrizione
403 / 404Oggetto non disponibileNon dispone dell'autorizzazione, oppure l'oggetto non esiste.
409device_busyIl dispositivo ha già una richiesta o un pagamento attivo.
409device_unavailableIl dispositivo è connesso ma non è pronto.
409idempotency_conflictLa chiave è già stata usata con un corpo diverso.
503device_offlineIl dispositivo non è connesso.

Gli errori di convalida dell'importo e della valuta seguono le stesse convenzioni del resto della Platform API.

Eventi webhook

EventoInviato quandoContenuto di data
device.connectedUn dispositivo apre una nuova connessione attiva.externalDeviceId, connected, availability, lastSeenAt
device.disconnectedLa connessione si chiude o il controllo di attività della connessione va in timeout.externalDeviceId, connected, availability, lastSeenAt
device.availability_changedLa disponibilità passa tra ready, busy e unavailable.externalDeviceId, availability, reason facoltativo
payment_request.updatedLa richiesta viene salvata, ricevuta, rifiutata, scade o le viene associato un pagamento.requestId, externalDeviceId, status, paymentToken, reference, reason, expiresAt
payment.updatedLo stato del pagamento cambia.paymentToken, requestId, externalDeviceId, status, reference, amount, currency, receiptUrl facoltativo

Ogni evento arriva come HTTP POST con la stessa struttura (envelope):

{
    "eventId": "...",
    "type": "payment_request.updated",
    "occurredAt": "2026-01-13T16:30:59Z",
    "data": {
        "requestId": "...",
        "externalDeviceId": "till-01",
        "status": "acknowledged",
        "paymentToken": null,
        "reference": "ORDER-1042",
        "reason": null,
        "expiresAt": "2026-01-13T16:30:59Z"
    }
}
Manca qualcosa in questa pagina?Richieda una funzionalità. Alleghiamo questa pagina, così il team vede il contesto.