Checkout über Booking v1 abschließen
- Last verified
- Last verified 24. Sept. 2026
Verwenden Sie /api/graphql/booking/v1, um einen bestehenden KORONA Event Warenkorb abzuschließen, und leiten Sie den Kunden, sofern eine Zahlung erforderlich ist, zum gehosteten Zahlungsportal weiter. Diese Anleitung setzt ein, nachdem der Warenkorb angelegt und die Kundendaten erfasst wurden. Die vollständigen Feld- und Enum-Definitionen finden Sie in der Booking v1 API-Referenz.
Bevor Sie beginnen
Senden Sie bei jeder Anfrage die Domain des Shops in X-Tenant-Domain mit. Behalten Sie das gültige Zugriffstoken für den Warenkorb bei; eine einfache Datensatz-ID gewährt keinen anonymen Zugriff. Der Warenkorb muss gültige Artikel sowie die erforderlichen Kontakt- und Checkout-Informationen enthalten. Für das Konto muss eine geeignete Zahlungsmethode konfiguriert sein.
Dieser Zahlungsablauf unterstützt Checkout-Richtlinien, die auf BOOKED ausgerichtet sind. Eine Richtlinie, die auf RESERVED oder REQUESTED ausgerichtet ist, erfordert einen anderen Übermittlungsablauf; nutzen Sie die Zahlungsauslösung nicht, um diesen zu umgehen.
Warenkorbanzeige und erforderliche Angaben vorbereiten
Führen Sie eine Abfrage für request mit dem Warenkorb-Zugriffstoken durch und wählen Sie requiresShipping aus, um zu entscheiden, ob Versanddetails erfasst werden sollen. Verwenden Sie requestItems { offerableNameTranslated offerableTimeZone } für lokalisierte Artikelnamen und die Zeitzone, die bei der Anzeige der Datums- und Zeitangaben der einzelnen Artikel verwendet wird.
Wählen Sie customFieldsCompletion(requiredByStage: BEFORE_PAYMENT) zusammen mit hasCustomFields, allComplete, allRequiredComplete sowie die Anzahlen unvollständiger Einträge und Gesamtzahlen bei RequestItem, Attendance sowie Contact (zum Beispiel countIncompleteAttendance und countTotalAttendance). Verwenden Sie diese Zahlen, um die verbleibenden Fragen beim Checkout anzuzeigen. Ist allRequiredComplete falsch, erfassen Sie die erforderlichen Antworten, bevor Sie den Checkout abschließen. Wird requiredByStage weggelassen oder null übergeben, wird BEFORE_PAYMENT verwendet; optionale, unbeantwortete Felder können dazu führen, dass allComplete auf „false“ gesetzt bleibt, selbst wenn die erforderlichen Antworten vollständig sind.
Diese Zusammenfassung gibt weder Antworten noch Tokens zur Antworterfassung noch die private Navigationsstruktur firstIncomplete preis. Nutzen Sie Ihren unterstützten Ablauf zur Erfassung von Antworten und aktualisieren Sie die Zusammenfassung anschließend. Aktualisieren Sie checkoutPolicy bei jeder Änderung des Warenkorbs: Die Werte compatible, targetState und conflicts sind für den kombinierten Warenkorb maßgeblich, selbst wenn einzelne Angebote einen Zielzustand für den Bezahlvorgang angeben.
Einen Code vor dem Checkout anwenden oder entfernen
Senden Sie pro HTTP-Anfrage eine Mutation, wobei das Warenkorb-Zugriffstoken als input.id und die Gutscheinnummer, der Coupon- oder Aktionscode des Kunden als input.code anzugeben sind:
mutation ApplyCheckoutCode($input: RequestApplyCodeInput!) {
requestApplyCode(input: $input) {
request {
vouchers {
number
name
value
}
totalVouchers
discounts {
label
value
coupon {
number
}
}
totalDiscount
}
requestItem {
id
}
followUpProducts {
id
name
}
followUpPriceValue
errors {
key
message
messageTranslated
}
}
}Prüfen Sie sowohl errors auf der obersten GraphQL-Ebene als auch errors in der Mutationsantwort, bevor Sie den Code als angewendet betrachten. Bei Erfolg aktualisieren Sie die angezeigten Gutscheine, Rabatte und Summen aus request. Gutscheinbeträge werden in vouchers und totalVouchers angezeigt; Rabatte aus Coupons und Aktionen erscheinen in discounts und totalDiscount. Durch das Anwenden eines Gutscheins auf einen Warenkorb wird dessen Guthaben nicht reserviert.
Ein Einzweckgutschein kann eine Produktauswahl erfordern. Wenn die Nutzlast requestItem: blank meldet und followUpProducts zurückgibt, zeigen Sie diese Artikel an und senden Sie requestApplyCode erneut mit demselben Warenkorb-Token und -Code sowie input.requestItem. Erstellen Sie diesen RequestItemInput aus dem ausgewählten Artikel, mit offerableId, offerableType und pricings; jeder Eintrag in pricings enthält die ausgewählten Werte für priceOriginId, priceOriginType und quantity. Fügen Sie alle erforderlichen Personalisierungen hinzu. Die erste Antwort ist eine Anfrage für diese Auswahl, keine erfolgreiche Anwendung, und deren request kann null sein.
Sofern angegeben, beschreibt followUpPriceValue den aus dem Gutschein übernommenen Preis. Der Server wendet diese Übernahme bei der Erstellung des Artikels an; senden Sie keine Preisüberschreibung vom Client, um dies nachzubilden. Booking v1 stellt weder targetPricingId noch eligibleVoucherTargets zur Auswahl einer bestehenden Preiszeile im Warenkorb bereit. Die Produktauswahl erstellt eine neue Warenkorbposition.
Um einen Code zu entfernen, übergeben Sie dasselbe Warenkorb-Token und den angewendeten Wert von vouchers.number oder discounts.coupon.number als input.code:
mutation RemoveCheckoutCode($input: RequestRemoveCodeInput!) {
requestRemoveCode(input: $input) {
request {
vouchers {
number
name
value
}
totalVouchers
discounts {
label
value
coupon {
number
}
}
totalDiscount
}
errors {
key
message
messageTranslated
}
}
}Behandeln Sie Fehler, bevor Sie die Darstellung des Warenkorbs aktualisieren, und verwenden Sie anschließend die zurückgegebenen Summen, wenn Sie den Bestellvorgang fortsetzen.
Lesen Sie die Warenkorb- und die aktuellen rechtlichen Hinweise
query CheckoutCart($id: IdOrNumberOrToken!) {
request(id: $id) {
checkoutHold {
expiresAt
secondsRemaining
}
checkoutPolicy {
compatible
targetState
conflicts {
reasonCode
requestItemId
targetState
}
}
requestItems {
id
requiresWithdrawalEarlyStartConsent
}
}
}Senden Sie diese Warenkorbabfrage in einer eigenen HTTP-Anfrage mit dem Warenkorb-Token als id. Anonymer Zugriff über ein Token unterstützt nur ein Feld auf oberster Ebene pro Operation. Laden Sie die rechtlichen Dokumente in einer separaten HTTP-Anfrage mit demselben X-Tenant-Domain-Header:
query CheckoutLegalDocuments($after: String) {
legalDocuments(first: 50, after: $after, required: [true]) {
edges {
node {
id
kind
nameTranslated
contentTranslated
checkboxLabelTranslated
isUrl
required
publishedAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}Lassen Sie bei der ersten Dokumentabfrage after weg oder setzen Sie es auf null. Wenn hasNextPage true ist, senden Sie eine weitere Dokumentabfrage mit endCursor als after, damit alle erforderlichen Dokumente angezeigt werden. Fassen Sie die Warenkorb- und Dokumentabfrage nicht in einer Operation zusammen. Es werden nur veröffentlichte, nicht verworfene Dokumente angezeigt. Verwenden Sie isUrl, um eine Dokument-URL von Inline-Inhalten zu unterscheiden.
Zeigen Sie dem Kunden jedes erforderliche Dokument mit dem zugehörigen Zustimmungstext. Speichern Sie dessen id und den exakten publishedAt-Wert zusammen mit der Zustimmung. Ersetzen Sie die gelesene Dokumentversion nicht durch die aktuelle Uhrzeit. Ändert sich die Version vor dem Absenden, laden Sie das Dokument erneut und holen Sie die Zustimmung zur neuen Version ein.
Wenn checkoutPolicy.compatible auf „false“ gesetzt ist, nutzen Sie die zurückgegebenen Konflikte, um dem Kunden die Möglichkeit zu geben, den Warenkorb zu ändern, bevor Sie fortfahren. Zeigen Sie die Frist des Checkout-Holds an, sofern vorhanden. Ein Countdown dient lediglich als Hinweis; der Server prüft beim Absenden, ob der Checkout-Hold noch aktiv ist.
Für Artikel mit requiresWithdrawalEarlyStartConsent: true holen Sie bitte eine ausdrückliche Einwilligung zum vorzeitigen Beginn ein. Übermitteln Sie die entsprechenden Artikel-IDs sowie den genauen Text, der dem Kunden angezeigt wurde; leiten Sie die Einwilligung nicht aus der Annahme anderer rechtlicher Dokumente ab.
Zur Kasse gehen
mutation CompleteCheckout($input: RequestPaymentInitiateInput!) {
requestPaymentInitiate(input: $input) {
request {
id
state
checkoutHold {
expiresAt
secondsRemaining
}
}
invoice {
accessToken
number
paymentLink
paymentState
paymentIntentCreateError
payments {
state
providerInitializationFailed
}
}
errors {
key
message
messageTranslated
}
}
}Verwenden Sie Variablen mit den zugelassenen Dokumentversionen:
{
"input": {
"id": "<cart access token>",
"legalDocumentAcceptances": [
{
"legalDocumentId": "<document ID>",
"legalDocumentVersion": "<publishedAt shown to the customer>"
}
]
}
}Fügen Sie bei Bedarf withdrawalEarlyStartConsent innerhalb von input ein, mit accepted: true, den betroffenen Positions-IDs in requestItemIds und dem angezeigten Einwilligungstext in text. Senden Sie die Einwilligung erst, nachdem der Kunde sie erteilt hat.
Behandeln Sie sowohl die GraphQL-Fehler in errors auf oberster Ebene als auch errors im Mutation-Payload. Ein Payload-Fehler bedeutet nicht, dass der Bestellvorgang abgeschlossen ist; verwenden Sie den Feldschlüssel und die übersetzte Meldung, um korrigierte Eingaben oder eine erneute rechtsgültige Zustimmung anzufordern.
Führen Sie die Zahlung erst dann durch, wenn dies erforderlich ist
Ein erfolgreicher Checkout kann invoice: null zurückgeben, beispielsweise bei einem kostenlosen Warenkorb. Lesen Sie in diesem Fall den zurückgegebenen request.state. Greifen Sie nicht auf Rechnungsfelder zu, starten Sie keine Zahlung und fragen Sie ohne Token keinen Rechnungsstatus ab.
Wenn eine Rechnung vorhanden ist, verwenden Sie deren paymentState. Eine Rechnung kann auch für einen bereits beglichenen Vorgang vorliegen. Das Vorliegen einer Rechnung, ihre Nummer, ein Vorgangsstatus von BOOKED oder das Vorhandensein von paymentLink beweisen nicht, dass noch ein Betrag aussteht oder dass die Zahlung erfolgreich war.
Öffnen Sie bei einer zahlungspflichtigen Rechnung den zurückgesendeten Link paymentLink unverändert. Er führt zur gehosteten Zahlungsseite und enthält ein Rechnungszugriffstoken. Behandeln Sie den Link und das Token als Anmeldedaten und vermeiden Sie die Erfassung durch Analysetools oder Protokollierung. Es handelt sich hierbei um den bestehenden, ein Token enthaltenden Zahlungslink; er bietet über diese Mutation weder einen einmalig verwendbaren Launch-Code-Austausch noch eine konfigurierbare Rückgabe-URL.
Überprüfen Sie paymentIntentCreateError und payments.providerInitializationFailed, wenn die Zahlungsinitialisierung fehlschlägt. Zeigen Sie keine Zahlungsbestätigung für fehlgeschlagene, ausstehende oder in Bearbeitung befindliche Zahlungen an.
Lesen Sie das Zahlungsergebnis aus und behandeln Sie den Fall eines Ablaufs
query CheckoutResult($id: IdOrNumberOrToken!) {
invoice(id: $id) {
paymentState
paymentIntentCreateError
payments {
state
providerInitializationFailed
}
request {
state
checkoutHold {
expiresAt
secondsRemaining
}
}
}
}Übermitteln Sie das accessToken der Rechnung als id mit demselben Shop-Header. Verwenden Sie den aktualisierten paymentState der Rechnung als maßgebliches Zahlungsergebnis. Eine Weiterleitung durch den Browser oder eine Rückmeldung des Zahlungsanbieters stellt keine Zahlungsbestätigung dar.
Sollte der Checkout-Hold ablaufen, aktualisieren Sie den verbindlichen Status, bevor Sie einen weiteren Zahlungsversuch unternehmen. Um die Stornierung eines abgelaufenen Warenkorbs zu beantragen, rufen Sie requestCancelExpiredCheckoutHold auf, wobei RequestCancelExpiredCheckoutHoldInput den Wert requestId: "<cart access token>" enthalten muss. Wählen Sie in der Nutzlast request { state } und errors { key message } aus. Der Server prüft die Berechtigung; ein aktiver Checkout-Hold gibt checkoutHold: not_expired zurück. Gehen Sie nicht davon aus, dass ein lokaler Countdown den Vorgang storniert oder die Kapazität freigegeben hat.