Checkout states
Free auto-issue versus paid Zahls checkout when creating orders via the API
POST /orders creates a checkout for an event. Requires orders:write and an Idempotency-Key. The organization must have zahls.ch connected for paid totals.
Create order response
Successful creates return 201 with:
{
"order": { "id": "…", "status": "COMPLETED" },
"checkoutUrl": null,
"issuedTickets": [{ "id": "…", "code": "…" }]
}| Field | Meaning |
|---|---|
order | Created order (includes items, customer, payment gateway when relevant) |
checkoutUrl | Zahls payment URL for pending paid orders; otherwise null |
issuedTickets | Tickets already issued when the order completed immediately; otherwise [] |
Free or fully discounted orders
When the payable total is zero (free tickets or discount to zero):
- The order completes automatically (
status: COMPLETED). - Tickets are issued immediately.
checkoutUrlisnull.issuedTicketscontains the issued tickets.- Related webhooks such as
order.completed/ticket.issuedmay fire.
No payment redirect is required.
Paid orders (Zahls)
When the payable total is greater than zero:
- The order stays
PENDINGuntil payment succeeds. checkoutUrlis a Zahls.ch checkout URL — redirect the customer there.issuedTicketsis empty until payment completes.- After successful payment, tickets are issued and completion webhooks fire.
Poll GET /orders/{orderId} or subscribe to webhooks for completion.
Optionally set checkoutRedirectUrls (success, failure, cancel) so Zahls returns customers to your storefront instead of Cowtic’s hosted pages. See Headless checkout.
Physical delivery
If the event uses physical delivery, include shippingAddress (street, zip, city, country) on create. Missing shipping data returns 400.
Cancel
POST /orders/{orderId}/cancel requires orders:cancel. Paid completed orders may require a manual refund outside the automatic cancel path — check the response flag requiresManualRefund.