So integrieren Sie Canonical

Erfahren Sie, wie Sie mit dem Canonical-PSS-Treiber einen Zahlungsdienstleister über die Implementierung eines standardisierten Deposit-API-Vertrags mit B2CORE verbinden, einschließlich der B2CORE-seitigen Konfiguration, Webhooks, Polling und des Deposit-Status-Lebenszyklus.

Der Canonical-Treiber ermöglicht Ihnen, einen Zahlungsdienstleister (PSP) Ihrer Wahl über PSS mit B2CORE zu verbinden, selbst wenn B2CORE noch keinen dedizierten Treiber für diesen Anbieter bietet.

Warum den Canonical-Treiber verwenden

Die meisten Zahlungssysteme in B2CORE basieren auf einem dedizierten Treiber, der speziell für einen Anbieter entwickelt wurde. Der Canonical-Treiber verfolgt einen anderen Ansatz: Er definiert einen einzigen, standardisierten API-Vertrag — die Canonical Deposit API — den jeder Anbieter implementieren kann. B2CORE übernimmt dann Authentifizierung, den Deposit-Startablauf, Polling, Webhooks und den Status-Lebenszyklus auf einheitliche Weise, unabhängig davon, welcher Anbieter hinter dem Vertrag steht.

Der Canonical-Treiber ist nützlich, wenn Sie:

  • Einen bevorzugten oder hausinternen PSP ohne dedizierten B2CORE-Treiber verbinden möchten, ohne auf individuelle Entwicklung zu warten.
  • Die Markteinführungszeit verkürzen möchten, indem Ihr Anbieter einen dokumentierten, stabilen Vertrag statt einer individuellen Integration implementiert.
  • Die vollständige Kontrolle über die Anbieterseite behalten möchten, während B2CORE den Deposit-Workflow auf seiner Seite verwaltet.

Der Canonical-Treiber unterstützt derzeit Deposit-Abläufe. Um Deposits über Ihren Anbieter anzubieten, muss der Anbieter die in der untenstehenden OpenAPI-Spezifikation beschriebene Canonical Deposit API implementieren und die Verhaltensanforderungen auf dieser Seite einhalten.

OpenAPI-Spezifikation

Die Canonical Deposit API ist in der folgenden OpenAPI-Spezifikation definiert, die Authentifizierung, Anfrage- und Antwortschemas, Endpunkte und Statuscodes abdeckt. Laden Sie sie herunter, um den vollständigen Vertrag zu prüfen, den Ihr Anbieter implementieren muss:

canonical-deposit-api.yaml

Der Rest dieser Seite beschreibt die Verhaltensanforderungen, die B2CORE-seitige Konfiguration und Designentscheidungen, die die Spezifikation nicht ausdrücken kann. Lesen Sie beides zusammen, um ein vollständiges Bild der Integration zu erhalten.

B2CORE-Treiberanmeldedaten

Diese Felder werden auf der B2CORE-Seite (Back Office) konfiguriert und zur Authentifizierung bei der PSP-API verwendet. Vollständige Details zur JWT-Token-Erstellung und -Verifizierung finden Sie in der OpenAPI-Spezifikation.

FeldBeschreibung
API-Basis-URLHTTPS-Basis-URL der PSP-API.
App-IDEindeutige Händlerkennung. Wird als sub-Claim im JWT verwendet.
App-SecretGeheimer Schlüssel für HMAC-SHA256-Signierung. Base64-URL-kodiert, 32 Byte (43 Zeichen). Wird niemals in Anfragen gesendet — nur zum Signieren von Token verwendet.

B2CORE-Treiberkonfigurationsfelder

Diese Felder werden auf der B2CORE-Seite (Back Office) konfiguriert und steuern das Treiberverhalten. Sie sind nicht Teil der PSP-seitigen API.

Globale Parameter (globalParam1, globalParam2, globalParam3)

Drei konfigurationsbezogene Zeichenkettenfelder, die mit jeder authentifizierten Anfrage an den PSP gesendet werden.

  • Für POST-Endpunkte werden sie in den JSON-Anfragetext aufgenommen.
  • Für GET-Endpunkte werden sie als Abfrageparameter aufgenommen.

