# Node.js SDK (/it/online/integration/node_sdk)



`@tapayadot/checkout` è l'SDK TypeScript lato server per Tapaya Checkout. Questo riferimento descrive la versione **0.3.0**.

| Dettaglio                 | Valore                                                                                   |
| ------------------------- | ---------------------------------------------------------------------------------------- |
| **Pacchetto**             | `@tapayadot/checkout`                                                                    |
| **Versione**              | 0.3.0                                                                                    |
| **Runtime**               | Node.js 22.13.0 o versioni successive, moduli ES, dichiarazioni TypeScript incluse       |
| **Script per il browser** | Tapaya.js 0.2.0, caricato per [Embedded Checkout](/online/integration/embedded_checkout) |
| **Codice sorgente**       | [tapayadot/checkout-node](https://github.com/tapayadot/checkout-node)                    |

<CodeBlockTabs defaultValue="npm" groupId="package-manager">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="npm">
      npm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="pnpm">
      pnpm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="bun">
      Bun
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="npm">
    ```sh
    npm install @tapayadot/checkout
    ```
  </CodeBlockTab>

  <CodeBlockTab value="pnpm">
    ```sh
    pnpm add @tapayadot/checkout
    ```
  </CodeBlockTab>

  <CodeBlockTab value="bun">
    ```sh
    bun add @tapayadot/checkout
    ```
  </CodeBlockTab>
</CodeBlockTabs>

```ts
import { Tapaya } from '@tapayadot/checkout';

const tapaya = new Tapaya();
```

Il client legge `TAPAYA_SECRET_KEY` dall'ambiente del server. Il pacchetto contiene anche il loader per il browser e l'hook React per [Embedded Checkout](/online/integration/embedded_checkout). Il loader scarica Tapaya.js **0.2.0** da `https://js.tapaya.com/checkout/0.2.0/checkout.js`; la versione dello script per il browser è indipendente dalla versione di questo pacchetto. Il pacchetto non carica i file `.env`. Mantenga la chiave e il client in codice eseguito solo sul server. La [guida a Hosted Checkout](/online/integration/hosted_checkout) spiega come creare un ordine, reindirizzare il cliente e verificare il pagamento.

## Configurazione [#configuration]

```ts
const tapaya = new Tapaya(apiKey, {
	environment: 'sandbox',
	timeoutMs: 30_000,
	maxRetries: 2,
})
```

| Opzione                    | Predefinito                                                                                              | Descrizione                                                                                                                                                                                                     |
| -------------------------- | -------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `apiKey` (primo argomento) | `TAPAYA_SECRET_KEY`                                                                                      | Una chiave checkout dell'esercente, oppure la Secret key dell'organizzazione in modalità piattaforma.                                                                                                           |
| `environment`              | `TAPAYA_ENVIRONMENT`, altrimenti `production` per una chiave `tapaya_live_` e `sandbox` negli altri casi | `sandbox` (`https://api.sandbox.tapaya.com`) o `production` (`https://api.tapaya.com`). Una chiave live fuori dalla produzione, o una chiave di test in produzione, genera un errore alla creazione del client. |
| `baseUrl`                  | `TAPAYA_BASE_URL`, altrimenti l'URL selezionato da `environment`                                         | Sostituisce l'URL dell'API per le chiamate ospitate e incorporate.                                                                                                                                              |
| `timeoutMs`                | `30000`                                                                                                  | Timeout di ogni tentativo, in millisecondi.                                                                                                                                                                     |
| `merchantToken`            | Nessuno                                                                                                  | Token dell'esercente, inviato come `X-Tapaya-Merchant-Token`. Obbligatorio in modalità piattaforma.                                                                                                             |
| `maxRetries`               | `2`                                                                                                      | Nuovi tentativi dopo un errore di rete, un timeout, un HTTP 429, 502, 503 o 504, o una creazione ancora in corso.                                                                                               |
| `fetch`                    | `fetch` globale                                                                                          | Implementazione personalizzata di `fetch`, ad esempio per aggiungere un proxy o della strumentazione.                                                                                                           |

Per usare un endpoint API personalizzato, imposti `TAPAYA_BASE_URL=https://api.example.com` sul Suo server.
Un `baseUrl` esplicito ha la precedenza su `TAPAYA_BASE_URL`; entrambi prevalgono sulla selezione dell'ambiente.

Il client determina la chiave API e l'URL dell'API una sola volta, quando viene creato. Usi una chiave che corrisponda
all'ambiente selezionato. Gli URL dell'API, di ritorno e di Hosted Checkout devono usare HTTPS, con l'eccezione che HTTP è consentito per
`localhost`, `127.0.0.1` e `[::1]` al di fuori di `NODE_ENV=production`. L'SDK controlla il valore corrente di `NODE_ENV` ogni
volta che convalida un URL HTTP locale.

`timeoutMs` deve essere un intero da 1 a 2.147.483.647. `maxRetries` deve essere un intero sicuro non negativo. Il numero predefinito di nuovi tentativi consente fino a tre tentativi per chiamata, ciascuno con il proprio timeout.

Ogni metodo accetta anche `signal`, `timeoutMs` e `maxRetries` per una singola richiesta:

```ts
const current = await tapaya.checkout.sessions.get(sessionId, {
	signal: request.signal,
	timeoutMs: 5_000,
})
```

Quando il signal viene interrotto, il metodo si ferma immediatamente, senza nuovi tentativi, e la promise viene rifiutata con il reason del signal.

## Sessioni di Checkout [#checkout-sessions]

### Selezionare un esercente [#select-a-merchant]

In modalità esercente, una chiave checkout dell'esercente identifica il proprio esercente. Usi `new Tapaya()` senza `merchantToken`.

In modalità piattaforma, un'unica Secret key dell'organizzazione serve molti esercenti. Ogni richiesta richiede un token dell'esercente; non
esiste un esercente predefinito e una richiesta senza token fallisce con `TapayaAuthenticationError`. Copi i token dalla
tabella degli esercenti nelle [impostazioni di Checkout](/online/integration/checkout_settings) e passi il token dell'ordine sia alla
creazione sia al recupero:

```ts
const tapaya = new Tapaya(process.env.TAPAYA_SECRET_KEY)
const session = await tapaya.checkout.sessions.create(params, {
	merchantToken: order.merchantToken,
	idempotencyKey: order.checkoutAttemptKey,
})
const current = await tapaya.checkout.sessions.get(session.id, {
	merchantToken: order.merchantToken,
})
```

Può anche impostare un token predefinito con `new Tapaya(key, { merchantToken })`. Il token si applica alle chiamate ospitate e
incorporate. Tapaya rifiuta i token esterni all'organizzazione della chiave. Con una chiave dell'esercente, il token è facoltativo e deve
indicare l'esercente a cui appartiene la chiave. Si veda [Autenticazione di Checkout](/online/integration/api_integration#authentication).

### Creare una sessione [#create-a-session]

`tapaya.checkout.sessions.create(params, options?)` richiede `merchantOrderId`, `amount` e `currency`.
`merchantOrderId` è il Suo riferimento dell'ordine, da 1 a 200 caratteri. Un ordine può essere pagato una sola volta; una nuova sessione per
un ordine non pagato sostituisce quella precedente. Si veda [Un pagamento per ordine](/online/integration/api_integration#one-payment-per-order). `amount` è il totale finale,
imposte e spedizione comprese, un intero tra 1 e 2.147.483.647 unità minime della valuta. `currency` è un codice ISO 4217
di tre lettere. Tapaya lo salva e lo restituisce in maiuscolo.

Campi facoltativi:

| Campo                     | Descrizione                                                                                                                                                                                             |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `locale`                  | Lingua della pagina ospitata, ad esempio `en`. Valore predefinito: `en`.                                                                                                                                |
| `successUrl`, `cancelUrl` | URL di ritorno. Per impostazione predefinita, gli URL delle Sue impostazioni di Checkout.                                                                                                               |
| `tax`, `shipping`         | Imposte e spedizione incluse in `amount`, nell'unità minore della valuta.                                                                                                                               |
| `taxRate`                 | Aliquota d'imposta unica in punti percentuali, ad esempio `21`.                                                                                                                                         |
| `taxBreakdown`            | Imposta per aliquota, `[{ taxRate, tax }]`, per ordini con aliquote miste. Da usare al posto di `taxRate`: i tipi non accettano entrambi insieme.                                                       |
| `items`                   | Prodotti mostrati nella pagina ospitata: `reference`, `name`, `description`, `imageUrl`, `quantity` e `unitAmount`. Le righe servono solo per la visualizzazione e non modificano l'importo addebitato. |
| `customer`                | `email`, `billingAddress` e `shippingAddress` facoltativi. Invii solo i dati che raccoglie.                                                                                                             |

Prima dell'invio, l'SDK controlla i tipi, i campi obbligatori, gli importi interi, il formato della valuta e una lunghezza massima dell'email
di 254 caratteri. Gli URL di ritorno devono essere URL HTTPS assoluti, con l'eccezione per HTTP locale descritta in
[Configurazione](#configuration). Tapaya convalida le regole di business, come il formato dell'email, i limiti dell'indirizzo e i codici
paese, e segnala i problemi come `TapayaInvalidRequestError`. Si veda
[Sessioni di Checkout](/online/integration/api_integration#checkout-sessions) per le regole dei campi,
i totali delle imposte e i limiti dell'indirizzo del cliente.

### Recuperare una sessione [#get-a-session]

`tapaya.checkout.sessions.get(id, options?)` restituisce lo stato attuale di una sessione. L'ID deve essere una stringa non vuota di al massimo 200 caratteri; `.` e `..` non sono validi. L'SDK codifica l'ID per l'URL.

La creazione e il recupero di una sessione ospitata restituiscono un `HostedCheckoutSession`. Per i metodi incorporati `prepare()`, `verify()` e `configuration()`, si veda [Embedded Checkout](/online/integration/embedded_checkout).

Campi della sessione ospitata:

| Campo                                        | Descrizione                                                                                                                    |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `id`                                         | ID della sessione, ad esempio `cs_Y7u2d`.                                                                                      |
| `url`                                        | Pagina di pagamento ospitata. Reindirizzi il cliente a questo URL senza modificarlo.                                           |
| `merchantOrderId`, `amount`, `currency`      | Dati dell'ordine da confrontare con l'ordine salvato.                                                                          |
| `status`                                     | `open`, `completed` o `expired`. Le sessioni accettano nuovi pagamenti per 30 minuti. Potrebbero essere aggiunti nuovi valori. |
| `paymentStatus`                              | `unpaid`, `successful`, `failed`, `cancelled` o `action_needed`. Potrebbero essere aggiunti nuovi valori.                      |
| `paymentReference`                           | Token dell'ultimo tentativo di pagamento, oppure `null` prima del primo tentativo.                                             |
| `tax`, `shipping`, `taxRate`, `taxBreakdown` | Totali inviati alla creazione della sessione. Valori predefiniti: `0`, `0`, `null` e `[]`.                                     |
| `items`                                      | Righe inviate alla creazione della sessione, oppure un array vuoto.                                                            |
| `createdAt`, `expiresAt`, `completedAt`      | Timestamp ISO 8601. `completedAt` è `null` finché il pagamento non va a buon fine.                                             |

Gestisca i valori sconosciuti di `status` e `paymentStatus`, ad esempio trattandoli come non ancora pagati. Solo
`paymentStatus: 'successful'` prova il pagamento.

Una carta rifiutata è un esito del pagamento, non un errore. La sessione resta `open` con `paymentStatus: 'failed'` e
il cliente può riprovare. Mentre Tapaya conferma un esito incerto, la sessione resta `open` e `unpaid`.
I webhook non sono ancora disponibili; interroghi periodicamente `get()` da un job di riconciliazione.

## Idempotenza e nuovi tentativi [#idempotency-and-retries]

Ogni richiesta di creazione invia un `Idempotency-Key`. Una chiave esplicita deve essere una stringa non vuota di caratteri ASCII stampabili. Tapaya accetta al massimo 250 caratteri. Se omette `idempotencyKey`, l'SDK genera una chiave casuale per
ogni chiamata. All'interno di quella chiamata, i nuovi tentativi riutilizzano la chiave, quindi un nuovo tentativo non crea mai una seconda sessione.

Per operare in sicurezza anche tra chiamate separate e riavvii del processo, salvi una chiave insieme all'ordine e la passi ogni volta che
crea una sessione per quel tentativo, con gli stessi parametri. Tapaya restituisce la sessione originale invece di
crearne una nuova. Usi una nuova chiave solo per un nuovo tentativo di checkout, mai per ripetere una richiesta con esito incerto.

Una creazione ospitata ripetuta restituisce la stessa sessione con i suoi `status` e `paymentStatus` attuali.
Chiami `tapaya.checkout.sessions.get(session.id)` per verificare di nuovo lo stato prima di evadere l'ordine.

Per lo stesso esercente, i nuovi tentativi ospitati devono usare lo stesso corpo della richiesta e la stessa modalità di credenziale: chiave checkout
dell'esercente o Secret key dell'organizzazione. Modificare uno dei due restituisce HTTP 409 con codice `API-0025`. Cambiare modalità di credenziale
genera un conflitto anche quando il corpo è identico, perché ogni modalità usa le proprie impostazioni di reindirizzamento.

L'SDK ripete entrambi i metodi dopo errori di rete, timeout e HTTP 429, 502, 503 e 504. Ripete anche una
creazione che fallisce con HTTP 409 `API-0024`. I nuovi tentativi inviano la stessa chiave e lo stesso corpo, quindi restituiscono la sessione originale. L'SDK
attende tra un tentativo e l'altro con backoff esponenziale e jitter, e rispetta `Retry-After` fino a 10 secondi. Quando Tapaya
richiede un'attesa più lunga, l'SDK smette di riprovare e genera l'errore corrispondente a quello stato HTTP: `TapayaRateLimitError`
per 429, `TapayaServerError` per 502, 503 o 504, oppure `TapayaConflictError` per 409. Solo `TapayaRateLimitError`
espone il ritardo richiesto come `retryAfterMs`; gli altri errori HTTP conservano l'intestazione `Retry-After` in `headers`.
Tutti i nuovi tentativi condividono il limite `maxRetries`. Imposti `maxRetries: 0` per disattivare i nuovi tentativi.

Non passi mai a una nuova chiave per aggirare un esito incerto. La richiesta originale potrebbe aver già creato una
sessione; con una nuova chiave e lo stesso ordine non pagato, la nuova sessione la sostituisce.

## Errori [#errors]

Le classi di errore dell'SDK estendono `TapayaError`. Una richiesta interrotta viene rifiutata con il reason del signal.

| Errore                      | Quando                                                                                                                                                                                                    |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `TapayaError`               | Chiave API mancante o configurazione del client non valida; classe base degli errori dell'SDK.                                                                                                            |
| `TapayaValidationError`     | I parametri non hanno superato la convalida prima dell'invio della richiesta.                                                                                                                             |
| `TapayaAuthenticationError` | HTTP 401: la chiave è mancante o non valida, il token dell'esercente manca in modalità piattaforma, oppure il token non corrisponde a un esercente attivo.                                                |
| `TapayaInvalidRequestError` | HTTP 400 o 422: Tapaya ha rifiutato i parametri.                                                                                                                                                          |
| `TapayaPermissionError`     | HTTP 403.                                                                                                                                                                                                 |
| `TapayaNotFoundError`       | HTTP 404: la sessione non esiste per questo esercente.                                                                                                                                                    |
| `TapayaConflictError`       | HTTP 409. `code` è `API-0025` quando la idempotency key è già stata usata con parametri diversi. Anche la creazione di una sessione per un ordine già pagato o con un pagamento in corso restituisce 409. |
| `TapayaRateLimitError`      | HTTP 429 dopo i nuovi tentativi, oppure subito quando `Retry-After` supera i 10 secondi. `retryAfterMs` contiene il ritardo richiesto, quando Tapaya lo invia.                                            |
| `TapayaServerError`         | HTTP 5xx. Vengono ripetuti solo 502, 503 e 504, a meno che i nuovi tentativi siano disattivati o `Retry-After` superi i 10 secondi. Gli altri stati 5xx generano subito un errore.                        |
| `TapayaApiError`            | Classe base degli errori HTTP sopra elencati e di qualsiasi altro stato di errore HTTP.                                                                                                                   |
| `TapayaConnectionError`     | La richiesta non è riuscita o la risposta è andata persa dopo i nuovi tentativi. L'errore originale si trova in `cause`.                                                                                  |
| `TapayaTimeoutError`        | Un `TapayaConnectionError` per un tentativo che ha superato `timeoutMs`.                                                                                                                                  |
| `TapayaResponseError`       | Tapaya ha restituito una risposta che l'SDK non è riuscito a leggere.                                                                                                                                     |

Gli errori HTTP contengono `status`, il `code` di errore di Tapaya, `fieldErrors` (`{ field, message, code? }[]`), gli
`headers` della risposta e `requestId` dall'intestazione `X-Request-Id`, se presente. Attualmente il backend non
imposta questa intestazione. Nelle richieste di assistenza indichi l'ID della sessione o il riferimento dell'ordine e l'ora della richiesta, insieme a
`requestId`, se disponibile. Anche `TapayaResponseError` contiene `status`, `headers` e `requestId`.
Anche `TapayaValidationError` contiene `fieldErrors`, con `field` impostato sul percorso del parametro, ad esempio `customer.email`.

```ts
import { TapayaConnectionError, TapayaError, TapayaValidationError } from '@tapayadot/checkout'

try {
	const session = await tapaya.checkout.sessions.create(params, { idempotencyKey })
	return Response.redirect(session.url, 303)
} catch (error) {
	if (error instanceof TapayaValidationError) {
		console.error(error.fieldErrors)
	} else if (error instanceof TapayaConnectionError) {
		// The outcome is unknown. Retry later with the same idempotency key.
	} else if (error instanceof TapayaError) {
		console.error(error.message)
	}
	throw error
}
```

## Tipi esportati [#exported-types]

Il pacchetto esporta `TapayaEnvironment`, `TapayaOptions`, `RequestOptions`, `CreateSessionOptions`, `CreateCheckoutSessionParams`, `CheckoutSessions`, `CheckoutSession`, `CheckoutSessionStatus`, `CheckoutPaymentStatus`, `CheckoutItem`, `TaxBreakdownEntry`, `CheckoutCustomer`, `CheckoutContactAddress` e `TapayaFieldError`.

`VERSION` contiene la versione dell'SDK. I tipi si importano con import con nome tramite `import type`:

```ts
import type { CheckoutSession, CreateCheckoutSessionParams } from '@tapayadot/checkout';
```

## Aggiornamento dalla versione 0.2.x [#upgrade-from-02x]

* Il loader per il browser carica Tapaya.js 0.2.0, che supporta Apple Pay e Google Pay. Rifiuta uno script 0.1.x già caricato. Aggiorni ogni tag script che gestisce a `https://js.tapaya.com/checkout/0.2.0/checkout.js`.
* `environment: 'production'` supporta sia i pagamenti ospitati sia quelli incorporati. `configuration()` restituisce `environment: 'production'` con le chiavi del gateway live.
* Senza un ambiente esplicito o `TAPAYA_ENVIRONMENT`, una chiave `tapaya_live_` seleziona la produzione. Le credenziali che non corrispondono all'ambiente selezionato generano un errore durante la creazione del client. `baseUrl` continua a sostituire l'URL dell'API.
