Skip to main content
Migrieren Sie Ihre Integration von API v1 und v2 in zwei Durchgängen zu v3:
  • Teil 1, das Konzept. Lesen Sie dies zuerst. v3 ist eine Neugestaltung, keine Umbenennung: Wenn Sie alte Endpunkte eins zu eins abbilden, arbeiten Sie gegen die API. Zehn Minuten hier sparen Ihnen später Tage.
  • Teil 2, die API. Endpunkt-für-Endpunkt-Mapping, Anfragebeispiele, Zustandsautomaten und eine Migrations-Checkliste.
Basiert auf der Produktions-OpenAPI-Spezifikation (platform.swipelux.com/openapi.json). v1 und v2 bleiben aktiv und sind noch nicht als veraltet markiert; alle neuen Capability-, Empfänger-, Task- und Quoting-Funktionen erscheinen ausschließlich in v3. Abonnieren Sie das Webhook-Ereignis api.deprecation, um Abschaltmitteilungen zu erhalten.
Inhalt. Teil 1: 1.1 warum v3 existiert, 1.2 Objektmodell, 1.3 Bereitschaft pro Capability, 1.4 Task-Schleife, 1.5 Geldbewegung, 1.6 Zustandsautomaten, 1.7 Konventionen, 1.8 goldener Pfad. Teil 2: 2.1 Kunden, 2.2 Capabilities, 2.3 Tasks und Submissions, 2.4 Accounts, 2.5 Empfänger und Destinations, 2.6 Quotes und Transfers, 2.7 Webhooks, 2.8 Sandbox, 2.9 Legacy-Endpunkte, 2.10 Migrationsreihenfolge, 2.11 Stolperfallen-Checkliste.

Teil 1, das Konzept

1.1 Warum v3 existiert

v1 und v2 haben vier sich überschneidende Wege entwickelt, um einen Kunden zahlungsbereit zu machen: /rails, /banks, /accounts/applications und die Business-Oberfläche rail-applications, jede mit ihrem eigenen Statusvokabular. Die Dokumentenerfassung (/documents, KYC-Importe, Verification-SDK-Tokens) war losgelöst von dem, was sie eigentlich freischalten sollte. v3 fasst all dies in sechs Ressourcen zusammen: den Kunden plus fünf Dinge, die er besitzt:

1.2 Das Objektmodell

Zwei strukturelle Regeln, die Sie verinnerlichen sollten:
  1. Capabilities steuern alles. Accounts werden unter einer ready Capability bereitgestellt; Quotes werden gegen eine Capability bepreist. Onboarding heißt, die benötigten Capabilities auf ready zu bringen.
  2. Tasks können überall hängen. Eine Capability, ein Account oder ein laufender Transfer kann openTaskIds tragen. Wo immer Sie sie sehen, ist die Schleife dieselbe: Task lesen, Antworten übermitteln, auf Prüfung warten, das übergeordnete Objekt erneut lesen.

1.3 Bereitschaft gilt pro Capability, nicht pro Kunde

v1 verknüpfte die Bereitschaft von /rails mit einem kundenweiten KYC-Gate. In v3 gibt es keinen Kundenstatus: Ein Kunde kann stablecoin_transfers vollständig nutzen, während seine sepa-Capability noch offene Tasks hat. Capabilities mit gepoolten Accounts erreichen in der Regel schneller den Status ready als benannte, beginnen Sie also mit dem, was ready ist, statt auf alles zu warten. Wenn Ihr v1- oder v2-Code UI-Badges anhand des Verifizierungsstatus des Kunden anzeigt, schreiben Sie ihn um:
  • “Kann er auf X handeln?” wird zu Capability X status == "ready".
  • “Muss er etwas tun?” wird zu einem beliebigen Task mit Status action_required (die Capability zeigt typischerweise restricted mit statusReason.resolution: "complete_tasks").
  • “Warten wir auf Swipelux?” wird zu Tasks in_review, Capability pending.

1.4 Die Task-Schleife

