# API-Integration (/de/online/integration/api_integration)





Ihr Backend erstellt für jede Bestellung eine Checkout-Session und ruft sie ab, um die Zahlung zu verifizieren.

Für Node.js bietet das [SDK `@tapayadot/checkout`](/online/integration/node_sdk) typisierte Methoden `create()` und `get()` für diese Endpoints. Es liest standardmäßig `TAPAYA_SECRET_KEY`. Die HTTP-Beispiele auf dieser Seite übergeben `TAPAYA_CHECKOUT_API_KEY` explizit.

## Authentifizierung [#authentication]

Jeder Checkout-Aufruf erfolgt von Server zu Server und sendet einen Schlüssel als Bearer-Token:

```http
Authorization: Bearer <key>
```

Wählen Sie den Modus, der dazu passt, wer das Backend betreibt. Bewahren Sie jeden der beiden Schlüssel auf Ihrem Server auf; siehe [Checkout-Sicherheit](/online/security/checkout_security).

<Cards>
  <VisualCard title="Händlermodus" visual="<Store />" href="#merchant-mode" description="Ein Shop. Ein Checkout-Händlerschlüssel bestimmt seinen Händler, ohne zusätzlichen Header." />

  <VisualCard title="Plattformmodus" visual="<Building2 />" href="#platform-mode" description="Viele Händler. Der Secret key der Organisation plus ein Händler-Token pro Anfrage." />
</Cards>

### Händlermodus [#merchant-mode]

