Webhook-Events und Payloads
July 30, 2026
Referenz der FlowAlp Pay Webhook-Events: Payloads für Transaktionen, Subscriptions und Auszahlungen mit JSON-Beispielen und Idempotenz-Tipps.
FlowAlp Pay liefert drei Arten von Webhook-Events an die von Ihnen konfigurierte URL: Transaktions-, Subscription- und Auszahlungs-Events. Diese Seite dokumentiert die Payloads und wie Ihr Endpoint sie quittieren muss.
Grundlagen der Zustellung
- Jedes Event ist ein HTTP-
POSTan Ihre Webhook-URL, je nach Konfiguration als JSON oder Formulardaten kodiert. - Alle Beträge sind Ganzzahlen in der kleinsten Währungseinheit:
8925bedeutet CHF 89.25. - Transaktions- und Subscription-Events feuern bei jedem Statuswechsel; Auszahlungs-Events erst, wenn eine Auszahlung tatsächlich verarbeitet wird.
- Ordnen Sie Ihre Bestellung über
referenceIdzu — oder über die Payment-Link-ID in deninvoice-Daten.
Transaktions-Events
Der Payload enthält ein einzelnes transaction-Objekt. Die wichtigsten Felder:
| Feld | Typ | Beschreibung |
|---|---|---|
| id / uuid | int / string | Interne ID und öffentliche ID der Transaktion |
| status | string | Transaktionsstatus, siehe Tabelle unten |
| amount | int | Verarbeiteter Betrag in Minor Units |
| referenceId | string | Ihre Bestellreferenz |
| time | string | Erstellungszeitpunkt im ISO-8601-Format |
| mode | string | TEST oder LIVE |
| psp / pspId | string / int | Kennungen des verarbeitenden Zahlungsanbieters |
| type | string | E-Commerce, POS-Terminal oder Tap to Pay |
| refundable / partiallyRefundable | bool | Ob eine (Teil-)Rückerstattung möglich ist |
| invoice | object | Bestelldaten: currency, products, originalAmount, refundedAmount, custom_fields, … |
| contact | object oder null | Kunden- und Lieferadressdaten |
| payment | object | Zahlungsmittel, z. B. brand und wallet |
| subscription | object oder null | Vorhanden, wenn die Transaktion zu einer Subscription gehört |
| instance | object | Ihr Händlerkonto: name und uuid |
| payoutUuid | string oder null | UUID der Auszahlung, die diese Transaktion enthält |
| preAuthorizationId | int | Nur bei Tokenisierungen/Charges: ID der Tokenisierungsquelle |
| originalTransactionId / -Uuid | int / string | Nur bei Rückerstattungen: die ursprünglich belastete Transaktion |
Beachten Sie: Die Währung steckt im invoice-Objekt (invoice.currency) und ist kein Top-Level-Feld.
| Status | Bedeutung |
|---|---|
waiting | Bestellung angelegt, Zahlung noch nicht abgeschlossen |
confirmed | Erfolgreiche Zahlung |
cancelled | Zahlung durch die Kundschaft abgebrochen |
declined | 3-D Secure fehlgeschlagen oder von der Issuer-Bank abgelehnt |
authorized | Erfolgreiche Tokenisierung |
reserved | Erfolgreiche Reservation (Vorautorisierung) |
refunded | Vollständige Rückerstattung |
partially-refunded | Teilrückerstattung |
refund_pending | Rückerstattung in Verarbeitung |
chargeback | Karteninhaber hat das Geld zurückgefordert |
disputed | Zu dieser Transaktion wurde ein Disput eröffnet |
error | Während der Zahlung ist ein Problem aufgetreten |
expired | Zahlung wegen Inaktivität abgebrochen |
{
"transaction": {
"id": 1234,
"uuid": "1122aabb",
"status": "confirmed",
"amount": 8925,
"referenceId": "ORDER-975382",
"time": "2026-07-30T09:36:07+00:00",
"lang": "de",
"psp": "Native_PSP",
"pspId": 44,
"mode": "TEST",
"type": "E-Commerce",
"refundable": true,
"partiallyRefundable": true,
"instance": {
"name": "demo-shop",
"uuid": "aabb1122"
},
"metadata": {},
"invoice": {
"number": "IV_2041",
"currency": "CHF",
"test": 1,
"referenceId": "ORDER-975382",
"originalAmount": 8925,
"refundedAmount": 0,
"shippingAmount": null,
"paymentLink": null,
"paymentRequestId": null,
"products": [
{
"name": "Season pass",
"quantity": 1,
"price": 8925,
"sku": null,
"vatRate": "8.1",
"description": ""
}
],
"discount": {
"code": null,
"amount": 0,
"percentage": null
},
"custom_fields": [
{
"type": "email",
"name": "E-Mail",
"value": "buyer@example.com"
}
]
},
"contact": {
"id": 1234,
"uuid": "aabb1122",
"firstname": "Jane",
"lastname": "Doe",
"company": "Alpina Sport AG",
"street": "Burgstrasse 20",
"zip": "3600",
"place": "Thun",
"country": "Switzerland",
"countryISO": "CH",
"phone": "0335500010",
"email": "buyer@example.com"
},
"payment": {
"brand": "visa",
"wallet": null
},
"subscription": null,
"payoutUuid": null
}
}Subscription-Events
Subscription-Events feuern, wenn sich der Zustand einer wiederkehrenden Abrechnung ändert. Felder: id, uuid, status, start, end, valid_until (nächstes Abbuchungsdatum), paymentInterval (eine Dauer wie P1M gemäss PHP-DateInterval-Spezifikation) sowie die Objekte invoice und contact.
| Status | Bedeutung |
|---|---|
active | Subscription aktiv, weitere Abbuchungen folgen |
failed | Erstellung fehlgeschlagen, oder Abbuchung und Wiederholung sind beide gescheitert |
cancelled | Vom Händler mit sofortiger Wirkung gekündigt — keine weiteren Abbuchungen |
in_notice | Von der Kundschaft vor dem Enddatum gekündigt; die restlichen Abbuchungen folgen noch |
overdue | Eine Abbuchung schlug fehl und wird wiederholt; ein zweiter Fehlschlag führt zu failed |
{
"id": 5678,
"uuid": "ccdd3344",
"status": "active",
"start": "2026-01-01",
"end": null,
"valid_until": "2026-12-31",
"paymentInterval": "P1M",
"invoice": {
"currency": "CHF",
"referenceId": "SUB-2026-042",
"originalAmount": 1990,
"refundedAmount": 0,
"products": [
{
"name": "Monthly membership",
"price": 1990,
"quantity": 1,
"sku": null,
"vatRate": "8.1",
"description": ""
}
],
"discount": {
"code": null,
"amount": 0,
"percentage": null
},
"custom_fields": []
},
"contact": {
"id": 1234,
"uuid": "aabb1122",
"firstname": "Jane",
"lastname": "Doe",
"email": "buyer@example.com"
}
}Auszahlungs-Events
Auszahlungs-Events beschreiben Geld, das Ihr FlowAlp Pay Guthaben Richtung Bankkonto verlässt. Zentrale Felder: uuid, mode, object (immer payout), amount, total_fees, currency (ISO 4217), date, statement (Verwendungszweck), payer (Auslöser der Auszahlung), status, destination (z. B. Bankkonto mit IBAN), transfers (enthaltene Transaktionen und Gebühren), merchant und is_manual_payout.
| Status | Bedeutung |
|---|---|
processing | Die Auszahlungsdatei wurde an die Bank übergeben |
sent | Auszahlung erfolgreich an die Bank übermittelt |
failed | Auszahlung fehlgeschlagen und von der Bank retourniert |
Für die internen Auszahlungszustände initiated, pending und under-review werden keine Webhooks gesendet — das erste Event, das Sie erhalten, ist processing.
{
"uuid": "AABB1122",
"mode": "LIVE",
"object": "payout",
"amount": 29390,
"total_fees": 610,
"currency": "CHF",
"date": "2026-07-28",
"statement": "Alpina Sport AG Thun",
"status": "sent",
"is_manual_payout": false,
"destination": {
"type": "bank_account",
"iban": "CH00 0000 0000 0000 0000 0",
"account_holder": "Alpina Sport AG"
},
"transfers": [
{
"type": "payout-fee",
"amount": -10,
"date_time": "2026-07-28T05:00:00+00:00",
"items": [
{ "type": "payout-fee", "amount": -10 }
],
"transaction": {}
},
{
"type": "transaction",
"amount": 29400,
"date_time": "2026-07-27T13:44:30+00:00",
"items": [
{ "type": "transaction", "amount": 30000 },
{ "type": "transaction-fee", "amount": -600 }
],
"transaction": {
"type": "transaction",
"uuid": "1122aabb",
"amount": 30000,
"currency": "CHF",
"reference_id": "ORDER-975382"
}
}
]
}Mit HTTP 200 quittieren
Antworten Sie mit einem 2xx-Status innerhalb von 20 Sekunden. Jede andere Antwort — oder ein Timeout — gilt als fehlgeschlagene Zustellung und wird gemäss Ihrer Retry-Konfiguration wiederholt. Halten Sie den synchronen Teil minimal:
<?php
$rawBody = file_get_contents('php://input');
// 1. Verify the signature first (see the signature verification guide)
// 2. Queue the raw event for asynchronous processing
http_response_code(200);Events idempotent verarbeiten
- Wiederholungen bedeuten Duplikate: Deduplizieren Sie über Transaktions-
id(oderuuid) plusstatus, bevor Sie Änderungen anwenden. - Zustellungen können in falscher Reihenfolge ankommen — ignorieren Sie ein Event, wenn Ihr gespeicherter Zustand bereits final ist (z. B.
refundednachconfirmed). - Speichern Sie den rohen Payload und das Verarbeitungsergebnis, damit sich Vorfälle nachspielen und prüfen lassen.
- Verarbeiten Sie kein Event, bevor Sie seine Signatur geprüft haben.
Nächster Schritt: Sichern Sie Ihren Endpoint mit der Webhook-Signaturprüfung ab, bevor Sie live gehen.