Alles, was die alte Dokumenten- und KYC-Oberfläche tat, ist jetzt diese eine Schleife: Wichtige Eigenschaften:
  • Ein Task enthält requirements[], die einzelnen Anforderungen. Jede hat eine task-spezifische requirementId, einen stabilen key, der die Anforderung benennt (zum Beispiel Adressnachweis, deduplizieren Sie damit Ihre UI), und ein typisiertes request, das genau beschreibt, welche Eingabe erwartet wird (Text, Datum, Auswahl, Dokument, Attestierung usw.).
  • Das Übermitteln ist prüfungsgesteuert: Es verändert weder Capability- noch Account-Status direkt, das tut erst die Annahme. Eine Ausnahme: profile-Antworten schreiben beim Übermitteln direkt ins Kundenprofil durch (2.3). Nach dem Übermitteln pollen Sie den Task oder die übergeordnete Ressource.
  • taskRevision (Echo der revision des Tasks) ist ein Nebenläufigkeitsschutz: Hat sich der Task seit Ihrem Lesen geändert, lesen Sie neu und bauen Ihre Antworten neu auf.
  • absence ist eine vollwertige Antwort (“Ich habe das nicht, weil …”), verwenden Sie sie, statt Anforderungen offen zu lassen.

1.5 Geldbewegung

Ein Ablauf für Payins, Payouts und Stablecoin-Bewegungen. Es gibt keine Richtungsangabe, Sie erklären nie Payin gegenüber Payout. Die Ein- und Ausgangswährungsformen leiten eine schreibgeschützte direction am Quote und Transfer ab: fiat_to_stablecoin (Payin), stablecoin_to_fiat (Payout) oder stablecoin_move.

1.6 Ein Zustandsautomat pro Ressource

Jede statusführende Ressource hat ihr eigenes Enum, und jeder Nicht-Gut-Status trägt einen strukturierten Grund. Accounts, Applications und Transfers teilen die Form { code, message, actor, retryable }: Accounts und Applications zeigen sie als statusReason, Transfers als stateDetail. actor sagt, wer handeln muss (customer, developer, provider, network, swipelux), retryable sagt, ob ein erneuter Versuch helfen kann. Capabilities verwenden { code, resolution, message }, wobei resolution (complete_tasks, wait, contact_support, none) angibt, was die Capability weiterbringt. code-Werte sind ein offener, nur-erweiternder Katalog: Verzweigen Sie über resolution (oder actor plus retryable) und tolerieren Sie Codes, die Sie noch nie gesehen haben. Zustände, die dieser Leitfaden nicht durchspielt (rejected, suspended, disabled, failed, canceled), sind terminal oder support-getrieben; die Definitionen pro Ressource finden sich in der Spezifikation. Transfer im Detail:

1.7 Konventionen

Idempotenzregeln, die Sie vor dem Programmieren verinnerlichen sollten:
  • Ein Schlüssel mit abweichendem Body ergibt 409 idempotency_conflict, solange der Schlüssel aufbewahrt wird (mindestens 7 Tage), planen Sie also nie eine Wiederverwendung. Erzeugen Sie pro logischem Vorgang eine neue UUID und speichern Sie sie mit Ihrem Job.
  • Der Replay umfasst auch Fehler: Endete die ursprüngliche Anfrage in einem terminalen 4xx, liefert derselbe Schlüssel plus Body dieselbe Problemantwort erneut.
  • Zwei gleichzeitige Anfragen mit demselben Schlüssel: Eine gewinnt, die andere erhält 409. Wiederholen Sie den Verlierer, nachdem der Gewinner beendet ist; der Replay liefert die ursprüngliche Antwort.

1.8 Der goldene Pfad


Teil 2, die API

2.1 Kunden

