Logocowtic
Öffentliche API

Headless-Checkout

Eigenen Shop mit Warenkorb, Zahls-Zahlung und Ticketausstellung über die Public API aufbauen

Nutzen Sie die Public API von Ihrem Backend aus. Legen Sie keinen Organisations-API-Key in Browser-JavaScript ab. Die Cowtic-CORS-Konfiguration erlaubt keine beliebigen Partner-Origins für /api/v1.

Dieser Leitfaden beschreibt einen minimalen eigenen Checkout, der:

  1. Tickettypen auf Ihrer Website anzeigt
  2. den Warenkorb im Browser hält
  3. die Bestellung über Ihr Backend erstellt
  4. zahlende Kundinnen und Kunden zu Zahls weiterleitet
  5. sie auf Ihre Erfolgs-/Fehler-/Abbruchseiten zurückführt
  6. nach der Zahlung ausgegebene Tickets abruft

Zu den Bestellstatus (COMPLETED vs. PENDING, gratis vs. bezahlt) siehe Checkout-Zustände.

Ausführbares Beispiel

Im Repository liegt eine Bun-Referenz-App:

examples/headless-checkout

Sie nutzt @cowtic/sdk serverseitig, signierte HttpOnly-Cookies für die Bestellabfrage und eigene Zahls-Return-URLs.

Erforderliche Scopes

SchrittScopes
Katalog ladenevents:read, ticket_types:read
Checkout erstellenorders:write
Abschluss pollenorders:read, tickets:read
Optional Check-intickets:check_in

Für bezahlte Totale muss zahls.ch für die Organisation verbunden sein.

Architektur

Ihr Frontend (Warenkorb-UI)


Ihr Backend (API-Key + @cowtic/sdk)


Cowtic Public API  ──►  Zahls checkoutUrl
        ▲                      │
        │ Webhook              │ Return-URLs
        └──────────────────────┘
Ihre Erfolgsseite pollt GET /orders/{id}

Ablauf von Ende zu Ende

Tickettypen laden

GET /events/{eventId} und GET /events/{eventId}/ticket-types von Ihrem Backend. Rendern Sie Preise und Verfügbarkeit auf Ihrer Website.

Warenkorb lokal halten

Es gibt keine Cart-API. Speichern Sie die Auswahl im Browser (oder in Ihrer eigenen Session). Bestand wird erst reserviert, wenn POST /orders erfolgreich ist.

Bestellung erstellen

Rufen Sie von Ihrem Backend POST /orders mit einem Idempotency-Key auf:

import { Cowtic } from "@cowtic/sdk";

const cowtic = new Cowtic({ apiKey: process.env.COWTIC_API_KEY! });

const { data } = await cowtic.orders.create({
  eventId: process.env.COWTIC_EVENT_ID!,
  customer: { email: "buyer@example.com", name: "Buyer" },
  items: [{ ticketId: "ticket_type_id", quantity: 1 }],
  checkoutRedirectUrls: {
    success: "https://shop.example.com/checkout/success",
    failure: "https://shop.example.com/checkout/failure",
    cancel: "https://shop.example.com/checkout/cancel",
  },
}, {
  idempotencyKey: "checkout_01J...",
});
  • Gratis / Total 0: order.status ist COMPLETED, checkoutUrl ist null, issuedTickets ist befüllt.
  • Bezahlt: order.status ist PENDING, checkoutUrl ist eine Zahls-URL, issuedTickets ist leer.

Zu Zahls weiterleiten

Leiten Sie die Kundin oder den Kunden zu checkoutUrl. Nach Zahlung (oder Abbruch/Fehler) kehrt Zahls zur passenden URL aus checkoutRedirectUrls zurück.

Ausstellung abwarten

Tickets werden ausgestellt, nachdem Cowtic den Zahls-Webhook erhalten hat. Auf Ihrer Erfolgsseite:

  1. pollen Sie GET /orders/{orderId}, bis status COMPLETED ist, oder
  2. abonnieren Sie Webhooks für order.completed / ticket.issued

Rufen Sie danach GET /tickets/{ticketId} für das vollständige Ticket ab (inkl. code und downloadTicketUrl).

Check-in

Scannen Sie den QR-Code (Ticketcode) in der Cowtic-Check-in-App oder rufen Sie POST /tickets/check-in mit { "code": "TCKT-…" } auf.

Eigene Return-URLs

checkoutRedirectUrls ist optional bei POST /orders. Ohne Angabe führt Zahls auf Cowtics gehostete Bestätigungsseiten. Wenn gesetzt, sind alle drei Felder Pflicht:

FeldWann Zahls es nutzt
successZahlung erfolgreich
failureZahlung fehlgeschlagen
cancelKundin oder Kunde hat abgebrochen

URLs müssen http oder https verwenden. Nutzen Sie absolute URLs, die Ihr Shop ausliefern kann.

Sicherheitshinweise

  • API-Key nur auf dem Server speichern.
  • Beliebige Bestell-IDs nicht ohne eigene Auth an anonyme Browser ausliefern (Session-Cookie, signiertes Token usw.).
  • Für die Produktion Webhooks bevorzugen; Polling eignet sich für die UX der Erfolgsseite.

Physische Lieferung und Formulare

Dieser minimale Headless-Pfad deckt digitale Tickets ab. Physische Lieferung erfordert weiterhin shippingAddress bei der Erstellung (siehe Checkout-Zustände). Eigene Event-Formularfelder sind im Public-API-Schema zur Bestellerstellung noch nicht verfügbar.

On this page