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.
Metadaten zum Ereignis. Eindeutige Kennung dieser Zustellung (ULID), identisch mit dem Header X-Webhook-Id. Nutze sie, um Wiederholungen idempotent zu verarbeiten.
Der Ereignistyp, zum Beispiel payment_plan.rate_paid.
Schema-Version des Ereignisses, aktuell v1.
Zeitpunkt der Auslösung im ISO-8601-Format.
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.
Jede Zustellung bringt diese Header mit:
Header Inhalt 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
Event Wird 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:
Die Rechnung, die aufgeteilt wird.
Der Status des Plans: active, completed, broken oder canceled.
Summe aller Raten in Cent.
Währung, zum Beispiel EUR.
Grund des Planbruchs, sonst null.
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.