Erstellen, unterschieden nach type (beispielhafte Werte, Feldnamen laut Spezifikation):
  • Die Erstellung ist progressiv: { "type": "individual" } allein ist ein gültiger Create. Fehlende Angaben machen den Kunden nie ungültig, sie erscheinen später als Intake-Tasks an den Capabilities, die sie benötigen.
  • Unternehmen führen business plus Registrierungsdaten. Das Shareholder-CRUD aus v1 wird auf Related Parties abgebildet, erweitert um Directors, Officers und Owners: Erstellen Sie sie inline bei der Kundenerstellung (jede erhält eine stabile rp_-Id) oder verwalten Sie sie über die dedizierten Related-Parties-Endpunkte.
  • Kein Kunden-status-Feld, siehe 1.3.
  • Bestehende Kunden werden übernommen: Kunden, die auf v1 oder v2 erstellt wurden, sind unter derselben Id über v3-Endpunkte erreichbar. Das v3-Lesen ist eine bereinigte Ansicht, Legacy-Werte, die die v3-Validierung nicht bestehen, fehlen. Nach Ihrem ersten v3-Write wird diese Ansicht dauerhaft: fehlende Werte kommen nicht von selbst zurück. Reichern Sie also frühzeitig an, planen Sie einen einmaligen Durchgang ein, der das vollständige Profil aus Ihren eigenen Datensätzen per PATCH einspielt, bevor Sie sich auf v3-Reads verlassen. v1-metadata ist ein separater Namespace und wird nicht übernommen, setzen Sie sie auf v3 erneut.
  • externalId ist erstklassig und eindeutig über alle Ihre Kunden in v3, pro Umgebung (409 duplicate_external_id). Das Archivieren eines Kunden gibt seine externalId nicht frei, leeren Sie sie per PATCH vor DELETE, wenn Sie sie wiederverwenden möchten.
  • DELETE ist eine Archivierungskaskade (keine Wiederherstellung; Ids werden nie wiederverwendet). Sie wird mit 409 customer_has_active_resources plus blockingResources[] blockiert, solange ein nicht archivierter Account oder ein laufender Transfer existiert.
  • PATCH-Merge-Regeln: explizites null leert ein nullbares Feld, Arrays ersetzen komplett (außer inline Related Parties, die per Id upgeserted werden), metadata-Schlüssel werden gemerged. Vollständige Schemata und Listenfilter finden sich in der OpenAPI-Spezifikation.

2.2 /rails, /banks, Applications werden zu Capabilities

  • Eine Capability besteht aus method (ach, wire, rtp, pix, sepa, swift, spei, pse, transfers_3_0, faster_payments, sepa_instant, uaefts, card, stablecoin_transfers usw.) plus accountType (pooled oder named, null für Nicht-Bank-Methoden) plus directions (payin oder payout). Die öffentliche capabilityId ist das qualifizierte Paar (sepa_pooled, ach_named) oder die reine Methode für card und stablecoin_transfers.
  • Jede Capability-Anfrage erzeugt eine Application, den Datensatz pro Versuch unter .../capabilities/{capabilityId}/applications (plus /{applicationId}/history), mit eigenen Status (1.6) und statusReason. Sie ist der Prüfpfad einer Anfrage; im Alltag pollen Sie die Capability selbst.
  • capabilities/supported liefert Verfügbarkeit (available, beta oder disabled), Berechtigung und angebotene Institute. Die Bankauswahl geschieht zum Anfragezeitpunkt über das optionale institutions-Array, es gibt keine separate /banks-Ressource. Wird es weggelassen (oder [] gesendet), werden alle Standardinstitute ausgewählt; isDefault: true ist ein kunden- und capability-spezifisches Flag, keines global. Eine nicht leere Liste überschreibt die Standards, und eine bankgestützte Capability ohne anwendbaren Standard liefert 422 capability_institutions_required. Instituts-Ids sind opak, tolerieren Sie neue.
  • stablecoin_transfers wird bei der Kundenerstellung automatisch gewährt und ist von Geburt an ready (wird also nie angefordert und ist nicht kündbar). card ist nur für Individuen.
  • openTaskIds an der Capability ist Ihr “was tue ich als Nächstes”-Zeiger. Offen bedeutet action_required oder in_review, und die Aggregation umfasst gemeinsame Tasks auf Kundenebene, die über aktive Abhängigkeiten erreichbar sind.
  • cancel funktioniert nur aus pending oder restricted und ohne blockierende Ressourcen, sonst 409 capability_not_cancelable, dessen Problem-Body die blockingResources auflistet. Ein erneutes Anfordern nach dem Abbrechen ist ein frisches Create mit einem neuen Idempotency-Key.
  • Pollen Sie das GET. Der Capability-Status aktualisiert sich beim Lesen; pollen Sie GET .../capabilities/{capabilityId} oder abonnieren Sie capability.status_changed, cachen Sie nicht.
  • Das Anfordern einer Methode kann verwandte Methoden sofort verfügbar machen, behandeln Sie Capabilities als Menge, die Sie neu lesen, nicht als einzelne Zeile, die Sie verfolgen.
  • Verwenden Sie tasks-preview, um Onboarding-Anforderungen vor dem Absetzen einer Anfrage anzuzeigen.
  • Verifizierung ist nicht einmalig: Neue Tasks können an einer bereits ready Capability auftauchen (periodische oder ereignisgesteuerte Re-Verifizierung). Halten Sie die Task-Schleife für die gesamte Kundenlebensdauer aktiv, nicht nur beim Onboarding.