Verwenden Sie diesen Modus, wenn das Backend einen einzigen Shop bedient. Erstellen Sie einen **Checkout-Händlerschlüssel** in den [Checkout-Einstellungen](/online/integration/checkout_settings#create-merchant-checkout-keys): Öffnen Sie den Händler und wählen Sie **Create merchant key**. Der Schlüssel beginnt in der Sandbox mit `tapaya_test_` bzw. in der Produktion mit `tapaya_live_` und verweist genau auf diesen Händler.

```http
Authorization: Bearer <merchant-checkout-key>
```

`X-Tapaya-Merchant-Token` ist in diesem Modus optional. Wenn Sie ihn senden, muss er denselben Händler bezeichnen.

Die Platform zeigt den Schlüssel einmal an und speichert nur einen Hash. Um ihn zu rotieren, erstellen Sie einen Ersatz, bevor Sie den alten Schlüssel widerrufen. Das Widerrufen eines Schlüssels wirkt sich nicht auf andere Händlerschlüssel, Schlüssel der Organisation oder bereits an Browser ausgegebene client secrets aus.

### Plattformmodus [#platform-mode]

Verwenden Sie diesen Modus, wenn ein Backend für viele Händler handelt, etwa ein Marktplatz oder eine Plattform für Essenslieferungen. Senden Sie bei **jeder** Anfrage den Secret key der Organisation von der [Seite API Keys](https://platform.tapaya.com/api-keys/) und das Token des Händlers:

```http
Authorization: Bearer <secret-key>
X-Tapaya-Merchant-Token: <merchant-token>
```

Es gibt keinen Standardhändler. Eine Anfrage ohne den Header gibt HTTP 401 zurück. Der Händler muss zur Organisation des Schlüssels gehören. Kopieren Sie Händler-Tokens aus der Händlertabelle in den [Checkout-Einstellungen](/online/integration/checkout_settings). Das Token identifiziert den Händler; es ist kein Geheimnis.

Der Secret key der Organisation ist dieselbe Zugangsberechtigung, die in der [Dokumentation der Platform API](/platform-api#authentication) Server Secret Token heißt. Checkout erfordert das Präfix `Bearer`. Andere Endpoints der Platform API nehmen das Token direkt entgegen. Händler-Onboarding und Verwaltung der Organisation verwenden die [Platform API](/platform-api).

Request-Bodys akzeptieren keine `merchantId`.

## Umgebungen [#environments]

| Umgebung   | API-Origin                       | Origin von Hosted Checkout            | Zugangsdaten                                                         |
| ---------- | -------------------------------- | ------------------------------------- | -------------------------------------------------------------------- |
| Sandbox    | `https://api.sandbox.tapaya.com` | `https://checkout.sandbox.tapaya.com` | Sandbox-Schlüssel, mit [Testkarten](/online/getting-started/testing) |
| Produktion | `https://api.tapaya.com`         | `https://checkout.tapaya.com`         | Live-Schlüssel, mit echten Zahlungsmethoden                          |

Setzen Sie `TAPAYA_CHECKOUT_API_URL` auf den API-Origin Ihrer Umgebung. Sowohl gehostete als auch eingebettete Zahlungen sind in der Produktion verfügbar. Jeder Händler muss das [Onboarding](/merchants/onboarding) abschließen, die Freigabe des Zahlungsabwicklers für Online-Zahlungen erhalten und ein konfiguriertes Payment-Gateway haben. Prüfen Sie die Bereitschaft der Händler in den [Checkout-Einstellungen](/online/integration/checkout_settings). Verwenden Sie die zurückgegebene URL der gehosteten Session unverändert.

## Checkout-Sessions [#checkout-sessions]

<div className="fd-steps [&_h3]:fd-step">
  ### Checkout-Session erstellen [#create-a-checkout-session]

  Erstellen Sie eine Session, wenn der Kunde in Ihrem Shop auf **Checkout** klickt, und leiten Sie ihn dann zur zurückgegebenen `url` weiter.
  Berechnen Sie zuerst den endgültigen Gesamtbetrag auf Ihrem Server und speichern Sie die Bestellung mit einem eindeutigen idempotency key (Idempotenzschlüssel).

  **Endpoint:** `POST /merchant/checkout-sessions`

  <CodeBlockTabs defaultValue="curl" groupId="http-client">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="curl">
        cURL
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="curl">
      ```bash
      curl -X 'POST' "$TAPAYA_CHECKOUT_API_URL/merchant/checkout-sessions" \
      -H 'Content-Type: application/json' \
      -H "Authorization: Bearer $TAPAYA_CHECKOUT_API_KEY" \
      -H "X-Tapaya-Merchant-Token: $TAPAYA_MERCHANT_TOKEN" \
      -H 'Idempotency-Key: order-1001-checkout-1' \
      -d '{
              "merchantOrderId": "order-1001",
              "amount": 12100,
              "currency": "EUR",
              "tax": 2100,
              "shipping": 605,
              "taxRate": 21,
              "successUrl": "https://shop.example/checkout/return",
              "cancelUrl": "https://shop.example/checkout/cancel"
          }'
      ```
    </CodeBlockTab>
  </CodeBlockTabs>

  **Header:**

  | Header                    | Erforderlich   | Beschreibung                                                                                             |
  | ------------------------- | -------------- | -------------------------------------------------------------------------------------------------------- |
  | `Authorization`           | ✓              | `Bearer <key>`: ein Checkout-Händlerschlüssel oder der Secret key der Organisation.                      |
  | `X-Tapaya-Merchant-Token` | Plattformmodus | Händler-Token, das zur Organisation des Schlüssels gehört. Optional bei einem Checkout-Händlerschlüssel. |
  | `Idempotency-Key`         | ✓              | Nicht leer, höchstens 250 Zeichen. Siehe [Idempotenz und Fehler](#idempotency-and-errors).               |

  **Parameter:**

  | Feld              | Typ       | Erforderlich | Beschreibung                                                                                                                       |
  | ----------------- | --------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
  | `merchantOrderId` | `string`  | ✓            | Ihre Bestellreferenz, 1 bis 200 Zeichen. Siehe [Eine Zahlung pro Bestellung](#one-payment-per-order).                              |
  | `amount`          | `integer` | ✓            | Endgültiger zu belastender Gesamtbetrag in der kleinsten Währungseinheit, einschließlich Steuern und Versand. 1 bis 2.147.483.647. |
  | `currency`        | `string`  | ✓            | Vom Backend unterstützter dreistelliger Code nach ISO 4217, in Großbuchstaben, etwa `EUR`.                                         |
  | `locale`          | `string`  |              | Standardwert ist `en`.                                                                                                             |
  | `successUrl`      | `string`  |              | Überschreibt die Standard-Erfolgs-URL für diese Session. Muss zu einer erlaubten Website der aufrufenden Zugangsdaten passen.      |
  | `cancelUrl`       | `string`  |              | Überschreibt die Standard-Abbruch-URL für diese Session. Muss zu einer erlaubten Website der aufrufenden Zugangsdaten passen.      |
  | `tax`             | `integer` |              | Bereits in `amount` enthaltene Mehrwertsteuer, zwischen null und `amount`. Standardwert ist `0`.                                   |
  | `shipping`        | `integer` |              | Bereits in `amount` enthaltene Versandkosten, zwischen null und `amount`. Standardwert ist `0`.                                    |
  | `taxRate`         | `number`  |              | Mehrwertsteuersatz für die gesamte Bestellung in Prozent, etwa `21` oder `5.5`. Nicht negativ.                                     |
  | `taxBreakdown`    | `array`   |              | Mehrwertsteuer nach Steuersatz gruppiert. Ein nicht leeres Array kann nicht zusammen mit `taxRate` verwendet werden.               |
  | `items`           | `array`   |              | Bestellpositionen nur zur Anzeige. Bestimmen nicht den zu belastenden Gesamtbetrag.                                                |
  | `customer`        | `object`  |              | E-Mail-Adresse, Rechnungsadresse und Lieferadresse des Kunden.                                                                     |

  Die Session belastet in der von Ihnen festgelegten `currency`. [Unterstützte Währungen](/merchants/supported_currencies) listet jede
  von Tapaya unterstützte Währung auf, ein Händler ist jedoch in der Regel nur für einige davon freigeschaltet. Das Erstellen einer Session in einer
  Währung, die der Händler oder das Backend nicht unterstützt, wird zurückgewiesen, sodass keine gehostete Seite erstellt wird.

  Die API belastet `amount` so, wie der Betrag übergeben wurde. Sie addiert weder Versand noch Steuern, berechnet keine Mehrwertsteuer aus einem Steuersatz und keinen
  Gesamtbetrag aus den Positionen.

  <Accordions>
    <Accordion title="Einträge in taxBreakdown">
      Jeder Eintrag enthält einen numerischen `taxRate` und eine ganzzahlige `tax`, beide nicht negativ. Die Steuersätze sind eindeutig, und die
      Steuerbeträge der Einträge ergeben in Summe die `tax` der obersten Ebene.

      ```json
      {
          "amount": 22650,
          "currency": "EUR",
          "tax": 2650,
          "shipping": 605,
          "taxBreakdown": [
              { "taxRate": 21, "tax": 2100 },
              { "taxRate": 5.5, "tax": 550 }
          ]
      }
      ```
    </Accordion>

    <Accordion title="Einträge in items">
      Jede Position erfordert `reference`, `name`, `description`, `imageUrl`, `quantity` und `unitAmount`. Die Textfelder
      sind nicht leer, `imageUrl` ist eine URL, `quantity` ist eine positive Ganzzahl und `unitAmount` ist eine
      nicht negative Ganzzahl in der kleinsten Währungseinheit.
    </Accordion>

    <Accordion title="Felder von customer">
      Das Objekt `customer` akzeptiert `email`, `billingAddress` und `shippingAddress`. Jedes Feld ist optional,
      ebenso jedes Adressfeld, sodass eine Rechnungsadresse auch nur Postleitzahl und Land enthalten kann.

      | Feld                     | Grenze oder Format                                         |
      | ------------------------ | ---------------------------------------------------------- |
      | `email`                  | E-Mail-Adresse, bis zu 254 Zeichen.                        |
      | `name`, `line1`, `line2` | Jeweils bis zu 200 Zeichen.                                |
      | `phone`                  | Bis zu 30 Zeichen.                                         |
      | `city`, `state`          | Jeweils bis zu 100 Zeichen.                                |
      | `postalCode`             | Bis zu 20 Zeichen.                                         |
      | `country`                | Zweistelliger ISO-Ländercode in Großbuchstaben, etwa `CZ`. |

      Übergebener Adresstext darf nicht leer sein. Unbekannte Felder können weggelassen werden. Das Backend speichert einen Snapshot der übergebenen
      Kundendaten als Risikoinformation für das Gateway. Kundendaten sind in den Antworten zur Session
      nicht enthalten.
    </Accordion>
  </Accordions>

  **Antworten:**

  | Code  | Beschreibung                                                                                                                                                                   |
  | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
  | `200` | Session erstellt, oder bei wiederholtem Schlüssel, Body und Zugangsdatenmodus dieselbe Session mit ihrem aktuellen Status zurückgegeben                                        |
  | `409` | Konflikt: Der Schlüssel wurde mit geändertem Body oder Zugangsdatenmodus erneut verwendet (`API-0025`), oder die Bestellung ist bereits bezahlt oder hat eine laufende Zahlung |

  **Body der Antwort:**

  ```json
  {
      "id": "cs_7Hq2x9LmR4",
      "merchantOrderId": "order-1001",
      "url": "https://checkout.sandbox.tapaya.com/c/cs_7Hq2x9LmR4",
      "status": "open",
      "paymentStatus": "unpaid",
      "amount": 12100,
      "currency": "EUR",
      "tax": 2100,
      "shipping": 605,
      "taxRate": 21,
      "taxBreakdown": [],
      "items": [],
      "expiresAt": "2026-07-15T12:30:00Z",
      "createdAt": "2026-07-15T12:00:00Z"
  }
  ```

  `taxRate` ist nur enthalten, wenn es übergeben wurde. Speichern Sie die `id` mit Ihrer Bestellung und leiten Sie den Browser dann mit
  HTTP 303 zur `url` weiter. Eine Session nimmt nach ihrer Erstellung 30 Minuten lang neue Zahlungen an; eine bereits abgesendete Zahlung wird auch danach
  noch abgeschlossen. Rückkehr-URLs werden beim Erstellen ausgewählt und validiert, entweder anhand der Werte der Anfrage oder
  anhand der Standardwerte der aufrufenden Zugangsdaten: die [Rückkehrziele](/online/integration/checkout_settings#configure-return-destinations) der Organisation
  für den Secret key der Organisation mit `X-Tapaya-Merchant-Token`, die des Händlers für einen Checkout-Händlerschlüssel. Die
  beiden werden nie kombiniert.

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

  Wenn der Kunde zu Ihrer Erfolgs- oder Abbruch-URL zurückkehrt, oder aus einem Abgleichsjob heraus, rufen Sie die Session ab und
  vergleichen Sie sie vor der Abwicklung mit der gespeicherten Bestellung.

  **Endpoint:** `GET /merchant/checkout-sessions/{id}`

  <CodeBlockTabs defaultValue="curl" groupId="http-client">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="curl">
        cURL
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="curl">
      ```bash
      curl "$TAPAYA_CHECKOUT_API_URL/merchant/checkout-sessions/cs_7Hq2x9LmR4" \
      -H "Authorization: Bearer $TAPAYA_CHECKOUT_API_KEY" \
      -H "X-Tapaya-Merchant-Token: $TAPAYA_MERCHANT_TOKEN"
      ```
    </CodeBlockTab>
  </CodeBlockTabs>

  Es gibt kein Suffix `/status`. Die Antwort enthält Identität, URL, Summen, Steuerfelder, Status und
  Zeitstempel der Session sowie die Felder `paymentReference` und `completedAt`, die null sein können. `paymentReference` identifiziert den letzten
  Bestätigungsversuch und ist null, solange es keinen Versuch gibt. Eine Referenz ungleich null beweist keinen Erfolg.
  Zeitstempel sind Zeichenketten nach ISO 8601.

  **Session-Status:**

  | `status`    | Bedeutung                                                                                                                                          |
  | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
  | `open`      | Die Session steht für eine Zahlung zur Verfügung, oder das Ergebnis einer abgesendeten Zahlung wird noch bestätigt.                                |
  | `completed` | Die Session ist abgeschlossen. Das Zahlungsergebnis steht in `paymentStatus`.                                                                      |
  | `expired`   | Die Session steht für keine neue Zahlung mehr zur Verfügung: Sie ist abgelaufen, oder eine neuere Session für dieselbe Bestellung hat sie ersetzt. |

  <a id="payment-status" />

  **Zahlungsstatus:**

  | `paymentStatus` | Bedeutung für die Bestellung                                                                                        |
  | --------------- | ------------------------------------------------------------------------------------------------------------------- |
  | `unpaid`        | Keine bestätigte erfolgreiche Zahlung. Das Ergebnis wird möglicherweise noch bestätigt.                             |
  | `successful`    | Die Zahlung war erfolgreich. Gleichen Sie Bestellreferenz, Betrag und Währung vor der Abwicklung ab.                |
  | `failed`        | Die Zahlung wurde abgelehnt. Der Kunde kann eine andere Karte oder Wallet versuchen, solange die Session offen ist. |
  | `cancelled`     | Die Zahlung wurde abgebrochen.                                                                                      |
  | `action_needed` | Eine weitere Aktion ist erforderlich. Wickeln Sie die Bestellung nicht als bezahlt ab.                              |

  Bei einer abgelehnten Karte bleibt `status` auf `open` und `paymentStatus` auf `failed`. Während Tapaya ein unsicheres
  Ergebnis im Hintergrund bestätigt, bleibt die Session `open` und `unpaid`; rufen Sie sie später erneut ab. Das Folgen des Abbruch-Links der gehosteten
  Seite ist eine Navigation zur `cancelUrl`; es beweist für sich allein keinen Zahlungsstatus `cancelled`.

  <Callout title="Auf dem Server verifizieren" type="warn">
    Wickeln Sie die Bestellung nur ab, wenn die abgerufene Session mit Referenz, Betrag und Währung Ihrer gespeicherten Bestellung übereinstimmt und
    `paymentStatus` gleich `successful` ist. Eine Browser-Weiterleitung allein beweist niemals eine Zahlung.
  </Callout>
</div>

## Zuständigkeit für Bestellung und Zahlung [#order-and-payment-ownership]

| Ihr Server verwaltet                                   | Tapaya verwaltet                                           |
| ------------------------------------------------------ | ---------------------------------------------------------- |
| Bestellreferenz, Preise, Währung und Abwicklungsstatus | Die Checkout-Session und das Zahlungsergebnis des Gateways |

Eine Checkout-Session-ID identifiziert einen Hosted Checkout. Ihre `merchantOrderId` verknüpft sie mit Ihrer Bestellung, während
`paymentReference` den letzten Bestätigungsversuch identifiziert. Speichern Sie die Session-ID mit der Bestellung, damit Sie
das Ergebnis auch dann abrufen können, wenn der Kunde den Browser schließt.

Die gehostete Seite verwendet separate öffentliche Endpoints, um die Session zu laden und zu bestätigen. Ihre Session-ID ist eine
Zugangsberechtigung für diese Endpoints. Eine Händlerintegration verifiziert die Zahlung über den authentifizierten Händler-Endpoint.

### Eine Zahlung pro Bestellung [#one-payment-per-order]

Hosted Checkout und [Embedded Checkout](/online/integration/embedded_checkout) teilen sich eine Payment-Engine. Ein Händler kann
höchstens eine erfolgreiche Zahlung pro `merchantOrderId` haben. Bestell-IDs gelten pro Händler, sodass verschiedene
Händler, auch innerhalb einer Organisation, dieselben IDs verwenden können.

* Das Erstellen einer Session für eine unbezahlte Bestellung ersetzt die vorherige unbezahlte Session. Die alte URL meldet `expired` und
  kann keine Zahlung mehr annehmen.
* Das Erstellen einer Session für eine Bestellung, die bereits bezahlt ist oder eine laufende Zahlung hat, gibt HTTP 409 zurück.
* Nach einer Ablehnung kann der Kunde in derselben Session eine andere Karte oder Wallet versuchen. Ein erneutes Absenden desselben Karten-Tokens
  führt nie zu einer doppelten Belastung.
* Tapaya legt die Richtlinie für 3-D Secure fest und versucht immer eine Authentifizierung.

## Idempotenz und Fehler [#idempotency-and-errors]

Das Erstellen erfordert einen nicht leeren `Idempotency-Key` mit höchstens 250 Zeichen. Für denselben Händler gilt:

| Sie senden                                                                                                                                                               | Tapaya gibt zurück                                                                              |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- |
| Denselben Schlüssel, Body und Zugangsdatenmodus                                                                                                                          | Dieselbe Session mit ihrem aktuellen `status` und `paymentStatus`                               |
| Denselben Schlüssel mit geändertem Body                                                                                                                                  | HTTP 409 mit dem Code `API-0025`                                                                |
| Denselben Schlüssel und Body mit dem anderen Zugangsdatenmodus                                                                                                           | HTTP 409 mit dem Code `API-0025`, weil jeder Modus eigene Weiterleitungseinstellungen verwendet |
| Ungültige Summen, eine nicht unterstützte Währung, ungültige Weiterleitungsziele, eine fehlende Gateway-Konfiguration oder einen nicht zu Checkout hinzugefügten Händler | Eine abgelehnte Erstellung                                                                      |

Eine Kartenablehnung ist ein Zahlungsergebnis, kein Beweis dafür, dass eine HTTP-Anfrage fehlgeschlagen ist.

<Callout title="Unbekanntes Ergebnis" type="warn">
  Nach einem Netzwerkfehler oder Timeout ist das Zahlungsergebnis unbekannt. Es gibt noch keine Checkout-Webhooks: Gleichen Sie ab, indem Sie
  die Session von Ihrem Server abrufen, und wiederholen Sie das Erstellen nur mit demselben Schlüssel und Body.
</Callout>
