Startseite Funktionen Preise Blog
Einloggen Kostenlos starten
English | Deutsch

Mit Webhooks reagieren Deine Systeme auf Ereignisse in Deinem Usetix-Konto — ein verkauftes Ticket, eine ausgelöste Rückerstattung, ein live geschaltetes Event — ohne unsere API abfragen zu müssen. Sobald ein abonniertes Ereignis eintritt, sendet Usetix eine signierte POST-Anfrage an eine von Dir festgelegte URL.

Webhooks verwaltest Du in Deinem Dashboard unter Einstellungen → Webhooks.

Zustellung

Eigenschaft Wert
Methode POST
Content-Type application/json
User-Agent usetix/1.0.0 Webhook
Timeout 7 Sekunden
Maximale Antwortgröße 100 KB

Jedes Ereignis erzeugt genau einen Zustellversuch pro passendem Webhook. Automatische Wiederholungen gibt es derzeit nicht — stell also sicher, dass Dein Endpunkt erreichbar ist und zügig antwortet.

Signierung

Jede Anfrage wird per HMAC-SHA256 mit dem signing_secret des Webhooks signiert. Das Secret wird Dir im Dashboard angezeigt, sobald Du den Webhook anlegst. Zwei Header werden mitgeschickt:

Header Beschreibung
X-Webhook-Signature Hex-kodierter HMAC-SHA256 des rohen Request-Body, erzeugt mit dem Signing-Secret des Webhooks.
X-Webhook-Timestamp ISO-8601-Zeitstempel (UTC) des Ereignisses — bleibt bei etwaigen künftigen Wiederholungen stabil.

Verifizierung in Ruby:

expected = OpenSSL::HMAC.hexdigest("SHA256", signing_secret, request.raw_post)
Rack::Utils.secure_compare(expected, request.headers["X-Webhook-Signature"])

Verifizierung in Node.js:

const expected = crypto
  .createHmac("sha256", signingSecret)
  .update(rawBody)
  .digest("hex");
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(req.header("X-Webhook-Signature")));

Berechne die Signatur immer über den rohen Request-Body — nicht über eine geparste oder neu serialisierte Kopie — und nutze einen zeitkonstanten Vergleich.

Automatische Deaktivierung

Wenn ein Webhook bei 10 aufeinanderfolgenden Zustellungen über mehr als 1 Stunde fehlschlägt, deaktiviert Usetix ihn automatisch. Es werden keine weiteren Zustellungen mehr versendet, bis Du den Webhook im Dashboard wieder aktivierst. Ein Endpunkt gilt als erfolgreich, wenn er HTTP 2xx zurückgibt; alles andere (Timeout, Nicht-2xx, TLS-Fehler, DNS-Fehler) zählt als Fehlschlag.

SSRF-Schutz

Webhook-URLs, die auf private, Loopback-, Link-Local- oder andere nicht-öffentliche IP-Adressen auflösen, werden bei der Zustellung abgelehnt. Verwende ausschließlich öffentliche Hostnamen.

Abonnierbare Ereignisse

Jeder Webhook abonniert eine oder mehrere der folgenden Aktionen:

  • order.paid
  • order.refunded
  • order.cancelled
  • event.published
  • event.unpublished

Payload-Envelope

Jeder Payload hat dieselbe äußere Struktur. Das eventable-Objekt variiert je nach Aktion.

{
  "action": "order.paid",
  "created_at": "2026-04-22T12:34:56Z",
  "eventable": { "...": "siehe unten" },
  "account": {
    "name": "Example Promoter",
    "subdomain": "example"
  }
}

Order-Payloads

Wird gesendet bei order.paid, order.refunded und order.cancelled. Das Feld action zeigt Dir, welcher Übergang ausgelöst wurde.

{
  "action": "order.paid",
  "created_at": "2026-04-22T12:34:56Z",
  "account": { "name": "Example Promoter", "subdomain": "example" },
  "eventable": {
    "id": "ord_c3a9f4e1",
    "type": "Order",
    "customer_email": "[email protected]",
    "customer_name": "Jane Doe",
    "total_amount": "42.00",
    "currency": "EUR",
    "status": "paid",
    "paid_at": "2026-04-22T12:34:50Z",
    "items": [
      {
        "id": "oi_4d2a8b9c",
        "ticket_title": "General Admission",
        "event_title": "Spring Showcase",
        "price": "21.00"
      }
    ]
  }
}
Feld Typ Hinweise
eventable.id string Öffentliche Bestellungs-ID. Stabil; kann als Korrelationsschlüssel gespeichert werden.
eventable.customer_email string E-Mail des Käufers.
eventable.customer_name string Name des Käufers.
eventable.total_amount string Dezimalwert als String kodiert (z. B. "42.00"), um Float-Präzisionsprobleme zu vermeiden.
eventable.currency string ISO-4217-Währungscode.
eventable.status string paid, refunded oder cancelled.
eventable.paid_at string | null ISO 8601 UTC. null bei Status ungleich paid.
eventable.items[].id string Öffentliche ID des Bestellpostens (eine pro Ticket).
eventable.items[].ticket_title string Titel des Tickettyps.
eventable.items[].event_title string Titel des Events, zu dem das Ticket gehört.
eventable.items[].price string Dezimalwert als String.

Event-Payloads

Wird gesendet bei event.published und event.unpublished.

{
  "action": "event.published",
  "created_at": "2026-04-22T12:34:56Z",
  "account": { "name": "Example Promoter", "subdomain": "example" },
  "eventable": {
    "slug": "spring-showcase",
    "type": "Event",
    "title": "Spring Showcase",
    "starts_at": "2026-05-01T19:00:00Z",
    "ends_at": "2026-05-01T23:00:00Z",
    "venue": {
      "name": "The Venue",
      "city": "Berlin"
    }
  }
}
Feld Typ Hinweise
eventable.slug string URL-Slug. Die öffentliche URL des Events lautet https://<subdomain>.usetix.io/events/<slug>.
eventable.title string Titel des Events.
eventable.starts_at string ISO 8601 UTC.
eventable.ends_at string ISO 8601 UTC.
eventable.venue.name string Name des Veranstaltungsorts.
eventable.venue.city string Stadt des Veranstaltungsorts.

Lokal testen

Für die lokale Entwicklung liefern Dir Tools wie ngrok oder Cloudflare Tunnel eine öffentliche URL, die auf localhost weiterleitet. Richte einen Webhook auf diese URL ein, löse dann Aktionen in Deinem Konto aus und siehe echte Payloads in Echtzeit ankommen.