2.3 Dokumente und KYC werden zu Tasks und Submissions

Hinweis zur Benennung. Diese Endpunkte wurden kurz als requirements und fulfillments ausgeliefert. Seit dem 02.08.2026 sind die öffentlichen Namen tasks und submissions. Die Umbenennung betraf nur die Ressourcen und Endpunktpfade, das requirements[]-Array innerhalb eines Tasks und seine requirementId behalten diese Namen.
Jede alte Dokumentenoberfläche wird auf denselben Ersatz abgebildet: lesen Sie GET /v3/customers/{customerId}/tasks, antworten Sie mit POST .../tasks/{taskId}/submissions. Rund um diese Schleife:
  • Rohdateispeicher: POST/GET/DELETE /v3/customers/{customerId}/documents (plus /{documentId}), einmal mit Ihrem API-Schlüssel hochladen, dann Dokument-Ids in Submission-Antworten referenzieren. Dies ersetzt jeden Upload-Token und jedes Direct-Upload-Intake.
  • Neu: GET /v3/tasks (händlerweiter Posteingang), GET /v3/transfers/{transferId}/tasks, GET .../tasks/{taskId}/history, GET .../tasks/{taskId}/submissions (plus /{submissionId}).
Submission (beispielhaft):
  • Antworttypen: profile, text, date, single_select, multi_select, boolean, attestation, document, resource_reference, absence. Das request-Objekt jeder Anforderung sagt, welchen Typ sie erwartet.
  • Eine Submission muss jede aktionierbare Anforderung in der aktuellen Runde beantworten, mit der exakten taskRevision, die Sie gelesen haben. Teilsubmissions werden abgelehnt.
  • profile-Antworten schreiben durch: Sie aktualisieren das Kundenprofil über den normalen Validierungspfad und bewerten sofort jede Capability neu, die auf dieselbe Intake-Arbeit verweist. Geschwister-Intake-Tasks, deren Anforderungen alle erfüllt sind, schließen automatisch.
  • Anforderungen können alternative Gruppen bilden (alternativeKey): reichen Sie genau eine aus der Gruppe ein.
  • changes_requested erhöht remediationRound und trägt reviewFeedback. Lesen Sie den Task erneut und übermitteln Sie erneut mit einem frischen Idempotency-Key.
  • Gehostete Verifizierungs-URLs erscheinen nur im kundenspezifischen Task-Detail (GET /v3/customers/{customerId}/tasks/{taskId}) und nur, solange die Session aktionierbar ist; Listen und GET /v3/tasks/{taskId} sind bewusst URL-frei.
  • Nutzungsbedingungen sind ebenfalls ein Task: openTaskIds kann einen Task mit category: "terms_of_service" enthalten, dessen gehostete Akzeptanzseite auf demselben Weg verlinkt wird (nur kundenspezifisches Detail). Generische Submissions können Bedingungen nicht annehmen, und eine KYC-Freigabe impliziert nie eine Annahme der Bedingungen.
  • Tasks sind pro Capability abgegrenzt, daher kann die “gleiche” Anforderung (z. B. Adressnachweis) einmal pro Capability erscheinen. Deduplizieren Sie in Ihrer UI über den key der Anforderung.
  • Keine Übersetzungsebene: Das Posten auf /v1/documents entsperrt keine v3-Capabilities. Sobald ein Kunde auf v3 ist, steuern Sie alle Anforderungen über Tasks.

