Zum Hauptinhalt springen

Webhooks

Webhooks ermöglichen Ihrer Anwendung den Empfang von Echtzeit-HTTP-Callbacks, wenn Ereignisse in Ihrer Gäld-Organisation auftreten. Wenn ein Ereignis ausgelöst wird, sendet Gäld eine POST-Anfrage an jede registrierte Webhook-URL.

Webhook einrichten

Erstellen Sie einen Webhook über die API:

curl -X POST https://app.gaeld.ch/api/v1/webhooks \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/gaeld",
"events": ["invoice.created", "invoice.finalized", "customer.created"],
"is_active": true
}'

Die Antwort enthält ein secretspeichern Sie es sicher, Sie benötigen es zur Signaturprüfung.

Ereignisse

EreignisWird ausgelöst, wenn
invoice.createdEine neue Rechnung erstellt wird
invoice.updatedEine Rechnung geändert wird
invoice.deletedEine Rechnung gelöscht wird
invoice.finalizedEine Rechnung finalisiert (zur Bearbeitung gesperrt) wird
invoice.payment_recordedEine Zahlung für eine Rechnung erfasst wird
customer.createdEin neuer Kunde erstellt wird
customer.updatedEin Kunde geändert wird
customer.deletedEin Kunde gelöscht wird
expense.createdEine neue Ausgabe erstellt wird
expense.updatedEine Ausgabe geändert wird
expense.deletedEine Ausgabe gelöscht wird
expense.approvedEine Ausgabe im Workflow genehmigt wird

Verwenden Sie GET /api/v1/meta/webhook-events, um diese Liste programmatisch abzurufen.

Payload-Format

Jede Webhook-Zustellung sendet eine JSON-POST-Anfrage:

{
"event": "invoice.finalized",
"timestamp": "2025-06-01T12:00:00Z",
"data": {
"id": "uuid",
"number": "INV-2025-042",
"status": "finalized",
"customer": { "id": "uuid", "name": "ACME GmbH" },
"total": "1081.00",
"currency": "CHF"
}
}

Das Feld data enthält die vollständige Ressourcendarstellung (gleiches Format wie die Antwort des entsprechenden API-Endpunkts).

Anfrage-Header

Jede Webhook-Anfrage enthält diese Header:

HeaderBeschreibung
Content-Typeapplication/json
X-Webhook-SignatureHMAC-SHA256-Hex-Digest des Anfragekörpers
X-Webhook-EventEreignisname (z. B. invoice.created)
X-Webhook-IdEindeutige Zustellungs-ID
User-AgentGaeld-Webhook/1.0

Signaturprüfung

Jede Webhook-Anfrage wird mit HMAC-SHA256 und dem Webhook-Secret signiert. Überprüfen Sie immer die Signatur, bevor Sie den Payload verarbeiten.

PHP

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';

$computed = hash_hmac('sha256', $payload, $webhookSecret);

if (! hash_equals($computed, $signature)) {
http_response_code(400);
exit('Invalid signature');
}

$event = json_decode($payload, true);
// $event verarbeiten

Node.js

const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
const computed = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(computed),
Buffer.from(signature)
);
}

// In Ihrem Express-Handler:
app.post('/webhooks/gaeld', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-webhook-signature'];
if (!verifySignature(req.body, signature, process.env.WEBHOOK_SECRET)) {
return res.status(400).send('Invalid signature');
}
const event = JSON.parse(req.body);
// Ereignis verarbeiten
res.sendStatus(200);
});

Python

import hmac
import hashlib

def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
computed = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
return hmac.compare_digest(computed, signature)

Zustellung & Wiederholungsversuche

EigenschaftWert
HTTP-Timeout10 Sekunden
Max. Versuche3
Wiederholungs-Backoff30 Sekunden, 5 Minuten, 1 Stunde
Erwartete AntwortJeder 2xx-Statuscode

Wenn Ihr Endpunkt einen Nicht-2xx-Status zurückgibt oder ein Timeout auftritt, wiederholt Gäld mit exponentiellem Backoff. Nach 3 fehlgeschlagenen Versuchen wird die Zustellung als fehlgeschlagen markiert. Sie können den Zustellungsstatus über die Webhook-API überprüfen.

Webhooks verwalten

AktionMethodeEndpunkt
Alle auflistenGET/api/v1/webhooks
Details anzeigenGET/api/v1/webhooks/{id}
ErstellenPOST/api/v1/webhooks
Ereignisse/URL aktualisierenPUT/api/v1/webhooks/{id}
LöschenDELETE/api/v1/webhooks/{id}
Secret erneuernPOST/api/v1/webhooks/{id}/regenerate-secret
Secret-Rotation

Nach dem Aufruf von regenerate-secret aktualisieren Sie Ihre Anwendung sofort mit dem neuen Secret. Das alte Secret wird ungültig und alle nachfolgenden Zustellungen verwenden das neue.

Best Practices

  • Überprüfen Sie immer Signaturen — vertrauen Sie niemals dem Payload-Inhalt, ohne die HMAC-Signatur zu prüfen
  • Antworten Sie schnell — geben Sie sofort 200 zurück und verarbeiten Sie das Ereignis asynchron (z. B. über eine Job-Queue)
  • Behandeln Sie Duplikate — verwenden Sie den X-Webhook-Id-Header zur Deduplizierung, falls Ihr Endpunkt mehrfach aufgerufen wird
  • Verwenden Sie HTTPS — Webhook-URLs müssen in der Produktion HTTPS verwenden
  • Überwachen Sie Fehler — überprüfen Sie regelmässig den Webhook-Zustellungsstatus und beheben Sie fehlerhafte Endpunkte