Diese stellen PSP-spezifische Werte wie Händler-ID, Kanal oder Projekt-ID dar. Die genaue Bedeutung hängt von der PSP-Implementierung ab. Der B2CORE-Administrator trägt sie bei der Einrichtung der Konfiguration ein.

Pflichtfelder (schreibgeschützt)

Typ: Mehrfachauswahl

Legt fest, welche Benutzerinformationsfelder im Zahlungsformular als schreibgeschützt (nicht bearbeitbar) angezeigt werden.

Ausgewählte Felder müssen bereits im B2CORE-Profil des Benutzers konfiguriert und gespeichert sein. Wenn ein ausgewähltes Feld im Profil fehlt, schlägt die Generierung des Zahlungsformulars mit einem Fehler für fehlende Felder fehl — der Benutzer kann nicht fortfahren, bis die Daten in seinem B2CORE-Profil ausgefüllt sind.

Die ausgewählten Felder bestimmen zusammen mit den Feldern aus Pflichtfelder (bearbeitbar), welche Benutzerdaten im startDepositUserInfo-Objekt, das in der POST /api/v1/deposits-Anfrage an den PSP gesendet wird, sinnvoll befüllt werden. Felder, die in keiner der beiden Listen ausgewählt sind, werden im Formular ausgeblendet und können als leere Werte gesendet werden.

Pflichtfelder (bearbeitbar)

Typ: Mehrfachauswahl

Legt fest, welche Benutzerinformationsfelder im Zahlungsformular als bearbeitbar angezeigt werden. Der Benutzer kann diese Felder direkt im Zahlungsformular ausfüllen oder ändern. Anders als bei Pflichtfelder (schreibgeschützt) besteht keine Anforderung, dass diese Felder bereits im B2CORE-Profil des Benutzers konfiguriert sind.

Prioritätsregel: Wenn ein Feld sowohl in Pflichtfelder (schreibgeschützt) als auch in Pflichtfelder (bearbeitbar) ausgewählt ist, wird es als schreibgeschützt angezeigt. Die schreibgeschützte Einstellung hat immer Vorrang.

E-Mail-Verhalten: E-Mail wird immer im Zahlungsformular angezeigt und immer im startDepositUserInfo gesendet, unabhängig davon, ob sie in einer der beiden Listen ausgewählt ist. Die Konfiguration steuert nur, wie sie angezeigt wird:

E-Mail ausgewählt inVerhalten
Keiner ListeWird als bearbeitbares Feld angezeigt
Pflichtfelder (bearbeitbar)Wird als bearbeitbares Feld angezeigt
Pflichtfelder (schreibgeschützt)Wird als schreibgeschütztes Feld angezeigt (Wert aus dem B2CORE-Profil)
Beiden ListenWird als schreibgeschütztes Feld angezeigt (schreibgeschützt hat Vorrang)

Standard-Synchronisierungsfrist

Typ: Auswahl
Standard: 4h

Maximale Dauer nach der Deposit-Erstellung, während der B2CORE den Deposit-Status abfragt. Nach Ablauf dieser Frist:

  • StatusSyncInProgress → das Deposit wird auf unexpected gesetzt.
  • StatusSyncUnexpected → das Deposit wird auf unexpected gesetzt.

Der Status unexpected erfordert eine manuelle Untersuchung durch einen Administrator über den LifecycleService.

Sicheres Fehlschlagen beim Start

Typ: Boolesch (derzeit fest auf yes eingestellt, keine Auswahl)

Legt fest, ob es sicher ist, ein Deposit als failed (terminal) zu markieren, wenn die Startanfrage auf einen unerwarteten Fehler trifft.

  • yes — wenn der PSP beim Deposit-Start einen Fehler zurückgibt und B2CORE sicher ist, dass das Deposit nicht auf der PSP-Seite erstellt wurde (wenn B2CORE beispielsweise nie eine Weiterleitungs-URL erhalten hat), kann das Deposit sicher auf failed gesetzt werden. Der Kunde hat kein Geld verloren.
  • no — selbst bei einem Fehler wird das Deposit mit einer nicht verifizierten externen ID auf in_progress gesetzt und abgefragt, da der PSP das Deposit trotz des Fehlers erstellt haben könnte.