2.4 Accounts und Wallets

Erstellen, unterschieden nach origin plus type. Ausgestellte Bankkonten nehmen eine einzelne method; externe Bankkonten nehmen stattdessen ein methods-Array (das Senden von method dort wird abgelehnt):
  • country bei ausgestellten Bankkonten ist optional (methodenabhängig voreingestellt); bei externen Bank-Konten geben Sie es explizit an. Wallet-Konten führen überhaupt kein Land.
  • settlement.accountId ist bei ausgestellten Bankkonten erforderlich: Er benennt das ausgestellte Wallet-Konto, das die abgewickelten Gelder aus Einzahlungen auf das Bankkonto empfängt.
  • Ausgestellte Konten stellen details (IBAN oder Routing plus Kontonummer oder Adresse) bereit, versioniertes routing (Einzahlungskoordinaten können rotieren, rendern Sie immer den neuesten Lesestand), fees, balances.
  • Netzwerke: polygon, ethereum, base, arbitrum, optimism, bsc, avalanche.
  • Das Capability-Gate gilt nur für ausgestellte Konten: Die Erstellung gegen eine nicht bereite Capability schlägt mit einem capability-codierten Fehler fehl, fordern Sie die Capability zuerst an (2.2). Externe Konten benötigen keine Capability (und keine Kundenzustimmung); sie erhalten nur eine Request-Schema- und Bankdaten-Validierung.
  • Ausgestellte Bankkonten werden provisioning mit details: null geboren. Pollen Sie das Konto oder beobachten Sie account.status_changed, bis ready.
  • DELETE archiviert, löscht nie hart. Konten, die von laufenden Transfers referenziert werden, liefern 409 account_has_active_transfers. Wiederholen Sie, nachdem diese Transfers einen terminalen Status erreicht haben.
  • Neu in v3: Rules, stehende Anweisungen an einem ausgestellten Wallet-Konto (POST/GET /v3/customers/{customerId}/rules, GET/PATCH/DELETE .../rules/{ruleId}), die eingehende Gelder automatisch an ein anderes Konto oder eine Wallet-Destination weiterleiten. Kein v1- oder v2-Äquivalent.

2.5 Empfänger und Destinations

v2 hatte kein Empfänger-Konzept. Wenn Sie auf v2 sind und an Dritte auszahlen, ist dies eine neue Oberfläche, keine Umbenennung.
  • Recipient ist das Wer: individual (Vor- und Nachname) oder business (Firmenname), mit erforderlicher relationship (employee, contractor, vendor, subsidiary, merchant, customer, landlord, family, other). Recipients und Destinations sind ausschließlich für Dritte. Eine First-Party-Auszahlung verwendet keinen Recipient: Zielen Sie eines der eigenen acc_-Konten des Kunden als destinationId des Quotes an (2.6).
  • Destination ist das Wohin: pro Methode typisiert, sepa (IBAN, BIC optional), ach oder wire (Routing plus Konto), swift (vollständige Koordinaten plus optionale Zwischenbank), spei (clabe), pse, transfers_3_0 (cbu) usw., sowie Wallet-Destinationen. Jede Destination hat ihren eigenen Status. Beobachten Sie destination.status_changed.
  • Fiat-Destinations erfordern die vollständige address des Recipients (Straße, Stadt, Postleitzahl, Land) vor der Erstellung. Fehlende Angaben schlagen mit 422 recipient_address_required fehl. Wallet-Destinationen überspringen die Adresse, verlangen aber ownership auf oberster Ebene (self_custodied oder custodial mit Custodian-Namen).
  • Die Genauigkeit des Empfängernamens zählt: Empfangende Banken gleichen den rechtlichen Namen des Kontos ab. Senden Sie den exakten rechtlichen Vor- plus Nachnamen oder Firmennamen, keinen Anzeige-Spitznamen.
  • Feldschemata für Destinations pro Methode finden sich in der OpenAPI-Spezifikation.

