Schnellstart für die Booking API
- Last verified
- Last verified 29. Sept. 2026
In diesem Tutorial verkaufen Sie zwei Tickets für ein Event mit festem Termin, etwa ein Konzert, und übergeben die Zahlung an die gehostete Zahlungsseite des Shops. Dafür brauchen Sie sieben Anfragen: Event finden, Preiskategorien lesen, Tickets in den Warenkorb legen, Kunden hinzufügen, erforderliche Rechtsdokumente lesen, Checkout abschließen und Zahlung prüfen. Andere Angebote zeigt, was sich bei Eintritten ohne Zeitfenster, Zeitfenstern und Gutscheinen ändert.
Bevor Sie beginnen
- Ein Shop in KORONA Event mit mindestens einem veröffentlichten Event, für das noch Plätze frei sind und das für Buchungen mit Online-Zahlung eingerichtet ist.
- Die Domain des Shops, zum Beispiel
tickets.example.com, und Ihr KORONA Event API-Host. - Ein Werkzeug, das HTTP-POST-Anfragen mit JSON-Body sendet, zum Beispiel
curloder der HTTP-Client Ihrer Anwendung.
Für Reservierungen, Buchungsanfragen oder Zahlungen vor Ort folgen Sie Checkout abschließen und Zahlung mit der Booking API abwickeln.
Senden Sie jede Anfrage als POST https://<api-host>/api/graphql/booking/v1 mit diesen Headern:
Content-Type: application/json
X-Tenant-Domain: tickets.example.com
Accept-Language: deDer Body ist ein JSON-Objekt mit query und variables. So funktioniert die Booking API erklärt die Datensätze und Tokens, die unten verwendet werden.
1. Event finden
Listen Sie die Events des Shops auf. posId: "auto" wählt den eigenen Verkaufskanal des Shops.
query DiscoverEvents {
offers(posId: "auto", offerableTypes: [EVENT], first: 20) {
edges {
node {
... on Event {
id
nameTranslated
span
timeZone
locationName
bookingAvailability
}
}
}
}
}{
"data": {
"offers": {
"edges": [
{
"node": {
"id": "4711",
"nameTranslated": "Jazzabend",
"span": "[2026-11-12T18:00:00Z,2026-11-12T21:00:00Z)",
"timeZone": "Europe/Berlin",
"locationName": "Großer Saal",
"bookingAvailability": "AVAILABLE"
}
}
]
}
}
}span enthält Beginn und Ende des Events in UTC; zeigen Sie beides in der timeZone des Events an, hier 19:00 bis 22:00 Uhr in Berlin. Bieten Sie nur Events an, deren bookingAvailability AVAILABLE ist; Events mit SOLD_OUT oder EXCLUSIVELY_BOOKED lassen sich nicht buchen.
2. Preiskategorien lesen
Ein Event wird in Preiskategorien verkauft, etwa Erwachsene und Ermäßigt. Lesen Sie die Preisregeln des Events: Jede ist eine Preiskategorie mit ihrem Preis.
query EventPrices($id: ID!) {
offer(id: $id, type: EVENT, posId: "auto") {
... on Event {
id
remainingQuota
priceRules(posId: "auto") {
id
priceCategory {
nameTranslated
}
product {
currentPriceValue
}
}
}
}
}{ "id": "4711" }{
"data": {
"offer": {
"id": "4711",
"remainingQuota": "120",
"priceRules": [
{
"id": "31",
"priceCategory": { "nameTranslated": "Erwachsene" },
"product": { "currentPriceValue": { "amount": 2500, "currency": "EUR" } }
},
{
"id": "32",
"priceCategory": { "nameTranslated": "Ermäßigt" },
"product": { "currentPriceValue": { "amount": 1500, "currency": "EUR" } }
}
]
}
}
}Geldbeträge enthalten amount in der kleinsten Einheit der Währung, 2500 sind also 25,00 EUR. remainingQuota ist die Zahl der freien Plätze und wird als Zeichenkette gesendet.
3. Tickets in den Warenkorb legen
Die erste Warenkorb-Mutation ohne requestId legt den Warenkorb an. Speichern Sie das zurückgegebene accessToken: Es ist das Warenkorb-Token für alle weiteren Anfragen. Fügen Sie je gewählter Preiskategorie eine Preisangabe mit der id der Preisregel und der Anzahl der Tickets hinzu.
mutation AddToCart($input: RequestItemCreateInput!) {
requestItemCreate(input: $input) {
request {
accessToken
totalGrossValue
checkoutHold {
expiresAt
secondsRemaining
}
}
requestItem {
id
}
errors {
key
message
messageTranslated
}
}
}{
"input": {
"offerableType": "EVENT",
"offerableId": "4711",
"pricings": [
{ "quantity": 1, "priceOriginType": "PRICE_RULE", "priceOriginId": "31" },
{ "quantity": 1, "priceOriginType": "PRICE_RULE", "priceOriginId": "32" }
]
}
}Die Antwort enthält das Warenkorb-Token, die Warenkorbsumme und den Checkout-Hold. Die Summe kann höher sein als die Ticketpreise, wenn der Veranstalter Gebühren erhebt. Um ein weiteres Event in denselben Warenkorb zu legen, senden Sie das Warenkorb-Token beim nächsten requestItemCreate als requestId.
4. Kunden hinzufügen
Senden Sie die Daten des Kunden mit dem Warenkorb-Token als id. Fügen Sie eine Rechnungsadresse hinzu und kennzeichnen Sie sie mit billing: true.
mutation AddCustomer($input: RequestUpdateInput!) {
requestUpdate(input: $input) {
request {
contact {
email
}
billingAddress {
city
}
checkoutPolicy {
compatible
targetState
}
requiresShipping
customFieldsCompletion {
allRequiredComplete
}
}
errors {
key
message
messageTranslated
}
}
}{
"input": {
"id": "<cart token>",
"contact": {
"firstName": "Alex",
"lastName": "Example",
"email": "[email protected]",
"customer": {
"addresses": [
{
"billing": true,
"street": "Example Street 1",
"postalCode": "12345",
"city": "Berlin",
"country": "DE"
}
]
}
}
}
}Prüfen Sie den zurückgegebenen Warenkorb vor dem Checkout:
| Feld | Vorgehen |
|---|---|
checkoutPolicy.targetState ist BOOKED | Fahren Sie mit diesem Tutorial fort. |
checkoutPolicy.compatible ist false | Der Warenkorb enthält Angebote, die nicht gemeinsam abgeschlossen werden können. Entfernen Sie die Positionen aus checkoutPolicy.conflicts. |
requiresShipping ist true | Fügen Sie eine Adresse mit shipping: true in einem Land aus shop.allowedShippingCountries hinzu. |
customFieldsCompletion.allRequiredComplete ist false | Erfassen Sie die Pflichtangaben vor dem Checkout; siehe den Hinweis unter der Tabelle. |
Wie Sie offene Pflichtfragen beantworten, beschreibt Buchungs- und Teilnehmerangaben mit der Booking API erfassen.
5. Erforderliche Rechtsdokumente lesen
Kunden müssen den erforderlichen Rechtsdokumenten des Shops zustimmen. Zeigen Sie für jedes Dokument ein Kontrollkästchen mit checkboxLabelTranslated an, oder mit nameTranslated, wenn keine Beschriftung hinterlegt ist, und verlinken Sie auf den Dokumenttext aus legalDocument(id:).
query RequiredDocuments {
legalDocuments(required: [true], first: 20) {
edges {
node {
id
nameTranslated
checkboxLabelTranslated
publishedAt
}
}
}
}Speichern Sie für den nächsten Schritt id und publishedAt jedes Dokuments. publishedAt bezeichnet die Version, der der Kunde zugestimmt hat. Hat der Shop mehr als 20 erforderliche Dokumente, blättern Sie wie in der Checkout-Anleitung beschrieben durch die Liste.
6. Checkout abschließen
Nachdem der Kunde den Dokumenten zugestimmt hat, schließen Sie den Checkout ab. Die Antwort enthält die Rechnung und den Link zur gehosteten Zahlungsseite.
mutation CompleteCheckout($input: RequestPaymentInitiateInput!) {
requestPaymentInitiate(input: $input) {
request {
state
}
invoice {
accessToken
paymentState
paymentLink
}
errors {
key
message
messageTranslated
}
}
}{
"input": {
"id": "<cart token>",
"legalDocumentAcceptances": [
{ "legalDocumentId": "1", "legalDocumentVersion": "2026-09-23T19:21:22+00:00" },
{ "legalDocumentId": "2", "legalDocumentVersion": "2026-09-23T19:21:22+00:00" }
]
}
}{
"data": {
"requestPaymentInitiate": {
"request": { "state": "BOOKED" },
"invoice": {
"accessToken": "<invoice token>",
"paymentState": "REQUIRES_PAYMENT",
"paymentLink": "https://tickets.example.com/de/payments/<token>"
},
"errors": null
}
}
}Leiten Sie den Browser des Kunden zu paymentLink weiter. Der Kunde wählt auf der gehosteten Zahlungsseite eine Zahlungsart und bezahlt; die Seite verwendet die Sprache Ihres Accept-Language-Headers.
7. Zahlung prüfen
Lesen Sie die Rechnung mit dem Rechnungs-Token, um die Zahlung zu verfolgen. paymentState wechselt zu PAID, wenn die Zahlung erfolgreich war.
query PaymentStatus($invoiceToken: IdOrNumberOrToken!) {
invoice(id: $invoiceToken) {
paymentState
paymentIntentCreateError
payments {
state
providerInitializationFailed
}
request {
state
checkoutHold {
secondsRemaining
}
ticketsUrl: shareablePublicTicketsUrl(format: PDF)
}
}
}Der Link zu den Tickets kann bereits vorhanden sein, während die Ticketaktivierung noch aussteht. Er kann die gehostete Ticketseite öffnen, auf der die Tickets nach Abschluss der Aktivierung verfügbar sind. Verwenden Sie das Vorhandensein des Links nicht als Signal dafür, dass ein PDF bereitsteht.
Andere Angebote
Mit denselben Schritten verkaufen Sie jede Art von Angebot. Nur die Suche nach dem Angebot und die Variablen für AddToCart ändern sich.
Eintritt ohne Zeitfenster. Ein Eintritt ohne Zeitfenster, etwa ein Tagesticket, funktioniert wie ein Event: Verwenden Sie offerableTypes: [ADMISSION], lesen Sie die Preisregeln mit ... on Admission und legen Sie die Tickets mit offerableType: "ADMISSION" in den Warenkorb. Schlägt das mit einem Fehler zu requestItems.0.offerableSpan fehl, hat der Eintritt Zeitfenster.
Zeitfenster. Eventvorlagen und Eintritte mit Zeitfenstern brauchen Datum und Uhrzeit. Termine und Zeitfenster mit der Booking API anzeigen zeigt den Kalender, die Zeitfenster eines Tages und wie Sie ein Zeitfenster in den Warenkorb legen.
Gutscheine. Suchen Sie die Gutscheine des Shops und legen Sie einen mit seiner id als Angebot und Preisherkunft in den Warenkorb:
query DiscoverVouchers {
offers(posId: "auto", offerableTypes: [VOUCHER_CONFIGURATION], first: 20) {
edges {
node {
... on VoucherConfiguration {
id
nameTranslated
currentPriceValue
}
}
}
}
}{
"input": {
"offerableType": "VOUCHER_CONFIGURATION",
"offerableId": "<voucher id>",
"pricings": [{ "quantity": 1, "priceOriginType": "VOUCHER_CONFIGURATION", "priceOriginId": "<voucher id>" }]
}
}Ergebnis prüfen
- Sie haben das Warenkorb-Token aus Schritt 3 gespeichert und in den Schritten 4 und 6 verwendet.
- Der Kunde hat vor Schritt 6 allen erforderlichen Rechtsdokumenten zugestimmt.
- Der Kunde ist über
paymentLinkauf der gehosteten Zahlungsseite gelandet.