Derzeit immer yes. Der typische Fall: Ohne eine Weiterleitungs-URL kann der Kunde die PSP-Zahlungsseite nicht abschließen, daher kann das Deposit nicht erfolgreich sein.

Vor dem Polling auf Webhook warten

Typ: Boolesch (derzeit fest auf yes eingestellt, keine Auswahl)

Steuert, ob B2CORE auf eine Webhook-Benachrichtigung wartet, bevor es mit dem Abfragen von GET /api/v1/deposits/{externalID} beginnt.

WertVerhalten
yesNach dem Deposit-Start wartet B2CORE bis zu 5 Minuten auf einen Webhook, bevor es mit dem Polling beginnt. Wenn innerhalb von 5 Minuten kein Webhook eintrifft, fährt B2CORE mit dem Standard-Polling fort.
noB2CORE beginnt sofort entsprechend dem standardmäßigen Backoff-Zeitplan mit dem Polling.

Begründung: Viele PSPs senden schnell eine Webhook-Benachrichtigung, wenn sich der Deposit-Status ändert. Das Warten auf den Webhook vor dem Polling reduziert die Anzahl unnötiger API-Aufrufe und hilft dabei, innerhalb von Ratenlimits zu bleiben. Das Zeitlimit von 5 Minuten stellt den Fortschritt auch sicher, wenn der Webhook verzögert wird oder verloren geht.

Ablauf der Testkonfiguration

Wenn ein Administrator in B2CORE auf Test Configuration klickt:

1. B2CORE generates a one-time JWT signed with appSecret
2. B2CORE → POST /api/v1/configuration/test (with Bearer JWT + globalParams)
3. If response status = "available" → test result: "available"
4. If response status = "failed" → test result: "failed" (with error from PSP)
5. If unexpected error (5xx, timeout, and similar) → test result: "unexpected"

Die Testkonfigurationsmethode ist die einzige Methode, bei der erwartet wird, dass ein Problem mit Anmeldedaten nicht 401 Unauthorized, sondern 200 OK mit einem Antworttext zurückgibt.

code und description werden dem B2CORE-Administrator angezeigt. Geben Sie daher saubere, nicht sensible Daten zurück.

Design des Webhook-Systems

Zwei Webhook-Kanäle

B2CORE unterstützt zwei Webhook-Kanäle pro Deposit:

KanalRegistrierungBeschreibung
AutomatischÜber notificationURL in der POST /api/v1/deposits-AnfrageImmer aktiv. B2CORE generiert die URL und übergibt sie an den PSP.
Durch Administrator konfigurierbarWird vom Administrator im B2CORE Back Office festgelegtOptional. Der Administrator kann eine separate Webhook-URL konfigurieren, an die der PSP Benachrichtigungen sendet (beispielsweise in der Administrationsoberfläche des PSP registriert).

Beide Kanäle führen in denselben B2CORE-Webhook-Handler → driver_transit-Speicher → Polling-Optimierungspipeline.

Webhook als Polling-Optimierung

Der Webhook ist nicht die Quelle der Wahrheit. Er ist eine Optimierung, die unnötige Polling-Anfragen reduziert.

PSP → B2CORE webhook handler → driver_transit (key-value store) → poller

So funktioniert es:

  1. Wenn ein Webhook eintrifft, speichert B2CORE ein Flag in driver_transit, das durch externalID gekennzeichnet ist.
  2. Der Poller prüft driver_transit, bevor er einen API-Aufruf durchführt:
    • Wenn ein Webhook-Flag für die externalID vorhanden ist, ruft B2CORE sofort GET /api/v1/deposits/{externalID} auf.
    • Wenn kein Flag vorhanden ist und weniger als 5 Minuten vergangen sind, wartet B2CORE (siehe Vor dem Polling auf Webhook warten).
    • Wenn kein Flag vorhanden ist und mehr als 5 Minuten vergangen sind, fährt B2CORE mit dem Standard-Polling fort.
  3. Wenn das Deposit einen terminalen Status erreicht (success oder failed), wird der driver_transit-Eintrag gelöscht.

Webhook-Payload

Die Webhook-Payload ist minimal (siehe den Webhook-Callback unter POST /api/v1/deposits in der OpenAPI-Spezifikation):

