Zum Inhalt

Webhooks & Callbacks

SecPaid bietet zwei unterschiedliche Benachrichtigungsmechanismen um Sie über abgeschlossene oder abgebrochene Zahlungen zu informieren. Das Verständnis des Unterschieds ist entscheidend für eine robuste Integration.

Übersicht

Mechanismus Typ Ausgelöst durch Empfänger Anwendungsfall
callback_url Browser-Redirect Browser des Kunden Kunde + Ihr Frontend Erfolgs-/Abbruch-Seite anzeigen
payment_endpoint Server-zu-Server POST SecPaid Backend Ihr Backend-Server Zuverlässige Zahlungsbestätigung für Auftragsabwicklung
sequenceDiagram
    participant C as Kunden-Browser
    participant S as SecPaid
    participant F as Ihr Frontend
    participant B as Ihr Backend

    C->>S: Zahlung abschließen
    S->>B: POST an payment_endpoint (Server-zu-Server)
    S->>C: HTTP 302 Redirect
    C->>F: GET callback_url?pay_id=123&status=Success

Verwenden Sie immer payment_endpoint für die Auftragsabwicklung

Die callback_url ist ein Browser-Redirect — der Kunde kann seinen Browser schließen bevor er ausgelöst wird. Verlassen Sie sich niemals ausschließlich auf callback_url um eine Zahlung zu bestätigen. Verwenden Sie immer payment_endpoint für kritische Geschäftslogik.

callback_url (Browser-Redirect)

Was es ist

Eine URL zu der der Browser des Kunden weitergeleitet wird, nachdem er eine Zahlung abgeschlossen oder abgebrochen hat. Dies ist ein clientseitiger Redirect — er findet im Browser des Kunden statt.

Wie man es setzt

Sie können callback_url auf zwei Arten angeben:

Option A: Pro Link (im API-Call)

{
  "amount": 49.99,
  "callback_url": "https://ihreseite.de/zahlung/ergebnis"
}

Option B: Aus Ihrer Callback-URLs-Liste