2.6 Quotes und Transfers

  • destinationId nimmt eine acc_-Id (kundeneigenes Konto) oder eine dst_-Id (Empfänger-Destination). Fiat-finanzierte Quotes (Payins) müssen auf ein acc_-Konto zielen, ein dst_-Ziel bedeutet immer eine Auszahlung (422 quote_direction_invalid sonst).
  • externalId auf Quotes und Transfers ist eine nicht eindeutige Korrelationsreferenz (in Reads gespiegelt, in Listen filterbar). Die Eindeutigkeit pro Umgebung (2.1) gilt nur für die externalId des Kunden.
  • Führen Sie einen Quote genau einmal aus, vor expiresAt. Ein abgelaufener Quote schlägt mit 409 quote_expired fehl, eine zweite Ausführung mit 409 quote_already_executed (das Problem enthält die existierende transferId).
  • Das Stornieren von Transfers wird noch nicht unterstützt: POST .../cancel liefert in jedem Zustand 409 transfer_not_cancelable. Aktuelle canceled Transfers stammen aus dem Ablaufen des Finanzierungsfensters eines unfinanzierten Payins, nicht von diesem Endpunkt.
  • Payins starten in awaiting_funds: Zeigen Sie GET .../instructions dem Zahler an, Bankkoordinaten plus Referenz- oder Verwendungszweck-Code für Fiat, Einzahlungsadresse für Krypto. Der Referenz-Code ist, wie die Einzahlung zugeordnet wird. Zeigen Sie ihn immer an.
  • state plus stateDetail für maschinenlesbare Sub-Zustände; action_required bedeutet, dass ein Compliance-Task angehängt ist (openTaskIds, GET .../tasks), antworten Sie über Submissions.
  • Auf ausgestellten Konten erkannte eingehende Einzahlungen erscheinen als Transfers mit origin: "inbound_deposit" (statt "quoted").
  • Zahlungsnetzwerk-Referenzen sind unter references konsolidiert: transactionHash, traceNumber, imad, uetr, explorerUrl, returnedTransferId.
Übersetzung des v1-Status: Zwei Migrationswarnungen:
  • Transfers wechseln nicht zwischen Versionen. Auf v1 oder v2 erstellte Transfers sind aus v3 nicht lesbar. Die Liste lässt sie aus und GET /v3/transfers/{transferId} liefert 404. Stellen Sie zuerst die Erstellung um, behalten Sie den v1-Lesepfad, bis diese Transfers terminale Zustände erreichen, und entfernen Sie ihn dann.
  • Keine Token-Swaps. stablecoin_move erfordert dieselbe Ein- und Ausgangswährung: USDC zu USDT schlägt mit 422 recipient_destination_invalid und einem currency_mismatch-Feldfehler fehl. Dasselbe Netzwerk auf beiden Seiten, kein Bridging, und Wallet-zu-Wallet-Bewegungen unterstützen derzeit nur gebührenfreie Zustellung: Ein Quote, dessen Plattform- oder Entwicklergebühr ungleich Null ist, schlägt mit 422 amount_not_deliverable fehl.

2.7 Webhooks

Ereigniskatalog: customer.created, customer.updated, customer.archived, capability.created, capability.status_changed, application.status_changed, recipient.status_changed, destination.status_changed, account.created, account.status_changed, account.details_changed, transfer.created, transfer.state_changed, api.deprecation.
  • GET /v3/webhooks/portal liefert eine gehostete Management-Portal-URL für Zustellprotokolle, Wiederholungen und manuelle Replays.
  • transfer.created wird derzeit im alten v1-Payload-Format ausgeliefert (der v3-Envelope wird aktiv, wenn v1-Webhooks abgeschaltet werden). Behandeln Sie es rein als Hinweis und rufen Sie den Transfer per GET ab; bauen Sie nicht auf seinen Body.
  • Ereignisse sind Hinweise: Rufen Sie beim Empfang die Ressource ab und handeln Sie nach dem Read. Bauen Sie den Zustand niemals auf Ereignisdaten oder Reihenfolgen auf. Zustellung ist mindestens einmal und kann verzögert oder umgeordnet sein. Deduplizieren Sie nach Event-Id und holen Sie verpasste Ereignisse mit dem inklusiven updatedAfter-Filter jeder Liste nach.
  • Abonnieren Sie api.deprecation, den maschinellen Kanal für Versionsabschaltungen.
  • Kein task.*-Ereignis heute: Pollen Sie nach dem Übermitteln den Task oder seinen übergeordneten Datensatz.