{
  "externalID": "550e8400-e29b-41d4-a716-446655440000",
  "status": "success"
}

Die Payload enthält die folgenden Felder:

  • externalID — entspricht der UUID aus der POST /api/v1/deposits-Anfrage.
  • status — einer von "success", "failed" oder "unprocessable".

Der Webhook sollte nur gesendet werden, wenn das Deposit in einen terminalen Status übergeht.

Deposit-Startablauf

Startanfrage

B2CORE initiiert ein Deposit durch Aufruf von POST /api/v1/deposits.

Die Anfrage enthält ein Feld returnURL — eine URL zu einer B2CORE-Frontend-Seite, auf die der Benutzer nach der Interaktion mit der PSP-Seite zurückgeleitet wird. Dies ist kein Webhook — es handelt sich ausschließlich um eine Browser-Weiterleitung.

Alle weiteren Details finden Sie in der OpenAPI-Spezifikation.

Zuordnung des Startergebnisses

Die PSP-Antwort wird wie folgt einer B2CORE-Aktion zugeordnet:

PSP-AntwortB2CORE-Aktion
PSP gibt eine Weiterleitungs-URL zurückAuf in_progress setzen
2xx mit einer Spezifikationsverletzung (beispielsweise keine Weiterleitungs-URL)Auf failed setzen
HTTP 4xx / 5xx / Timeout / NetzwerkfehlerAuf failed setzen

Alle Fehlerszenarien führen zu failed (nicht unexpected), da Sicheres Fehlschlagen beim Start auf yes gesetzt ist (siehe Sicheres Fehlschlagen beim Start): Ohne gültige Weiterleitungs-URL kann der Endbenutzer nicht mit der PSP-Zahlungsseite interagieren, sodass kein Geld verloren gehen kann.

Weiterleitungsablauf

Bei einem erfolgreichen Start erhält B2CORE eine Weiterleitungs-URL und leitet den Endbenutzer zur PSP-Zahlungsseite weiter:

sequenceDiagram
    participant B as B2CORE
    participant P as PSP
    participant U as End user

    B->>P: POST /api/v1/deposits
    P-->>B: 200 OK<br/>action.type: "redirect"<br/>action.redirect.url: "..."
    B->>U: Redirect end user to PSP payment page
    U->>P: Open PSP payment page
    U->>P: Complete payment
    P-->>U: Redirect to returnURL
    U->>B: Land on B2CORE "in progress" page
  • Die returnURL führt den Benutzer zurück zu einer B2CORE-Frontend-Seite, die anzeigt, dass das Deposit verarbeitet wird.
  • Nach dem Start beginnt B2CORE mit dem Polling- und Webhook-Ablauf (siehe Polling und Statussynchronisierung).
  • Derzeit ist "redirect" der einzige unterstützte Aktionstyp.

Polling und Statussynchronisierung

Polling-Backoff-Zeitplan

B2CORE verwendet progressiven Backoff, um GET /api/v1/deposits/{externalID} abzufragen:

Zeit seit Deposit-StartPolling-Intervall
0–15 MinutenJede Minute
15–60 MinutenAlle 3 Minuten
1–3 StundenAlle 5 Minuten
3–5 StundenAlle 10 Minuten
5+ StundenAlle 15 Minuten

Behandlung der Frist

Standardfrist: 4 Stunden nach der Deposit-Erstellung (konfigurierbar, siehe Standard-Synchronisierungsfrist).

Wenn die Frist überschritten wird, werden Zwischenstatus wie folgt aufgelöst:

Letztes Polling-ErgebnisB2CORE-Aktion
inProgressAuf unexpected setzen
Netzwerkfehler, 5xx, Parse-Fehler und ÄhnlichesAuf unexpected setzen

Der Status unexpected beendet das automatische Polling und erfordert eine manuelle Administratoraktion über den LifecycleService von B2CORE.

Webhook-Wartelogik

Wenn Vor dem Polling auf Webhook warten auf yes gesetzt ist (aktueller Standard, siehe Vor dem Polling auf Webhook warten):