Sie können mehrere Callback-URLs im Plattform-Dashboard konfigurieren:

  1. Navigieren Sie zu SettingsCallback URLs
  2. Fügen Sie Ihre URLs hinzu (z.B. https://ihrshop.de/payment/done, https://shop.example.com/secpaid/callback)
  3. Klicken Sie auf Save Settings

Dann referenzieren Sie diese per Index (0-basiert) in Ihren API-Aufrufen:

{
  "amount": 49.99,
  "callback_url": "0"
}

Dies verwendet die erste URL aus Ihrer konfigurierten Liste. Verwenden Sie "1" für die zweite, usw.

Redirect-Verhalten

Nach der Zahlung wird der Kunde mit angehängten Query-Parametern weitergeleitet:

Bei Erfolg:

https://ihreseite.de/zahlung/ergebnis?pay_id=12345&status=Success

Bei Abbruch (nur wenn Link cancellable ist):

https://ihreseite.de/zahlung/ergebnis?pay_id=12345&status=cancel

Query-Parameter

Parameter Typ Beschreibung
pay_id integer Die linktopay_id des Payment Links
status string Success oder cancel

Wichtige Hinweise

  • Der Redirect findet im Browser des Kunden statt — wenn er den Tab schließt, erhalten Sie ihn nicht
  • Der Kunde kann Query-Parameter manipulieren — vertrauen Sie dem nicht zur Zahlungsverifizierung
  • Verwenden Sie dies um eine "Danke"- oder "Zahlung abgebrochen"-Seite anzuzeigen
  • Wenn keine callback_url gesetzt ist, sieht der Kunde SecPaids Standard-Erfolgs-/Abbruch-Seite

payment_endpoint (Server-zu-Server Webhook)

Was es ist

Eine URL auf Ihrem Backend die SecPaid via HTTP POST aufruft nachdem eine Zahlung abgeschlossen wurde. Dies ist ein Server-zu-Server-Aufruf — zuverlässig und nicht abhängig vom Browser des Kunden.

Wie man es setzt

Sie können payment_endpoint auf drei Arten konfigurieren:

Option A: Kontoweiter Standard

Konfigurieren Sie eine Standard-Webhook-URL in Ihren SecPaid-Kontoeinstellungen (Attribut paymentEndpoint). Diese gilt für alle Links, sofern nicht pro Link überschrieben.

Option B: Pro Link (direkte URL)

Überschreiben Sie den Konto-Standard durch Angabe einer URL im API-Aufruf:

{
  "amount": 49.99,
  "payment_endpoint": "https://ihreseite.de/webhooks/secpaid"
}

Option C: Pro Link (Index-Referenz)

Falls Sie mehrere Webhook-URLs in Ihrem Konto konfiguriert haben, übergeben Sie einen 0-basierten Index:

{
  "amount": 49.99,
  "payment_endpoint": "0"
}

Mehrere Endpoints

Sie können Webhooks an mehrere URLs gleichzeitig senden, indem Sie kommaseparierte Werte übergeben:

{
  "payment_endpoint": "https://primary.de/webhook,https://backup.de/webhook"
}

Oder mischen Sie Indizes und URLs:

{
  "payment_endpoint": "0,https://analytics.de/hook"
}

Alle aufgelisteten Endpoints erhalten denselben POST. Dies ist nützlich, um Zahlungsbenachrichtigungen an mehrere Systeme zu senden (z.B. Bestellverwaltung + Analytics + Buchhaltung).

Gilt auch für callback_url

Das callback_url-Feld unterstützt ebenfalls kommaseparierte Werte und Index-Referenzen, allerdings wird nur die erste URL für den Browser-Redirect verwendet.

Payload-Struktur

Standard (unverschlüsselt) — application/x-www-form-urlencoded:

ResponseCode=1&data[pay_id]=12345&data[note]=Rechnung+%231234&data[amount]=49.99&data[user_id]=abc-def-123&data[status]=Success

Geparst als:

{
  "ResponseCode": 1,
  "data": {
    "pay_id": 12345,
    "note": "Rechnung #1234",
    "amount": 49.99,
    "user_id": "abc-def-123",
    "status": "Success"
  }
}
Feld Typ Beschreibung
ResponseCode integer Immer 1 für Webhook-Aufrufe
data.pay_id integer Die linktopay_id
data.note string Die recipient_note vom Link
data.amount number Der bezahlte Betrag (Gesamt)
data.user_id string Ihre interne User-ID
data.status string "Success" oder "cancel"

Verschlüsseltes Payload

Wenn Sie Verschlüsselung aktiviert haben, wird das Payload als JSON mit Content-Type: application/json gesendet:

{
  "data": ["<base64-kodierter AES-256-CBC verschlüsselter String>"]
}

Bei Split Links mit Verschlüsselung wird ein zweiter POST an dieselben Endpoints gesendet mit der verschlüsselten Split-Aufschlüsselung:

{
  "data": ["<base64-kodiertes verschlüsseltes Array der Zahlungszeilen>"]
}

Entschlüsselt:

[
  {"user_id": "ersteller-uuid", "user_token": null, "amount": 40.00, "service_fee": 1.16, "service_fee_psp": 0.29, "net_amount": 38.55, "pay_id": 12345, "payment_method": null},
  {"user_id": "empfaenger-uuid", "user_token": "tok_a", "amount": 30.00, "service_fee": 0.87, "service_fee_psp": 0.22, "net_amount": 28.91, "pay_id": 12345, "payment_method": null}
]

Siehe Verschlüsselung für die Entschlüsselung.

Wann es ausgelöst wird

Der payment_endpoint wird aufgerufen wenn:

  • Eine Kartenzahlung bestätigt wird (Zahlungsanbieter → SecPaid → Ihr Endpoint) — status: "Success"
  • Eine Banküberweisung von einem Admin genehmigt wird — status: "Success"
  • Ein Kunde die Zahlung abbricht (wenn der Link einen paymentEndpoint konfiguriert hat) — status: "cancel"

Er wird NICHT aufgerufen bei:

  • Link-Löschung
  • Erstattungen (aktuell kein Webhook)

Webhook verarbeiten

Ihr Endpoint sollte:

  1. Eine POST-Anfrage mit Content-Type: application/json akzeptieren
  2. Die pay_id gegen eine erwartete Zahlung verifizieren
  3. Die Zahlung verarbeiten (Bestellung erfüllen, Bestätigung senden, etc.)
  4. Eine beliebige HTTP 2xx-Antwort zurückgeben
// Beispiel: Laravel Webhook-Handler
Route::post('/webhook/secpaid', function (Request $request) {
    $data = $request->input('data');

    $order = Order::where('secpaid_pay_id', $data['pay_id'])->first();

    if ($order && $data['status'] === 'Success') {
        $order->markAsPaid($data['amount']);
    }

    return response()->json(['received' => true]);
});

Beide zusammen: Vollständiger Flow

So funktionieren beide Mechanismen in einer typischen Integration:

flowchart TB
    subgraph erstellung [Link-Erstellung]
        A[Ihr Server] -->|"POST /api/v2/createLink<br/>callback_url + amount"| B[SecPaid API]
        B -->|"pay_link"| A
    end

    subgraph zahlung [Zahlung]
        A -->|"Kunde weiterleiten"| C[Kunde]
        C -->|"Öffnet pay_link"| D[SecPaid Checkout]
        D -->|"Bezahlt"| E[Zahlungsanbieter]
    end

    subgraph benachrichtigung [Benachrichtigungen]
        E -->|"Zahlung bestätigt"| F[SecPaid Backend]
        F -->|"POST JSON Payload"| G["Ihr payment_endpoint<br/>(Server-zu-Server)"]
        F -->|"HTTP 302"| H["Kunden-Browser<br/>→ callback_url?status=Success"]
    end

Empfohlenes Setup

Anwendungsfall callback_url payment_endpoint
"Danke"-Seite anzeigen ✅ Erforderlich
Bestellungen erfüllen ✅ Erforderlich
Bestätigungs-E-Mail senden ✅ Erforderlich
UI in Echtzeit aktualisieren ✅ Optional
Vollständige Integration ✅ Beide setzen ✅ Beide setzen

Abbruch-Flow

Wenn ein Kunde einen stornierbaren Link abbricht:

  1. Kunde klickt "Abbrechen" auf der Checkout-Seite
  2. SecPaid leitet seinen Browser weiter zu: callback_url?pay_id=12345&status=cancel
  3. Der payment_endpoint wird bei Abbruch NICHT aufgerufen
sequenceDiagram
    participant C as Kunde
    participant S as SecPaid Checkout
    participant F as Ihr Frontend

    C->>S: Klickt "Abbrechen"
    S->>C: HTTP 302 zu callback_url
    C->>F: GET callback_url?pay_id=123&status=cancel
    Note over F: "Zahlung abgebrochen"-Seite anzeigen

Webhooks manuell auslösen

Wenn eine Webhook-Zustellung fehlschlägt oder Sie ihn erneut senden müssen, verwenden Sie den sendWebhookViaPayId-Endpoint:

curl -X POST https://app.secpaid.com/api/v2/sendWebhookViaPayId \
  -H "Content-Type: application/json" \
  -H "token: IHR_TOKEN" \
  -d '{"pay_ids": "12345,12346", "status": "Success"}'

Dies löst den payment_endpoint-Webhook für die angegebenen Pay-IDs erneut aus.

Fehlerbehebung

Problem Ursache Lösung
Webhook nicht erhalten payment_endpoint nicht konfiguriert In Kontoeinstellungen setzen
Callback nicht erhalten Kunde hat Browser geschlossen payment_endpoint für zuverlässige Benachrichtigungen verwenden
Falscher Status im Callback Kunde hat URL manipuliert callback_url nie zur Verifizierung vertrauen — immer payment_endpoint verwenden
Verschlüsseltes Payload nicht entschlüsselbar Falscher Encryption-Key EncryptionKey-Attribut in Kontoeinstellungen prüfen
Webhook erhalten aber pay_id unbekannt Race Condition oder Testdaten Gegen Ihre Bestell-Datenbank verifizieren