Zum Hauptinhalt springen
Webhooks für Zahlungspläne benachrichtigen dein System automatisch über Ereignisse im Lebenszyklus eines Plans. Sobald ein Ereignis eintritt, sendet Fynn einen POST-Request mit strukturierten JSON-Daten an deine hinterlegte URL.
Die Einrichtung, die Zustellung und die Signaturprüfung sind für alle Webhooks gleich. Wie du Webhooks anlegst und absicherst, liest du unter Webhooks einrichten. Auf dieser Seite findest du nur, was für Zahlungspläne gilt: die verfügbaren Events und ihre Payloads.

Der Envelope

Jeder Zahlungsplan-Webhook hat denselben Aufbau. Das eigentliche Objekt steckt unter data, daneben liegen Metadaten zum Ereignis.
event
object
erforderlich
Metadaten zum Ereignis.
data
object
erforderlich
Die Nutzdaten des Ereignisses. Der Schlüssel paymentPlan enthält den Plan. Bei payment_plan.rate_paid liegt zusätzlich unter installment die soeben bezahlte Rate.

HTTP-Header

Jede Zustellung bringt diese Header mit:
HeaderInhalt
X-Webhook-EventDer Ereignistyp, zum Beispiel payment_plan.broken.
X-Webhook-Event-VersionSchema-Version, aktuell v1.
X-Webhook-IdEindeutige Kennung der Zustellung, identisch mit event.id.
X-Webhook-SignatureSignatur des Bodys zur Echtheitsprüfung.
X-Tenant-IdKennung deiner Organisation.
Prüfe immer die Signatur aus X-Webhook-Signature, bevor du eine Zustellung verarbeitest. So stellst du sicher, dass die Anfrage wirklich von Fynn stammt. Den Ablauf und Beispielcode findest du unter Webhooks einrichten.

Verfügbare Events

EventWird ausgelöst, wenn
payment_plan.createdEin Zahlungsplan für eine offene Rechnung angelegt wird.
payment_plan.rate_paidEine Rate vollständig gedeckt ist.
payment_plan.completedAlle Raten bezahlt sind und die Rechnung damit beglichen ist.
payment_plan.brokenEin Einzug ausfällt oder eine Rate überfällig bleibt.
payment_plan.canceledEin Plan manuell gekündigt wird.
payment_plan.extendedEin Plan mit einem neuen Zeitplan verlängert wird.

Das paymentPlan-Objekt

Unter data.paymentPlan erhältst du den Plan in seiner Lese-Darstellung, identisch zur Antwort der Plan-Endpunkte. Die wichtigsten Felder:
id
string
Eindeutige Kennung des Plans. Nutze sie, um über GET /payment-plans/{id} den vollständigen Stand nachzuladen.
invoiceId
string
Die Rechnung, die aufgeteilt wird.
status
string
Der Status des Plans: active, completed, broken oder canceled.
totalAmount
integer
Summe aller Raten in Cent.
currencyCode
string
Währung, zum Beispiel EUR.
brokenReason
string | null
Grund des Planbruchs, sonst null.
installments
array
Die Raten des Plans mit position, dueAt, amount, status und paidAt.

payment_plan.created

Feuert, sobald ein Plan angelegt ist. Ab jetzt ruht das Mahnwesen für die Rechnung.
{
  "event": {
    "id": "01JZ8F3KQ9X7N2VYB4C6D8E0FG",
    "type": "payment_plan.created",
    "version": "v1",
    "createdAt": "2026-07-05T16:20:00+00:00"
  },
  "data": {
    "paymentPlan": {
      "id": "10000000-0000-0000-00e0-000000000001",
      "invoiceId": "10000000-0000-0000-0003-000000000001",
      "status": "active",
      "totalAmount": 1190,
      "currencyCode": "EUR",
      "paymentMethodId": "10000000-0000-0000-004f-000000000001",
      "createdAt": "2026-07-05T16:20:00+00:00",
      "completedAt": null,
      "brokenAt": null,
      "canceledAt": null,
      "brokenReason": null,
      "installments": [
        { "id": "…", "position": 1, "dueAt": "2026-08-05", "amount": 595, "status": "open", "paidAt": null },
        { "id": "…", "position": 2, "dueAt": "2026-09-05", "amount": 595, "status": "open", "paidAt": null }
      ]
    }
  }
}

payment_plan.rate_paid

Feuert, sobald eine Rate vollständig gedeckt ist. Nur bei diesem Event liegt neben paymentPlan auch die betroffene Rate unter installment.
{
  "event": {
    "id": "01JZ8G4M0RY8P3WZC5D7E9F1GH",
    "type": "payment_plan.rate_paid",
    "version": "v1",
    "createdAt": "2026-08-05T04:00:03+00:00"
  },
  "data": {
    "paymentPlan": {
      "id": "10000000-0000-0000-00e0-000000000001",
      "invoiceId": "10000000-0000-0000-0003-000000000001",
      "status": "active",
      "totalAmount": 1190,
      "currencyCode": "EUR",
      "paymentMethodId": "10000000-0000-0000-004f-000000000001",
      "createdAt": "2026-07-05T16:20:00+00:00",
      "completedAt": null,
      "brokenAt": null,
      "canceledAt": null,
      "brokenReason": null,
      "installments": [
        { "id": "…", "position": 1, "dueAt": "2026-08-05", "amount": 595, "status": "paid", "paidAt": "2026-08-05T04:00:02+00:00" },
        { "id": "…", "position": 2, "dueAt": "2026-09-05", "amount": 595, "status": "open", "paidAt": null }
      ]
    },
    "installment": {
      "id": "…",
      "position": 1,
      "dueAt": "2026-08-05",
      "amount": 595,
      "status": "paid",
      "paidAt": "2026-08-05T04:00:02+00:00"
    }
  }
}

