Buchungen mit Zahlung an einen externen Partner erstellen

Availability
Beta
Last verified
Last verified 6. Nov. 2026

Verwenden Sie diesen Server-zu-Server-Ablauf, wenn ein externes Buchungssystem die Zahlung vom Gast entgegennimmt und später mit der Veranstaltungsstätte abrechnet. KORONA Event erstellt die Buchung und einen fiskalischen Lieferschein für den konfigurierten Wiederverkäufer. Die Veranstaltungsstätte setzt ihren vereinbarten Abrechnungsprozess in KORONA.studio fort.

Bevor Sie beginnen

Beantragen Sie die API-Basis-URL, die Mandantendomäne, den API-Schlüssel des Dienstkontos, die ID des Verkaufspunkts (POS) und die bestehende ID des Vorgangskanals beim Integrationsadministrator des Veranstaltungsortes. Verwenden Sie, sofern verfügbar, einen bestehenden Testmandanten. Bewahren Sie API-Schlüssel auf Ihrem Server auf und halten Sie sie aus Browser-Bundles, Protokollen und Beispielen fern.

Der Administrator muss die Lieferscheine aktivieren und die Integrationszeile des Vorgangskanals für Ihr Dienstkonto konfigurieren, einschließlich des Wiederverkäufer-Ansprechpartners/Kunden und dessen Zuordnung zum KORONA.studio-Kunden. Der unten angegebene Gastkontakt ist von diesem Rechnungskunden getrennt. Die Zuordnung wird bei der Erstellung des Vorgangs gespeichert; spätere Konfigurationsänderungen führen nicht dazu, dass bestehende Vorgänge einem anderen Wiederverkäufer zugeordnet werden.

Die aktuelle Rolle des Dienstkontos benötigt Berechtigungen zum Erstellen, Lesen und Aktualisieren von Vorgängen sowie Leseberechtigungen für die Felder „Angebot“, „Preis“, „Position“ und „Kontakt“, die im Beispiel verwendet werden. Für Stornierungen wird ebenfalls die Berechtigung zum Aktualisieren von Vorgängen benötigt. Hierbei handelt es sich um gewöhnliche Rollenberechtigungen, nicht um einen auf eigene Integrationsvorgänge beschränkten Zugriff. Siehe Dienstkonto erstellen.

Senden Sie jeden Vorgang als separaten HTTPS-POST-Aufruf an /api/graphql/booking/v1:

http
Content-Type: application/json
Authorization: Bearer <service-account API key>
X-Tenant-Domain: <tenant domain>
Accept-Language: de

Verwenden Sie einen JSON-Body, der query und variables enthält. Geben Sie bei jedem Aufruf den API-Schlüssel an, auch bei Aufrufen, bei denen das zurückgegebene Warenkorb-Token verwendet wird. Ein Warenkorb-Token allein gewährt keine Zahlungsberechtigung für Partner. Anmeldedaten für die Management-API werden von diesem Endpunkt nicht akzeptiert.

Verwenden Sie denselben konfigurierten Wert für posId für die Ermittlung, die Preisangabe und die Erstellung. Ein explizit festgelegter POS hat Vorrang vor automatischen Standardwerten. Bei der automatischen Erstellung hat die POS-Überschreibung durch den Kanal bzw. den Benutzer Vorrang vor dem Standard-POS des Benutzers, gefolgt vom Standardwert des Kanals. Der explizit festgelegte POS in diesem Beispiel verhindert, dass beim Abrufen der Preise und beim Erstellen des Vorgangs unterschiedliche Kontexte zum Tragen kommen. Die Vorgangskanäle und der POS sind Konfigurationsparameter und keine Berechtigungszuweisungen.

Angebote und Besuchszeiten abrufen