flowchart TD
    A["t=0min: deposit created, redirect URL returned<br/>Poller scheduled but WAITS for webhook"] --> B{Webhook received<br/>before t=5min?}
    B -- yes --> C["Immediately poll<br/>GET /api/v1/deposits/{externalID}"]
    B -- "no (t=5min elapsed)" --> D["Begin standard polling<br/>(1-minute intervals initially)"]
    C --> E[Continue with standard<br/>polling backoff]
    D --> E
    E --> F[Continue until terminal status<br/>or deadline]

Zuordnung der Polling-Ergebnisse

Jedes Polling-Ergebnis von GET /api/v1/deposits/{externalID} wird einer internen B2CORE-Aktion zugeordnet:

PSP-AntwortstatusB2CORE-Aktion
"inProgress" + Frist nicht überschrittenPolling fortsetzen (Wiederholung)
"inProgress" + Frist überschrittenAuf unexpected setzen
"success"Auf success setzen, Polling beenden. finalAmount und finalCurrencyCode speichern
"failed"Auf failed setzen, Polling beenden. reason speichern
"unprocessable"Auf unexpected setzen, Polling beenden. reason speichern. Erfordert Administratoruntersuchung
HTTP 5xx / Timeout / Parse-FehlerAls unexpected-Polling-Versuch behandeln. Polling fortsetzen, wenn die Frist nicht überschritten ist
HTTP 404 mit X-Safe-To-Fail-After-SecondsPolling fortsetzen. Nach der angegebenen Zeit zuzüglich eines Sicherheitspuffers (5 Minuten), falls weiterhin 404, auf failed mit Grund „deposit redirect URL is expired“ setzen
HTTP 404 ohne den HeaderPolling fortsetzen. Warten, bis das Deposit auf der PSP-Seite erscheint oder die Synchronisierungsfrist überschritten wird

Deposit-Status-Lebenszyklus

Dieser Abschnitt beschreibt B2CORE-Deposit-Status. Informationen zur Zuordnung von PSP-Antwortstatus zu B2CORE-Status finden Sie unter Zuordnung des Startergebnisses und Zuordnung der Polling-Ergebnisse.

Vollständiges Statusdiagramm

flowchart TD
    created[created]
    post["POST /api/v1/deposits"]
    failed1[failed]
    inProgress1[in_progress]
    unexpected1[unexpected]
    poll["GET /api/v1/deposits/{externalID}<br/>(polling)"]
    retryIP["(in_progress)<br/>(retry)"]
    retryUX["(unexpected)<br/>(retry)"]
    success[success]
    failed2[failed]
    unprocessable["(unprocessable)<br/>(stop polling)"]
    inProgress2[in_progress]

    created --> post
    post --> failed1
    post --> inProgress1

    inProgress1 --> poll
    poll --> retryIP
    poll --> retryUX
    poll --> success
    poll --> failed2
    poll --> unprocessable

    retryIP --> inProgress2
    retryUX --> inProgress2
    unprocessable --> unexpected1
    unexpected1 -->|Manual recovery| inProgress2

Wiederherstellung aus dem Status unexpected

Ein Administrator kann diese manuellen Übergänge über den LifecycleService durchführen:

ÜbergangWann verwenden
unexpectedin_progressPolling wiederholen (beispielsweise nachdem ein PSP-Ausfall behoben wurde)
unexpectedsuccessNur wenn der letzte Polling-Versuch unprocessable war und der Administrator den Erfolg bestätigt
unexpectedfailedDer Administrator bestätigt, dass das Deposit fehlgeschlagen ist

Definitionen der Deposit-Status

Die folgende Tabelle definiert jeden B2CORE-Deposit-Status:

StatusGeschäftliche Bedeutung
in_progressDas Deposit wird verarbeitet. Deckt alle Zwischenzustände ab: ausstehende Banküberweisung, laufende 3DS-Verifizierung, Warten auf manuelle Prüfung auf der PSP-Seite, Interaktion des Kunden mit der PSP-Zahlungsseite und Ähnliches. Dies ist ein nicht terminaler Status — B2CORE setzt das Polling fort.
successDer Broker hat das Geld des Kunden erhalten. Der PSP hat bestätigt, dass die Gelder gutgeschrieben wurden. Die Felder finalAmount und finalCurrencyCode spiegeln den tatsächlich erhaltenen Betrag und die tatsächlich erhaltene Währung wider, die aufgrund von Gebühren oder Umrechnung vom ursprünglichen Antrag abweichen können.
failedDas Deposit wurde nicht durchgeführt. Der Kunde hat kein Geld verloren, und der Broker hat keine Gelder erhalten. Beispiele: Karte abgelehnt, Banküberweisung zurückgewiesen, Benutzer hat auf der PSP-Seite abgebrochen oder Weiterleitungslink abgelaufen.
unexpectedDas Deposit konnte nicht automatisch aufgelöst werden und erfordert eine manuelle Administratoraktion über B2CORE (siehe Wiederherstellung aus dem Status unexpected); das automatische Polling wurde beendet. Tritt bei einer Fristüberschreitung während in_progress auf oder wenn der PSP unprocessable meldet.

Zeitpunkt der Deposit-Erstellung

PSPs folgen einem von zwei Mustern für die Deposit-Erstellung:

MusterVerhaltenAuswirkung auf das Polling
Sofortige ErstellungDer PSP erstellt den Deposit-Datensatz bei POST /api/v1/deposits.GET /api/v1/deposits/{externalID} gibt unmittelbar nach dem Start ein Ergebnis zurück.
Verzögerte ErstellungDer PSP erstellt den Deposit-Datensatz erst, nachdem der Endbenutzer die PSP-Zahlungsseite abgeschlossen hat.GET /api/v1/deposits/{externalID} gibt 404 Not Found zurück, bis der Benutzer die Seite abgeschlossen hat.

Bei verzögerter Erstellung sollte der PSP mit der 404-Antwort den Header X-Safe-To-Fail-After-Seconds zurückgeben. Dieser Header teilt B2CORE mit, wie lange der Weiterleitungslink gültig ist. Nach redirect_time + header_value + safety_margin markiert B2CORE das Deposit als failed mit dem Grund „deposit redirect URL is expired“, falls das Deposit weiterhin 404 ist.

Wenn der Header fehlt, setzt B2CORE das Polling fort, bis das Deposit erscheint oder die Synchronisierungsfrist (standardmäßig 4 Stunden) überschritten wird. Dann wird das Deposit auf unexpected gesetzt.

Verhaltensanforderungen

Verteiltes Tracing

Alle HTTP-Anfragen von B2CORE an den PSP enthalten standardmäßige Tracing-Header gemäß der Spezifikation W3C Trace Context:

  • traceparent — enthält die Trace-ID, die übergeordnete Span-ID und Trace-Flags.
  • tracestate — anbieterspezifische Trace-Daten.

PSP-Implementierungen sollten diese Header für End-to-End-Beobachtbarkeit an ihre nachgelagerten Dienste weitergeben.

Währungssperre auf der PSP-Zahlungsseite

Wenn die Antwort zum Deposit-Start eine Weiterleitung zu einer PSP-Zahlungsseite enthält:

  • Die PSP-Seite darf nicht zulassen, dass der Endbenutzer den currencyCode in eine analoge, gleichwertige oder alternative Währung ändert.
  • Die auf der PSP-Seite angezeigte Währung muss genau der Währung entsprechen, die in der Deposit-Startanfrage gesendet wurde.
  • Wenn die PSP-Seite eine Währungsauswahl zulässt, muss die Währung vorausgewählt und gesperrt sein.

Empfehlung zur IP-Whitelist

Obwohl dies nicht durch die API-Spezifikation erforderlich ist, wird PSP-Implementierungen dringend empfohlen, auf ihrer Seite eine IP-Whitelist zu konfigurieren. Dies bietet zusätzlich zur JWT-Authentifizierung eine weitere Sicherheitsebene und beschränkt den API-Zugriff auf bekannte B2CORE-IP-Adressen.

Um den Canonical-Treiber in Ihrer Umgebung verfügbar zu machen, wenden Sie sich bitte an Ihren Account Manager. Geben Sie bitte genau an, wie und zu welchen Zwecken Sie den Canonical-Treiber einsetzen möchten, damit wir den Zugang entsprechend einrichten können.

Zuletzt aktualisiert am

Auf dieser Seite