payment_plan.completed

Feuert, sobald die letzte offene Rate gedeckt ist. Die Rechnung ist damit beglichen.
{
  "event": {
    "id": "01JZ9A5N1SZ9Q4XAD6E8F0G2HJ",
    "type": "payment_plan.completed",
    "version": "v1",
    "createdAt": "2026-09-05T04:00:04+00:00"
  },
  "data": {
    "paymentPlan": {
      "id": "10000000-0000-0000-00e0-000000000001",
      "invoiceId": "10000000-0000-0000-0003-000000000001",
      "status": "completed",
      "totalAmount": 1190,
      "currencyCode": "EUR",
      "paymentMethodId": "10000000-0000-0000-004f-000000000001",
      "createdAt": "2026-07-05T16:20:00+00:00",
      "completedAt": "2026-09-05T04:00:03+00:00",
      "brokenAt": null,
      "canceledAt": null,
      "brokenReason": null,
      "installments": [
        { "id": "…", "position": 1, "dueAt": "2026-08-05", "amount": 595, "status": "paid", "paidAt": "2026-08-05T04:00:02+00:00" },
        { "id": "…", "position": 2, "dueAt": "2026-09-05", "amount": 595, "status": "paid", "paidAt": "2026-09-05T04:00:03+00:00" }
      ]
    }
  }
}

payment_plan.broken

Feuert, sobald der Plan bricht: ein Lastschrift-Einzug ist fehlgeschlagen, oder eine Rate ist über ihre Frist hinaus unbeglichen geblieben. Der Restbetrag ist ab jetzt sofort fällig, und das Mahnwesen für die Rechnung läuft wieder. brokenReason nennt den Auslöser.
{
  "event": {
    "id": "01JZ9B6P2T0R5YBE7F9G1H3J4K",
    "type": "payment_plan.broken",
    "version": "v1",
    "createdAt": "2026-08-06T05:00:01+00:00"
  },
  "data": {
    "paymentPlan": {
      "id": "10000000-0000-0000-00e0-000000000001",
      "invoiceId": "10000000-0000-0000-0003-000000000001",
      "status": "broken",
      "totalAmount": 1190,
      "currencyCode": "EUR",
      "paymentMethodId": "10000000-0000-0000-004f-000000000001",
      "createdAt": "2026-07-05T16:20:00+00:00",
      "completedAt": null,
      "brokenAt": "2026-08-06T05:00:00+00:00",
      "canceledAt": null,
      "brokenReason": "installment collection failed",
      "installments": [
        { "id": "…", "position": 1, "dueAt": "2026-08-05", "amount": 595, "status": "failed", "paidAt": null },
        { "id": "…", "position": 2, "dueAt": "2026-09-05", "amount": 595, "status": "open", "paidAt": null }
      ]
    }
  }
}

payment_plan.canceled

Feuert, sobald ein Plan manuell gekündigt wird. Der offene Betrag wird wieder normal gemahnt.
{
  "event": {
    "id": "01JZ9C7Q3U1S6ZCF8G0H2J4K5L",
    "type": "payment_plan.canceled",
    "version": "v1",
    "createdAt": "2026-08-10T09:15:00+00:00"
  },
  "data": {
    "paymentPlan": {
      "id": "10000000-0000-0000-00e0-000000000001",
      "invoiceId": "10000000-0000-0000-0003-000000000001",
      "status": "canceled",
      "totalAmount": 1190,
      "currencyCode": "EUR",
      "paymentMethodId": "10000000-0000-0000-004f-000000000001",
      "createdAt": "2026-07-05T16:20:00+00:00",
      "completedAt": null,
      "brokenAt": null,
      "canceledAt": "2026-08-10T09:15:00+00:00",
      "brokenReason": null,
      "installments": [
        { "id": "…", "position": 1, "dueAt": "2026-08-05", "amount": 595, "status": "paid", "paidAt": "2026-08-05T04:00:02+00:00" },
        { "id": "…", "position": 2, "dueAt": "2026-09-05", "amount": 595, "status": "open", "paidAt": null }
      ]
    }
  }
}

payment_plan.extended

Feuert, sobald ein Plan mit einem neuen Zeitplan verlängert wird. Ein zuvor gebrochener Plan steht danach wieder auf active, brokenAt und brokenReason sind geleert.
{
  "event": {
    "id": "01JZ9D8R4V2T7ADG9H1J3K5L6M",
    "type": "payment_plan.extended",
    "version": "v1",
    "createdAt": "2026-08-07T11:00:00+00:00"
  },
  "data": {
    "paymentPlan": {
      "id": "10000000-0000-0000-00e0-000000000001",
      "invoiceId": "10000000-0000-0000-0003-000000000001",
      "status": "active",
      "totalAmount": 1190,
      "currencyCode": "EUR",
      "paymentMethodId": "10000000-0000-0000-004f-000000000001",
      "createdAt": "2026-07-05T16:20:00+00:00",
      "completedAt": null,
      "brokenAt": null,
      "canceledAt": null,
      "brokenReason": null,
      "installments": [
        { "id": "…", "position": 1, "dueAt": "2026-08-05", "amount": 595, "status": "failed", "paidAt": null },
        { "id": "…", "position": 2, "dueAt": "2026-10-05", "amount": 297, "status": "open", "paidAt": null },
        { "id": "…", "position": 3, "dueAt": "2026-11-05", "amount": 298, "status": "open", "paidAt": null }
      ]
    }
  }
}
Antworte mit einem 2xx-Statuscode, sobald du die Zustellung angenommen hast. Schlägt die Zustellung fehl, wiederholt Fynn sie bis zu dreimal.