2.8 Sandbox

Gleiche Basis-URL; der Sandbox-API-Schlüssel wählt die Umgebung. Die v3-Sandbox simuliert die Prüfschleife von Anfang bis Ende: Erstellen Sie einen Task, reichen Sie dagegen ein, reviewen Sie ihn auf accepted oder rejected und beobachten Sie, wie die Capability entsperrt wird. Proben Sie Ihre Remediation-UX vor der Produktion. Sowohl in der Sandbox erstellte Tasks als auch die regulären Intake-Tasks, die auf angeforderten Capabilities erscheinen, können auf diese Weise geprüft werden; wie in der Produktion feuern keine Task-Webhooks, pollen Sie (2.7).

2.9 Legacy-Endpunkte ohne v3-Ersatz

Diese haben keinen v3-Ersatz. Die meisten bleiben unverändert auf v1 (behalten Sie Ihre bestehenden Aufrufe bei); zwei werden komplett stillgelegt (siehe Verwendung): Jeder andere öffentliche v1- oder v2-Endpunkt erscheint in einer der Mapping-Tabellen oben.

2.10 Vorgeschlagene Migrationsreihenfolge

Jeder Schritt lässt sich unabhängig ausliefern; v1 oder v2 und v3 laufen parallel gegen dieselbe Kundenbasis. Proben Sie jeden Schritt gegen Ihren Sandbox-Schlüssel (2.8), bevor Sie ihn in der Produktion wiederholen.
1

Grundgerüst

Idempotency-Key für alle wirksamen Anfragen (POST, PATCH, PUT, DELETE; Sandbox-Endpunkte ausgenommen); Geld als Strings; Cursor-Paginierungs-Helfer.
2

Webhooks

Registrieren Sie v3-Endpunkte pro Ereignis, einschließlich api.deprecation. Die Single-Endpoint-Konfiguration von v1 ist eine separate Oberfläche, lassen Sie sie stehen; beide laufen parallel bis zum Drain in Schritt 9.
3

Profilanreicherung

PATCH /v3/customers/{id} mit dem vollständigen Profil, das Sie haben (v1 hat weniger erfasst, als v3 offenlegt), und setzen Sie metadata neu. Machen Sie dies bewusst zum ersten v3-Write pro Kunde: Er füllt die bereinigte Ansicht, bevor diese Ansicht dauerhaft wird (2.1).
4

Reads

Richten Sie Kunden-, Capability- und Account-Reads auf v3; schreiben Sie die Logik zum Kundenstatus gemäß 1.3 um. Erst nach Schritt 3, nicht angereicherte Reads liefern Legacy-invalide Felder als abwesend zurück.
5

Onboarding-Writes

Erstellen Sie über POST /v3/customers; fordern Sie Capabilities an, statt /rails, /banks oder Applications; bauen Sie die Task-Schleife (größte neue UI-Arbeit, tasks-preview hilft, Anforderungen vorab anzuzeigen). Ab hier hören Sie auf, /v1/documents für v3-gesteuerte Kunden zu posten, sie entsperren keine Capabilities (2.3).
6

Konten

Über v3 ausstellen; Imports auf origin: external umstellen.
7

Auszahlungen

Recipients plus Destinations, dann Quote und Transfer.
8

Einzahlungen

Quote, Transfer, Instructions; zeigen Sie den Referenz-Code weiter an.
9

Drain

