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



`@tapayadot/checkout` ist das serverseitige TypeScript-SDK für Tapaya Checkout. Diese Referenz beschreibt Version **0.3.0**.

| Detail               | Wert                                                                                    |
| -------------------- | --------------------------------------------------------------------------------------- |
| **Paket**            | `@tapayadot/checkout`                                                                   |
| **Version**          | 0.3.0                                                                                   |
| **Laufzeitumgebung** | Node.js 22.13.0 oder neuer, ES-Module, TypeScript-Deklarationen enthalten               |
| **Browser-Skript**   | Tapaya.js 0.2.0, geladen für [Embedded Checkout](/online/integration/embedded_checkout) |
| **Quellcode**        | [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();
```

Der Client liest `TAPAYA_SECRET_KEY` aus der Serverumgebung. Das Paket enthält außerdem den Browser-Loader und den React-Hook für [Embedded Checkout](/online/integration/embedded_checkout). Der Loader lädt Tapaya.js **0.2.0** von `https://js.tapaya.com/checkout/0.2.0/checkout.js`; die Version des Browser-Skripts ist unabhängig von der Version dieses Pakets. Der Client lädt keine `.env`-Dateien. Halten Sie Schlüssel und Client in reinem Servercode. Der [Leitfaden zu Hosted Checkout](/online/integration/hosted_checkout) behandelt das Erstellen einer Bestellung, die Weiterleitung des Kunden und die Verifizierung der Zahlung.

## Konfiguration [#configuration]

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

| Option                     | Standard                                                                                       | Beschreibung                                                                                                                                                                                                                      |
| -------------------------- | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `apiKey` (erstes Argument) | `TAPAYA_SECRET_KEY`                                                                            | Ein Checkout-Händlerschlüssel oder im Plattformmodus der Secret key der Organisation.                                                                                                                                             |
| `environment`              | `TAPAYA_ENVIRONMENT`, dann `production` für einen `tapaya_live_`-Schlüssel und sonst `sandbox` | `sandbox` (`https://api.sandbox.tapaya.com`) oder `production` (`https://api.tapaya.com`). Ein Live-Schlüssel außerhalb der Produktion oder ein Testschlüssel in der Produktion löst beim Erstellen des Clients einen Fehler aus. |
| `baseUrl`                  | `TAPAYA_BASE_URL`, dann die durch `environment` gewählte URL                                   | Überschreibt die API-URL für gehostete und eingebettete Aufrufe.                                                                                                                                                                  |
| `timeoutMs`                | `30000`                                                                                        | Timeout für jeden Versuch, in Millisekunden.                                                                                                                                                                                      |
| `merchantToken`            | Keiner                                                                                         | Händler-Token, gesendet als `X-Tapaya-Merchant-Token`. Im Plattformmodus erforderlich.                                                                                                                                            |
| `maxRetries`               | `2`                                                                                            | Wiederholungen nach einem Netzwerkfehler, einem Timeout, HTTP 429, 502, 503 oder 504 oder einem noch laufenden Erstellvorgang.                                                                                                    |
| `fetch`                    | Globales `fetch`                                                                               | Eigene `fetch`-Implementierung, zum Beispiel um einen Proxy oder Instrumentierung hinzuzufügen.                                                                                                                                   |

Um einen eigenen API-Endpoint zu verwenden, setzen Sie `TAPAYA_BASE_URL=https://api.example.com` auf Ihrem Server.
Ein explizites `baseUrl` hat Vorrang vor `TAPAYA_BASE_URL`; beide überschreiben die Auswahl der Umgebung.

Der Client ermittelt API-Schlüssel und API-URL einmalig bei seiner Erstellung. Verwenden Sie einen Schlüssel, der zur
gewählten Umgebung passt. API-, Rückkehr- und Hosted-Checkout-URLs müssen HTTPS verwenden; HTTP ist nur für
`localhost`, `127.0.0.1` und `[::1]` außerhalb von `NODE_ENV=production` erlaubt. Das SDK prüft den aktuellen `NODE_ENV` jedes
Mal, wenn es eine lokale HTTP-URL validiert.

`timeoutMs` muss eine Ganzzahl von 1 bis 2.147.483.647 sein. `maxRetries` muss eine nicht negative sichere Ganzzahl (Safe Integer) sein. Die Standardanzahl an Wiederholungen erlaubt bis zu drei Versuche pro Aufruf, jeder mit eigenem Timeout.

Jede Methode akzeptiert außerdem `signal`, `timeoutMs` und `maxRetries` für eine einzelne Anfrage:

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

Wenn das Signal abbricht, stoppt die Methode sofort ohne Wiederholung und wird mit dem Grund (reason) des Signals abgelehnt.

## Checkout-Sessions [#checkout-sessions]

### Händler auswählen [#select-a-merchant]

Im Händlermodus bestimmt ein Checkout-Händlerschlüssel seinen Händler. Verwenden Sie `new Tapaya()` ohne `merchantToken`.

Im Plattformmodus bedient ein einziger Secret key der Organisation viele Händler. Jede Anfrage benötigt ein Händler-Token; es
gibt keinen Standardhändler, und eine Anfrage ohne Token schlägt mit `TapayaAuthenticationError` fehl. Kopieren Sie die Tokens aus der
Händlertabelle in den [Checkout-Einstellungen](/online/integration/checkout_settings) und übergeben Sie das Token der Bestellung sowohl beim
Erstellen als auch beim Abrufen:

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

Sie können auch mit `new Tapaya(key, { merchantToken })` einen Standardwert festlegen. Das Token gilt für gehostete und eingebettete
Aufrufe. Tapaya lehnt Tokens außerhalb der Organisation des Schlüssels ab. Mit einem Händlerschlüssel ist ein Token optional und muss
den eigenen Händler des Schlüssels bezeichnen. Siehe [Checkout-Authentifizierung](/online/integration/api_integration#authentication).

### Session erstellen [#create-a-session]

`tapaya.checkout.sessions.create(params, options?)` erfordert `merchantOrderId`, `amount` und `currency`.
`merchantOrderId` ist Ihre Bestellreferenz mit 1 bis 200 Zeichen. Eine Bestellung kann nur einmal bezahlt werden; eine neue Session für
eine unbezahlte Bestellung ersetzt die vorherige. Siehe [Eine Zahlung pro Bestellung](/online/integration/api_integration#one-payment-per-order). `amount` ist der endgültige Gesamtbetrag
einschließlich Steuern und Versand, eine Ganzzahl zwischen 1 und 2.147.483.647 in der kleinsten Währungseinheit. `currency` ist ein dreistelliger Code nach ISO 4217.
Tapaya speichert ihn in Großbuchstaben und gibt ihn so zurück.

Optionale Felder:

| Feld                      | Beschreibung                                                                                                                                                                                         |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `locale`                  | Sprache der gehosteten Seite, etwa `en`. Standardwert ist `en`.                                                                                                                                      |
| `successUrl`, `cancelUrl` | Rückkehr-URLs. Standardmäßig die URLs aus Ihren Checkout-Einstellungen.                                                                                                                              |
| `tax`, `shipping`         | In `amount` enthaltene Steuern und Versandkosten, in der kleinsten Währungseinheit.                                                                                                                  |
| `taxRate`                 | Einheitlicher Steuersatz in Prozentpunkten, etwa `21`.                                                                                                                                               |
| `taxBreakdown`            | Steuer je Steuersatz, `[{ taxRate, tax }]`, für Bestellungen mit gemischten Steuersätzen. Verwenden Sie es anstelle von `taxRate`: Die Typen lehnen beide zusammen ab.                               |
| `items`                   | Auf der gehosteten Seite angezeigte Produkte: `reference`, `name`, `description`, `imageUrl`, `quantity` und `unitAmount`. Positionen dienen nur der Anzeige und ändern den belasteten Betrag nicht. |
| `customer`                | Optional `email`, `billingAddress` und `shippingAddress`. Senden Sie nur die Angaben, die Sie erheben.                                                                                               |

Vor dem Senden prüft das SDK Typen, Pflichtfelder, ganzzahlige Beträge, das Währungsformat und eine maximale E-Mail-Länge
von 254 Zeichen. Rückkehr-URLs müssen absolute HTTPS-URLs sein, mit der unter [Konfiguration](#configuration) beschriebenen
Ausnahme für lokales HTTP. Tapaya validiert Geschäftsregeln wie E-Mail-Format, Adressgrenzen und Ländercodes
und meldet Probleme als `TapayaInvalidRequestError`. Feldregeln, Steuersummen und Grenzen für Kundenadressen finden Sie unter
[Checkout-Sessions](/online/integration/api_integration#checkout-sessions).

### Session abrufen [#get-a-session]

`tapaya.checkout.sessions.get(id, options?)` gibt den aktuellen Zustand einer Session zurück. Die ID muss eine nicht leere Zeichenkette mit höchstens 200 Zeichen sein; `.` und `..` sind ungültig. Das SDK kodiert die ID für die URL.

Erstellen und Abrufen im gehosteten Modus geben eine `HostedCheckoutSession` zurück. Die eingebetteten Methoden `prepare()`, `verify()` und `configuration()` beschreibt [Embedded Checkout](/online/integration/embedded_checkout).

Felder einer gehosteten Session:

| Feld                                         | Beschreibung                                                                                                          |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `id`                                         | Session-ID, etwa `cs_Y7u2d`.                                                                                          |
| `url`                                        | Gehostete Zahlungsseite. Leiten Sie unverändert dorthin weiter.                                                       |
| `merchantOrderId`, `amount`, `currency`      | Bestelldaten zum Vergleich mit Ihrer gespeicherten Bestellung.                                                        |
| `status`                                     | `open`, `completed` oder `expired`. Sessions nehmen 30 Minuten lang neue Zahlungen an. Neue Werte können hinzukommen. |
| `paymentStatus`                              | `unpaid`, `successful`, `failed`, `cancelled` oder `action_needed`. Neue Werte können hinzukommen.                    |
| `paymentReference`                           | Token des letzten Zahlungsversuchs oder `null` vor dem ersten Versuch.                                                |
| `tax`, `shipping`, `taxRate`, `taxBreakdown` | Beim Erstellen der Session gesendete Summen. Standardwerte sind `0`, `0`, `null` und `[]`.                            |
| `items`                                      | Beim Erstellen der Session gesendete Positionen oder ein leeres Array.                                                |
| `createdAt`, `expiresAt`, `completedAt`      | Zeitstempel nach ISO 8601. `completedAt` ist `null`, bis die Zahlung erfolgreich ist.                                 |

Behandeln Sie unbekannte Werte von `status` und `paymentStatus`, zum Beispiel indem Sie sie als noch nicht bezahlt werten. Nur
`paymentStatus: 'successful'` beweist eine Zahlung.

Eine abgelehnte Karte ist ein Zahlungsergebnis, kein Fehler. Die Session bleibt `open` mit `paymentStatus: 'failed'`, und
der Kunde kann es erneut versuchen. Während Tapaya ein unsicheres Ergebnis bestätigt, bleibt die Session `open` und `unpaid`.
Webhooks gibt es noch nicht; fragen Sie `get()` aus einem Abgleichsjob per Polling ab.

## Idempotenz und Wiederholungsversuche [#idempotency-and-retries]

Jede Erstellungsanfrage sendet einen `Idempotency-Key`. Ein expliziter Schlüssel muss eine nicht leere Zeichenkette aus druckbaren ASCII-Zeichen sein. Tapaya akzeptiert höchstens 250 Zeichen. Wenn Sie `idempotencyKey` weglassen, erzeugt das SDK für
jeden Aufruf einen zufälligen Schlüssel. Innerhalb dieses Aufrufs verwenden Wiederholungen den Schlüssel erneut, sodass eine Wiederholung nie eine zweite Session erstellt.

Um auch über getrennte Aufrufe und Prozessneustarts hinweg sicher zu bleiben, speichern Sie einen Schlüssel mit der Bestellung und übergeben ihn jedes Mal, wenn Sie
für diesen Versuch eine Session erstellen, mit denselben Parametern. Tapaya gibt die ursprüngliche Session zurück, statt
eine neue zu erstellen. Verwenden Sie einen neuen Schlüssel nur für einen neuen Checkout-Versuch, niemals, um ein unsicheres Ergebnis zu wiederholen.

Ein wiederholtes Erstellen im gehosteten Modus gibt dieselbe Session mit ihrem aktuellen `status` und `paymentStatus` zurück.
Rufen Sie `tapaya.checkout.sessions.get(session.id)` auf, um den Status vor der Abwicklung der Bestellung erneut zu prüfen.

Für denselben Händler müssen gehostete Wiederholungen denselben Request-Body und denselben Zugangsdatenmodus verwenden: Checkout-Händlerschlüssel
oder Secret key der Organisation. Eine Änderung von einem der beiden gibt HTTP 409 mit dem Code `API-0025` zurück. Ein Wechsel des Zugangsdatenmodus
führt auch bei identischem Body zu einem Konflikt, weil jeder Modus eigene Weiterleitungseinstellungen verwendet.

Das SDK wiederholt beide Methoden nach Netzwerkfehlern, Timeouts sowie HTTP 429, 502, 503 und 504. Außerdem wiederholt es ein
Erstellen, das mit HTTP 409 `API-0024` fehlschlägt. Wiederholungen senden denselben Schlüssel und Body und geben daher die ursprüngliche Session zurück. Das SDK
wartet zwischen den Versuchen mit exponentiellem Backoff und Jitter und beachtet `Retry-After` bis zu 10 Sekunden. Wenn Tapaya
eine längere Wartezeit verlangt, hört das SDK mit den Wiederholungen auf und wirft den Fehler für diesen HTTP-Status: `TapayaRateLimitError`
für 429, `TapayaServerError` für 502, 503 oder 504 oder `TapayaConflictError` für 409. Nur `TapayaRateLimitError`
stellt die verlangte Verzögerung als `retryAfterMs` bereit; andere HTTP-Fehler behalten den Header `Retry-After` in `headers`.
Alle Wiederholungen teilen sich das Budget von `maxRetries`. Setzen Sie `maxRetries: 0`, um Wiederholungen abzuschalten.

Wechseln Sie niemals zu einem neuen Schlüssel, um ein unsicheres Ergebnis zu umgehen. Die ursprüngliche Anfrage hat möglicherweise bereits eine
Session erstellt; mit einem neuen Schlüssel und derselben unbezahlten Bestellung ersetzt die neue Session diese.

## Fehler [#errors]

Die Fehlerklassen des SDK erweitern `TapayaError`. Eine abgebrochene Anfrage wird mit dem Grund (reason) des Signals abgelehnt.

| Fehler                      | Wann                                                                                                                                                                                                                                           |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `TapayaError`               | Fehlender API-Schlüssel oder ungültige Client-Konfiguration; Basisklasse der SDK-Fehler.                                                                                                                                                       |
| `TapayaValidationError`     | Die Parameter haben die Validierung nicht bestanden, bevor eine Anfrage gesendet wurde.                                                                                                                                                        |
| `TapayaAuthenticationError` | HTTP 401: Der Schlüssel fehlt oder ist ungültig, im Plattformmodus fehlt das Händler-Token, oder das Token passt zu keinem aktiven Händler.                                                                                                    |
| `TapayaInvalidRequestError` | HTTP 400 oder 422: Tapaya hat die Parameter abgelehnt.                                                                                                                                                                                         |
| `TapayaPermissionError`     | HTTP 403.                                                                                                                                                                                                                                      |
| `TapayaNotFoundError`       | HTTP 404: Die Session existiert für diesen Händler nicht.                                                                                                                                                                                      |
| `TapayaConflictError`       | HTTP 409. `code` ist `API-0025`, wenn der idempotency key bereits mit anderen Parametern verwendet wurde. Das Erstellen einer Session für eine Bestellung, die bereits bezahlt ist oder für die eine Zahlung läuft, gibt ebenfalls 409 zurück. |
| `TapayaRateLimitError`      | HTTP 429 nach den Wiederholungen oder sofort, wenn `Retry-After` länger als 10 Sekunden ist. `retryAfterMs` enthält die verlangte Verzögerung, sofern Tapaya eine sendet.                                                                      |
| `TapayaServerError`         | HTTP 5xx. Nur 502, 503 und 504 werden wiederholt, sofern Wiederholungen nicht deaktiviert sind und `Retry-After` 10 Sekunden nicht überschreitet. Andere 5xx-Status schlagen sofort fehl.                                                      |
| `TapayaApiError`            | Basisklasse der obigen HTTP-Fehler und jedes anderen HTTP-Fehlerstatus.                                                                                                                                                                        |
| `TapayaConnectionError`     | Die Anfrage ist fehlgeschlagen oder die Antwort ging nach den Wiederholungen verloren. Der ursprüngliche Fehler steht in `cause`.                                                                                                              |
| `TapayaTimeoutError`        | Ein `TapayaConnectionError` für einen Versuch, der `timeoutMs` überschritten hat.                                                                                                                                                              |
| `TapayaResponseError`       | Tapaya hat eine Antwort zurückgegeben, die das SDK nicht lesen konnte.                                                                                                                                                                         |

HTTP-Fehler enthalten `status`, den Tapaya-Fehlercode `code`, `fieldErrors` (`{ field, message, code? }[]`), die
`headers` der Antwort und `requestId` aus dem Header `X-Request-Id`, sofern vorhanden. Das Backend setzt diesen Header
derzeit nicht. Geben Sie in Support-Anfragen die Session-ID oder Bestellreferenz und den Zeitpunkt der Anfrage an, zusammen mit
`requestId`, falls verfügbar. Auch `TapayaResponseError` enthält `status`, `headers` und `requestId`.
Auch `TapayaValidationError` enthält `fieldErrors`, wobei `field` auf den Parameterpfad gesetzt ist, etwa `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
}
```

## Exportierte Typen [#exported-types]

Das Paket exportiert `TapayaEnvironment`, `TapayaOptions`, `RequestOptions`, `CreateSessionOptions`, `CreateCheckoutSessionParams`, `CheckoutSessions`, `CheckoutSession`, `CheckoutSessionStatus`, `CheckoutPaymentStatus`, `CheckoutItem`, `TaxBreakdownEntry`, `CheckoutCustomer`, `CheckoutContactAddress` und `TapayaFieldError`.

`VERSION` enthält die SDK-Version. Typen werden als benannte Importe mit `import type` eingebunden:

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

## Upgrade von 0.2.x [#upgrade-from-02x]

* Der Browser-Loader lädt Tapaya.js 0.2.0, das Apple Pay und Google Pay unterstützt. Er weist ein bereits geladenes 0.1.x-Skript zurück. Aktualisieren Sie jedes von Ihnen verwaltete Script-Tag auf `https://js.tapaya.com/checkout/0.2.0/checkout.js`.
* `environment: 'production'` unterstützt sowohl gehostete als auch eingebettete Zahlungen. `configuration()` gibt `environment: 'production'` mit Live-Gateway-Schlüsseln zurück.
* Ohne explizite Umgebung oder `TAPAYA_ENVIRONMENT` wählt ein `tapaya_live_`-Schlüssel die Produktion. Zugangsdaten, die nicht zur gewählten Umgebung passen, schlagen beim Erstellen des Clients fehl. `baseUrl` überschreibt weiterhin die API-URL.
