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



`@tapayadot/checkout` est le SDK TypeScript côté serveur de Tapaya Checkout. Cette référence décrit la version **0.3.0**.

| Détail                        | Valeur                                                                                    |
| ----------------------------- | ----------------------------------------------------------------------------------------- |
| **Paquet**                    | `@tapayadot/checkout`                                                                     |
| **Version**                   | 0.3.0                                                                                     |
| **Environnement d’exécution** | Node.js 22.13.0 ou version ultérieure, modules ES, déclarations TypeScript incluses       |
| **Script navigateur**         | Tapaya.js 0.2.0, chargé pour l’[Embedded Checkout](/online/integration/embedded_checkout) |
| **Source**                    | [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();
```

Le client lit `TAPAYA_SECRET_KEY` dans l’environnement du serveur. Le paquet contient également le chargeur pour navigateur et le hook React de l’[Embedded Checkout](/online/integration/embedded_checkout). Le chargeur récupère Tapaya.js **0.2.0** depuis `https://js.tapaya.com/checkout/0.2.0/checkout.js` ; la version du script navigateur est indépendante de la version de ce paquet. Il ne charge pas les fichiers `.env`. Conservez la clé et le client dans du code exécuté uniquement côté serveur. Le [guide du Hosted Checkout](/online/integration/hosted_checkout) explique comment créer une commande, rediriger le client et vérifier le paiement.

## Configuration [#configuration]

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

| Option                      | Valeur par défaut                                                                      | Description                                                                                                                                                                                                      |
| --------------------------- | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `apiKey` (premier argument) | `TAPAYA_SECRET_KEY`                                                                    | Une clé checkout de commerçant, ou la Secret key de l’organisation en mode plateforme.                                                                                                                           |
| `environment`               | `TAPAYA_ENVIRONMENT`, puis `production` pour une clé `tapaya_live_` et `sandbox` sinon | `sandbox` (`https://api.sandbox.tapaya.com`) ou `production` (`https://api.tapaya.com`). Une clé de production hors de la production, ou une clé de test en production, lève une erreur à la création du client. |
| `baseUrl`                   | `TAPAYA_BASE_URL`, puis l’URL sélectionnée par `environment`                           | Remplace l’URL de l’API pour les appels hébergés et intégrés.                                                                                                                                                    |
| `timeoutMs`                 | `30000`                                                                                | Délai d’attente de chaque tentative, en millisecondes.                                                                                                                                                           |
| `merchantToken`             | Aucune                                                                                 | Jeton du commerçant, envoyé sous la forme `X-Tapaya-Merchant-Token`. Obligatoire en mode plateforme.                                                                                                             |
| `maxRetries`                | `2`                                                                                    | Nouvelles tentatives après une erreur réseau, un dépassement de délai, une réponse HTTP 429, 502, 503 ou 504, ou une création encore en cours.                                                                   |
| `fetch`                     | `fetch` global                                                                         | Implémentation personnalisée de `fetch`, par exemple pour ajouter un proxy ou de l’instrumentation.                                                                                                              |

Pour utiliser un endpoint d’API personnalisé, définissez `TAPAYA_BASE_URL=https://api.example.com` sur votre serveur.
Un `baseUrl` explicite est prioritaire sur `TAPAYA_BASE_URL` ; tous deux remplacent la sélection de l’environnement.

Le client résout la clé API et l’URL de l’API une seule fois, lors de sa construction. Utilisez une clé qui correspond à
l’environnement sélectionné. Les URL d’API, de retour et du Hosted Checkout doivent utiliser HTTPS, à ceci près que HTTP est autorisé pour
`localhost`, `127.0.0.1` et `[::1]` en dehors de `NODE_ENV=production`. Le SDK vérifie la valeur actuelle de `NODE_ENV` chaque
fois qu’il valide une URL HTTP locale.

`timeoutMs` doit être un entier compris entre 1 et 2 147 483 647. `maxRetries` doit être un entier sûr non négatif. Le nombre de nouvelles tentatives par défaut autorise jusqu’à trois tentatives par appel, chacune avec son propre délai d’attente.

Chaque méthode accepte aussi `signal`, `timeoutMs` et `maxRetries` pour une requête unique :

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

Lorsque le signal est interrompu, la méthode s’arrête immédiatement, sans nouvelle tentative, et rejette avec la raison du signal.

## Sessions Checkout [#checkout-sessions]

### Sélectionner un commerçant [#select-a-merchant]

En mode commerçant, une clé checkout de commerçant sélectionne son commerçant. Utilisez `new Tapaya()` sans `merchantToken`.

En mode plateforme, une même Secret key d’organisation sert de nombreux commerçants. Chaque requête a besoin d’un jeton de commerçant ; il n’y a
pas de commerçant par défaut, et une requête sans jeton échoue avec `TapayaAuthenticationError`. Copiez les jetons depuis le
tableau des commerçants dans les [paramètres du Checkout](/online/integration/checkout_settings) et transmettez le jeton de la commande à la
création comme à la récupération :

```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,
})
```

Vous pouvez également définir une valeur par défaut avec `new Tapaya(key, { merchantToken })`. Le jeton s’applique aux appels hébergés et
intégrés. Tapaya refuse les jetons extérieurs à l’organisation de la clé. Avec une clé de commerçant, un jeton est facultatif et doit
désigner le commerçant propre à la clé. Voir [Authentification du Checkout](/online/integration/api_integration#authentication).

### Créer une session [#create-a-session]

`tapaya.checkout.sessions.create(params, options?)` exige `merchantOrderId`, `amount` et `currency`.
`merchantOrderId` est votre référence de commande, de 1 à 200 caractères. Une commande ne peut être payée qu’une seule fois ; une nouvelle session pour
une commande impayée remplace la précédente. Voir [Un paiement par commande](/online/integration/api_integration#one-payment-per-order). `amount` est le total final,
taxes et livraison comprises, un entier compris entre 1 et 2 147 483 647 unités mineures. `currency` est un code ISO 4217
à trois lettres. Tapaya le stocke et le renvoie en majuscules.

Champs facultatifs :

| Champ                     | Description                                                                                                                                                                                               |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `locale`                  | Langue de la page hébergée, par exemple `en`. `en` par défaut.                                                                                                                                            |
| `successUrl`, `cancelUrl` | URL de retour. Par défaut, les URL définies dans vos paramètres du Checkout.                                                                                                                              |
| `tax`, `shipping`         | Taxes et livraison incluses dans `amount`, en unités mineures.                                                                                                                                            |
| `taxRate`                 | Taux de taxe unique en points de pourcentage, par exemple `21`.                                                                                                                                           |
| `taxBreakdown`            | Taxe par taux, `[{ taxRate, tax }]`, pour les commandes à taux mixtes. À utiliser à la place de `taxRate` : les types refusent les deux ensemble.                                                         |
| `items`                   | Produits affichés sur la page hébergée : `reference`, `name`, `description`, `imageUrl`, `quantity` et `unitAmount`. Les articles servent uniquement à l’affichage et ne modifient pas le montant débité. |
| `customer`                | `email`, `billingAddress` et `shippingAddress`, facultatifs. N’envoyez que les informations que vous collectez.                                                                                           |

Avant l’envoi, le SDK vérifie les types, les champs obligatoires, les montants entiers, le format de la devise et une longueur maximale
d’e-mail de 254 caractères. Les URL de retour doivent être des URL HTTPS absolues, avec l’exception HTTP locale décrite sous
[Configuration](#configuration). Tapaya valide les règles métier comme le format de l’e-mail, les limites d’adresse et les codes
pays, et signale les problèmes par `TapayaInvalidRequestError`. Voir
[Sessions Checkout](/online/integration/api_integration#checkout-sessions) pour les règles des champs,
les totaux de taxe et les limites des adresses client.

### Récupérer une session [#get-a-session]

`tapaya.checkout.sessions.get(id, options?)` renvoie l’état actuel d’une session. L’ID doit être une chaîne non vide de 200 caractères au maximum ; `.` et `..` ne sont pas valides. Le SDK encode l’ID pour l’URL.

La création et la récupération hébergées renvoient une `HostedCheckoutSession`. Pour les méthodes intégrées `prepare()`, `verify()` et `configuration()`, voir [Embedded Checkout](/online/integration/embedded_checkout).

Champs d’une session hébergée :

| Champ                                        | Description                                                                                                                                    |
| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                                         | ID de session, par exemple `cs_Y7u2d`.                                                                                                         |
| `url`                                        | Page de paiement hébergée. Redirigez-y le client sans la modifier.                                                                             |
| `merchantOrderId`, `amount`, `currency`      | Informations de commande à comparer avec votre commande enregistrée.                                                                           |
| `status`                                     | `open`, `completed` ou `expired`. Les sessions acceptent de nouveaux paiements pendant 30 minutes. De nouvelles valeurs peuvent être ajoutées. |
| `paymentStatus`                              | `unpaid`, `successful`, `failed`, `cancelled` ou `action_needed`. De nouvelles valeurs peuvent être ajoutées.                                  |
| `paymentReference`                           | Jeton de la dernière tentative de paiement, ou `null` avant la première tentative.                                                             |
| `tax`, `shipping`, `taxRate`, `taxBreakdown` | Totaux envoyés lors de la création de la session. Par défaut `0`, `0`, `null` et `[]`.                                                         |
| `items`                                      | Articles envoyés lors de la création de la session, ou un tableau vide.                                                                        |
| `createdAt`, `expiresAt`, `completedAt`      | Horodatages ISO 8601. `completedAt` vaut `null` tant que le paiement n’a pas réussi.                                                           |

Gérez les valeurs inconnues de `status` et `paymentStatus`, par exemple en les traitant comme non encore payées. Seul
`paymentStatus: 'successful'` prouve le paiement.

Une carte refusée est un résultat de paiement, et non une erreur. La session reste `open` avec `paymentStatus: 'failed'`, et
le client peut réessayer. Pendant que Tapaya confirme un résultat incertain, la session reste `open` et `unpaid`.
Il n’existe pas encore de webhooks ; interrogez `get()` depuis une tâche de rapprochement.

## Idempotence et nouvelles tentatives [#idempotency-and-retries]

Chaque requête de création envoie une `Idempotency-Key`. Une clé explicite doit être une chaîne non vide de caractères ASCII imprimables. Tapaya accepte 250 caractères au maximum. Si vous omettez `idempotencyKey`, le SDK génère une clé aléatoire pour
chaque appel. Au sein de cet appel, les nouvelles tentatives réutilisent la clé : une nouvelle tentative ne crée donc jamais de deuxième session.

Pour garantir la sécurité d’un appel distinct à l’autre et après un redémarrage du processus, enregistrez une clé avec la commande et transmettez-la chaque fois que vous
créez une session pour cette tentative, avec les mêmes paramètres. Tapaya renvoie la session d’origine au lieu
d’en créer une nouvelle. N’utilisez une nouvelle clé que pour une nouvelle tentative de checkout, jamais pour relancer une requête au résultat incertain.

Une création hébergée répétée renvoie la même session avec ses `status` et `paymentStatus` actuels.
Appelez `tapaya.checkout.sessions.get(session.id)` pour vérifier à nouveau le statut avant de traiter la commande.

Pour un même commerçant, les nouvelles tentatives hébergées doivent utiliser le même corps de requête et le même mode d’identification : clé checkout de commerçant
ou Secret key de l’organisation. Modifier l’un ou l’autre renvoie HTTP 409 avec le code `API-0025`. Changer de mode d’identification
provoque un conflit même lorsque le corps est identique, car chaque mode utilise ses propres paramètres de redirection.

Le SDK relance les deux méthodes après des erreurs réseau, des dépassements de délai et des réponses HTTP 429, 502, 503 et 504. Il relance aussi une
création qui échoue avec HTTP 409 `API-0024`. Les nouvelles tentatives envoient la même clé et le même corps, elles renvoient donc la session d’origine. Le SDK
attend entre les tentatives avec un backoff exponentiel et du jitter, et respecte `Retry-After` jusqu’à 10 secondes. Lorsque Tapaya
demande une attente plus longue, le SDK cesse les nouvelles tentatives et lève l’erreur correspondant à ce statut HTTP : `TapayaRateLimitError`
pour 429, `TapayaServerError` pour 502, 503 ou 504, ou `TapayaConflictError` pour 409. Seule `TapayaRateLimitError`
expose le délai demandé dans `retryAfterMs` ; les autres erreurs HTTP conservent l’en-tête `Retry-After` dans `headers`.
Toutes les nouvelles tentatives partagent le budget `maxRetries`. Définissez `maxRetries: 0` pour désactiver les nouvelles tentatives.

Ne passez jamais à une nouvelle clé pour contourner un résultat incertain. La requête d’origine a peut-être déjà créé une
session ; avec une nouvelle clé et la même commande impayée, la nouvelle session la remplace.

## Erreurs [#errors]

Les classes d’erreur du SDK étendent `TapayaError`. Une requête interrompue est rejetée avec la raison du signal.

| Erreur                      | Quand                                                                                                                                                                                                                         |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `TapayaError`               | Clé API manquante ou configuration du client invalide ; classe de base des erreurs du SDK.                                                                                                                                    |
| `TapayaValidationError`     | Les paramètres n’ont pas passé la validation avant l’envoi d’une requête.                                                                                                                                                     |
| `TapayaAuthenticationError` | HTTP 401 : la clé est manquante ou invalide, le jeton du commerçant est manquant en mode plateforme, ou le jeton ne correspond à aucun commerçant actif.                                                                      |
| `TapayaInvalidRequestError` | HTTP 400 ou 422 : Tapaya a refusé les paramètres.                                                                                                                                                                             |
| `TapayaPermissionError`     | HTTP 403.                                                                                                                                                                                                                     |
| `TapayaNotFoundError`       | HTTP 404 : la session n’existe pas pour ce commerçant.                                                                                                                                                                        |
| `TapayaConflictError`       | HTTP 409. `code` vaut `API-0025` lorsque l’idempotency key a déjà été utilisée avec des paramètres différents. La création d’une session pour une commande déjà payée ou dont un paiement est en cours renvoie également 409. |
| `TapayaRateLimitError`      | HTTP 429 après les nouvelles tentatives, ou immédiatement lorsque `Retry-After` dépasse 10 secondes. `retryAfterMs` contient le délai demandé, lorsque Tapaya en envoie un.                                                   |
| `TapayaServerError`         | HTTP 5xx. Seuls 502, 503 et 504 font l’objet de nouvelles tentatives, sauf si celles-ci sont désactivées ou si `Retry-After` dépasse 10 secondes. Les autres statuts 5xx échouent immédiatement.                              |
| `TapayaApiError`            | Classe de base des erreurs HTTP ci-dessus et de tout autre statut d’erreur HTTP.                                                                                                                                              |
| `TapayaConnectionError`     | La requête a échoué ou la réponse a été perdue après les nouvelles tentatives. L’erreur d’origine se trouve dans `cause`.                                                                                                     |
| `TapayaTimeoutError`        | Une `TapayaConnectionError` pour une tentative qui a dépassé `timeoutMs`.                                                                                                                                                     |
| `TapayaResponseError`       | Tapaya a renvoyé une réponse que le SDK n’a pas pu lire.                                                                                                                                                                      |

Les erreurs HTTP portent `status`, le `code` d’erreur Tapaya, `fieldErrors` (`{ field, message, code? }[]`), les
`headers` de la réponse et `requestId` issu de l’en-tête `X-Request-Id`, lorsqu’il est présent. Le backend ne définit pas
actuellement cet en-tête. Indiquez l’ID de session ou la référence de commande et l’heure de la requête dans vos demandes de support, ainsi que
`requestId` s’il est disponible. `TapayaResponseError` porte aussi `status`, `headers` et `requestId`.
`TapayaValidationError` porte aussi `fieldErrors`, avec `field` défini sur le chemin du paramètre, par exemple `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
}
```

## Types exportés [#exported-types]

Le paquet exporte `TapayaEnvironment`, `TapayaOptions`, `RequestOptions`, `CreateSessionOptions`, `CreateCheckoutSessionParams`, `CheckoutSessions`, `CheckoutSession`, `CheckoutSessionStatus`, `CheckoutPaymentStatus`, `CheckoutItem`, `TaxBreakdownEntry`, `CheckoutCustomer`, `CheckoutContactAddress` et `TapayaFieldError`.

`VERSION` contient la version du SDK. Les types s’importent par des imports nommés avec `import type` :

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

## Migrer depuis la version 0.2.x [#upgrade-from-02x]

* Le chargeur pour navigateur charge Tapaya.js 0.2.0, qui prend en charge Apple Pay et Google Pay. Il refuse un script 0.1.x déjà chargé. Mettez à jour toute balise script que vous gérez vers `https://js.tapaya.com/checkout/0.2.0/checkout.js`.
* `environment: 'production'` prend en charge les paiements hébergés comme intégrés. `configuration()` renvoie `environment: 'production'` avec les clés de passerelle de production.
* Sans environnement explicite ni `TAPAYA_ENVIRONMENT`, une clé `tapaya_live_` sélectionne la production. Les identifiants qui ne correspondent pas à l’environnement sélectionné échouent lors de la construction du client. `baseUrl` remplace toujours l’URL de l’API.
