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:
- Tickettypen auf Ihrer Website anzeigt
- den Warenkorb im Browser hält
- die Bestellung über Ihr Backend erstellt
- zahlende Kundinnen und Kunden zu Zahls weiterleitet
- sie auf Ihre Erfolgs-/Fehler-/Abbruchseiten zurückführt
- 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:
Sie nutzt @cowtic/sdk serverseitig, signierte HttpOnly-Cookies für die Bestellabfrage und eigene Zahls-Return-URLs.
Erforderliche Scopes
| Schritt | Scopes |
|---|---|
| Katalog laden | events:read, ticket_types:read |
| Checkout erstellen | orders:write |
| Abschluss pollen | orders:read, tickets:read |
| Optional Check-in | tickets: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.statusistCOMPLETED,checkoutUrlistnull,issuedTicketsist befüllt. - Bezahlt:
order.statusistPENDING,checkoutUrlist eine Zahls-URL,issuedTicketsist 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:
- pollen Sie
GET /orders/{orderId}, bisstatusCOMPLETEDist, oder - 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:
| Feld | Wann Zahls es nutzt |
|---|---|
success | Zahlung erfolgreich |
failure | Zahlung fehlgeschlagen |
cancel | Kundin 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.