Transfers wechseln nicht zwischen Versionen (2.6). Behalten Sie den v1- oder v2-Lesepfad und den v1-Webhook-Endpunkt für dort erstellte Transfers, lesen Sie doppelt, bis sie terminale Zustände erreichen, und entfernen Sie dann den alten Client und die v1-Webhook-Konfiguration.

2.11 Stolperfallen-Checkliste

  • Frische UUID pro logischem Vorgang, mit Ihrem Job gespeichert und bei Wiederholung wiederverwendet; niemals einen Schlüssel mit geändertem Body wiederverwenden (409 idempotency_conflict). Sandbox-Endpunkte sind vom Header ausgenommen.
  • Reichern Sie bestehende Kunden an (PATCH das vollständige Profil, metadata neu setzen, sie wird nicht übernommen) vor jedem anderen v3-Write, der erste v3-Write macht die bereinigte Ansicht dauerhaft.
  • externalId ist pro Umgebung eindeutig und wird nicht durch Archivierung freigegeben, leeren Sie sie per PATCH vor DELETE, wenn Sie sie wiederverwenden möchten.
  • Es gibt kein Kunden-status-Feld, leiten Sie die Bereitschaft pro Capability ab.
  • action_required und in_review bedeuten beide einen offenen Task.
  • Submissions sind prüfungsgesteuert (Übermitteln ist nicht dasselbe wie entsperrt) und müssen jede aktionierbare Anforderung mit der exakten taskRevision beantworten. Bei Nichtübereinstimmung erneut lesen und neu aufbauen.
  • Es gibt kein task.*-Webhook, pollen Sie den Task (oder sein übergeordnetes Objekt) nach jedem Übermitteln.
  • Wiederholung bei changes_requested bedeutet: Task erneut lesen, frische Antworten, frischer Idempotency-Key.
  • Das Posten auf /v1/documents entsperrt niemals eine v3-Capability, sobald ein Kunde auf Tasks ist, treiben Sie jede Anforderung über Tasks.
  • Neue Tasks können an einer bereits ready Capability erscheinen, halten Sie die Task-Schleife nach dem Onboarding weiterhin aktiv, nicht nur währenddessen.
  • Capability-cancel funktioniert nur aus pending oder restricted ohne blockierende Ressourcen (409 capability_not_cancelable); erneutes Anfordern nach dem Abbrechen ist ein frisches Create mit einem frischen Idempotency-Key.
  • Die Capability muss ready sein, bevor Konten unter ihr ausgestellt oder gegen sie Quotes erstellt werden.
  • Ein Quote hat einen Betrag auf genau einer Seite; kein Richtungsfeld; genau einmal vor expiresAt ausführen (409 quote_expired oder 409 quote_already_executed).
  • Stablecoin-Bewegungen sind nur gleichwährungs- und gleichnetzwerk-basiert (USDC zu USDT schlägt 422 fehl); Wallet-zu-Wallet unterstützt nur gebührenfreie Zustellung.
  • DELETE archiviert, löscht nie hart. Konto-Löschungen werden von laufenden Transfers blockiert (409 account_has_active_transfers); Kunden-Löschungen zusätzlich durch jedes nicht archivierte Konto (409 customer_has_active_resources, blockingResources[] benennt sie).
  • v1- oder v2-Transfers sind für v3-Reads unsichtbar (Liste lässt aus, GET liefert 404), doppelt lesen bis zum Drain, dann alte Pfade entfernen.
  • Einzahlungs-routing und Instructions können rotieren, immer den neuesten GET rendern und immer den Referenz-Code anzeigen.
  • Webhooks sind Hinweise; GET ist die Wahrheit, deduplizieren Sie nach Event-Id, holen Sie verpasste Ereignisse mit updatedAfter nach.

Nächster Schritt

Beginnen Sie bei Schritt 1 der Migrationsreihenfolge (2.10), Idempotency-Keys, Geld als Strings, Cursor-Paginierung, und proben Sie jeden Schritt gegen Ihren Sandbox-Schlüssel (2.8), bevor Sie ihn in der Produktion wiederholen.