graphql
query PartnerOffers($posId: ID!, $after: String) {
  offers(posId: $posId, offerableTypes: [EVENT_TEMPLATE], first: 50, after: $after) {
    edges {
      node {
        ... on EventTemplate {
          id
          nameTranslated
          timeZone
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

Geben Sie für die ausgewählte Eventvorlage einen begrenzten Datumsbereich und die gewünschte Anzahl an:

graphql
query PartnerSlots($id: ID!, $posId: ID!, $span: TsRange!, $quantity: Int!, $after: String) {
  offer(type: EVENT_TEMPLATE, id: $id, posId: $posId) {
    ... on EventTemplate {
      potentialEvents(posId: $posId, span: $span, spanOperator: CONTAINS_START, quantity: $quantity, first: 50, after: $after) {
        edges {
          node {
            span
            remainingQuota
            priceRules(posId: $posId) {
              id
              minPax
              maxPax
              priceCategory {
                id
                nameTranslated
              }
              product {
                currentPriceValue
              }
            }
          }
        }
        pageInfo {
          hasNextPage
          endCursor
        }
      }
    }
  }
}

Übergeben Sie einen halboffenen Bereich, zum Beispiel [2026-12-01T00:00:00+01:00,2026-12-02T00:00:00+01:00). Verwenden Sie bei der Erstellung des jeweiligen Elements den Wert von span jedes zurückgegebenen Slots unverändert. Zeigen Sie Zeiten in der IANA-Zeitzone timeZone des Angebots an; fügen Sie keinen festen Zeitzonen-Offset selbst hinzu. Setzen Sie die Paginierung mit endCursor fort, solange hasNextPage wahr ist.

Lesen Sie die Preise aus den Preisregeln des ausgewählten Eintrags aus. „Money“ ist ein JSON-Skalar wie beispielsweise {"amount": 2500, "currency": "EUR"}: Der Betrag wird in der kleinsten Währungseinheit angegeben (hier 25,00 €). Preise und Kapazitäten können sich ändern; die Abfrage reserviert keine Plätze und legt den Endpreis nicht fest. Kampagnenpreise oder spezielle Kontingente müssen separat konfiguriert und vereinbart werden und lassen sich nicht aus diesem API-Ablauf ableiten. Siehe Daten und Uhrzeiten.

Vorgang erstellen

graphql
mutation PartnerCreate($input: RequestCreateInput!) {
  requestCreate(input: $input) {
    request {
      id
      accessToken
      number
      externalRef
      paymentMethod
      state
      totalGrossValue
      requestItems {
        id
        offerableId
        offerableType
        offerableSpan
        pricings {
          id
          quantity
          priceValue
        }
      }
    }
    errors {
      key
      message
      messageTranslated
    }
  }
}
json
{
  "input": {
    "posId": "<configured POS ID>",
    "requestChannel": { "id": "<configured order-channel ID>" },
    "paymentMethod": "DELIVERY_NOTE",
    "externalRef": "PARTNER-ORDER-123",
    "contact": {
      "firstName": "Alex",
      "lastName": "Example",
      "email": "[email protected]",
      "customer": {}
    },
    "requestItems": [
      {
        "offerableType": "EVENT_TEMPLATE",
        "offerableId": "<selected template ID>",
        "offerableSpan": "<returned slot span>",
        "pricings": [{ "priceOriginType": "PRICE_RULE", "priceOriginId": "<returned price-rule ID>", "quantity": 1 }]
      }
    ]
  }
}

Setzen Sie externalRef auf die Vorgangsnummer des externen Systems. Damit können Mitarbeitende die Vorgänge beider Systeme zuordnen. Der Wert wird als Kommentar im fiskalischen Lieferschein übergeben. Er ist von der KORONA Event-Vorgangsnummer (number), externalId und einem Idempotenzschlüssel zu unterscheiden. Diese Referenz ist nicht eindeutig und verhindert keine doppelte Erstellung.

Bewahren Sie die zurückgegebenen Elemente id, number und accessToken sicher auf. Überprüfen Sie die zurückgegebenen Preise und den Gesamtbetrag vor der Bestätigung. Beim Erstellen eines zeitgesteuerten Vorlagenelements kann ein EVENT-Element mit einer neuen Ereignis-ID zurückgegeben werden; verwenden Sie die zurückgegebene Element-ID für nachfolgende Änderungen.

Bitte geben Sie die erforderlichen Teilnehmer- und Personalisierungsdaten ein und füllen Sie alle erforderlichen Formulare aus, bevor Sie die Buchung bestätigen. Dieses Minimalbeispiel geht von einem Angebot ohne zusätzliche Pflichtfragen aus. Informationen zum unterstützten Erfassungsablauf finden Sie unter Buchungs- und Teilnehmerdaten erfassen.

Ohne erneute Zahlung durch den Gast bestätigen

graphql
mutation PartnerConfirm($input: RequestFinalizeInput!) {
  requestFinalize(input: $input) {
    request {
      id
      number
      state
      externalRef
      paymentMethod
      paymentState
      shareablePublicTicketsUrl(format: PDF)
    }
    invoice {
      number
    }
    errors {
      key
      message
      messageTranslated
    }
  }
}
json
{ "input": { "id": "<returned cart accessToken>", "paymentMethod": "DELIVERY_NOTE" } }

Eine erfolgreiche Bestätigung des Lieferscheins gibt state: BOOKED zurück, und es wird keine neue Rechnung für die Zahlung durch den Gast erstellt. Es wird der fiskalische Lieferschein für die Wiederverkäufer-Zuordnung erstellt. Rufen Sie nicht paymentIntentCreate auf, eröffnen Sie keine gehostete Zahlung und verwenden Sie nicht den Zahlungsanbieter BOOKING_KIT, um Gelder darzustellen, die Ihr System eingezogen hat.

paymentState kann weiterhin REQUIRES_PAYMENT bleiben: Die Zahlung des Gastes an den Partner bedeutet nicht, dass die Veranstaltungsstätte die Abrechnung des Partners erhalten hat. Bitte stützen Sie sich nicht allein auf diesen Status, um zu entscheiden, ob diese Buchung mit Lieferschein bestätigt ist oder ob die Tickets ausgehändigt werden dürfen.

Verwenden Sie die zurückgegebene Ticket-URL unverändert, sofern vorhanden; behandeln Sie diese als Zugangsdaten. Falls diese fehlt, rufen Sie den Vorgang nach der Ticketausstellung erneut ab. Erstellen Sie keinen weiteren Vorgang, um einen Ticket-Link zu erhalten. Die Ticketausgabe hängt von der Ticketkonfiguration des Veranstaltungsortes ab, und ein Link allein stellt keine Bestätigung der Auszahlung durch den Partner dar.

Die Ticketaktivierung und die PDF-Erstellung können asynchron abgeschlossen werden. Wenn der Download HTTP 503 mit Retry-After zurückgibt, warten Sie das angegebene Intervall ab und rufen Sie dieselbe URL erneut auf.

Ergebnis nach einer unklaren Antwort prüfen

graphql
query PartnerStatus($id: IdOrNumberOrToken!) {
  request(id: $id) {
    id
    number
    state
    externalRef
    paymentMethod
    paymentState
    totalGrossValue
    shareablePublicTicketsUrl(format: PDF)
  }
}

Verwenden Sie das gespeicherte Warenkorb-Token als id zusammen mit dem API-Key-Header. Lesen Sie nach einem Timeout beim Bestätigen dieses Ergebnis aus, bevor Sie weitere Schreibvorgänge versuchen. Falls bereits BOOKED vorliegt, verwenden Sie diese Buchung. Sollte die Erstellung mit einem Timeout enden, bevor Sie eine Kennung erhalten haben, stimmen Sie sich anhand der Vorgangsnummer Ihres Systems mit dem Veranstaltungsort ab, bevor Sie den Vorgang erneut starten. Dieser API-Vertrag garantiert keine automatischen idempotenten Wiederholungsversuche oder eine Abfrage anhand von externalRef.

Überprüfen Sie HTTP-Fehler, die oberste Ebene von GraphQL errors und die Mutation-Payload errors. Ein HTTP-Status 200 allein bedeutet noch keinen Erfolg. Bei nicht verfügbarer Kapazität oder geänderten Preisen aktualisieren Sie die Auswahl und holen Sie die Zustimmung des Kunden zu etwaigen Änderungen ein. Bei einem Autorisierungsfehler überprüfen Sie die konfigurierten Zugriffsrechte mit dem Administrator; wechseln Sie nicht in den anonymen Zugriff. Sind Lieferscheine nicht verfügbar, beheben Sie die Probleme bei der Standortkonfiguration, anstatt auf eine andere Zahlungsart auszuweichen.

Eine Buchung stornieren

graphql
mutation PartnerCancel($input: RequestCancelInput!) {
  requestCancel(input: $input) {
    request {
      id
      state
      externalRef
    }
    errors {
      key
      message
      messageTranslated
    }
  }
}
json
{ "input": { "id": "<returned cart accessToken>", "autoRefund": false } }

Bei einem Vorgang, der ausschließlich über fiskalische Lieferscheine abgewickelt wurde, wird bei einer Stornierung ein Korrekturlieferschein erstellt. Ihr System ist weiterhin für die Erstattung an den Gast verantwortlich. Stimmen Sie die Stornierungs- und Änderungsregeln mit dem Veranstaltungsort ab; führen Sie keine Umbuchung durch, indem Sie nach Ablauf einer Zeitüberschreitung blindlings einen zweiten Vorgang erstellen.

Verwandte Artikel

Bereit loszulegen?

Buchen Sie eine kostenlose Demo oder kontaktieren Sie uns — wir freuen uns auf Sie.