Mit Treasury Geldbewegungen durchführen
Lernen Sie die Nutzung von SetupIntent und PaymentMethods sowie die Verifizierung von Bankkonten mit Stripe Treasury.
Homebox ist ein fiktives vertikales SaaS-Unternehmen, das Software für haushaltsnahe Dienstleister, wie Anbieter von Heizungs-, Lüftungs- und Klimaanlagen, Reinigungsunternehmen und Klempnerfirmen herstellt. Diese Integration geht auf einige grundlegende Geldübertragungen mithilfe der Treasury-Endpoints der Stripe API ein. Informationen dazu, wie das Unternehmen ein Treasury-Finanzkonto einrichtet und Zahlungskarten ausgibt, finden Sie unter Finanzkonten und Karten mit Treasury einrichten.
Externe Bankkonten verwenden
Stripe Treasury bietet Plattformen zahlreiche API-Endpoints für Kontoerstellung und Geldübertragungen. So können Gelder der verbundenen Konten gespeichert, verwaltet und bewegt werden. Plattformen können Gelder zu einem Finanzkonto hinzufügen und Gelder zwischen den Treasury-Finanzkonten und externen Bankkonten übertragen.
Die Stripe API unterstützt InboundTransfer
und OutboundTransfer
für Geldübertragungen zwischen den externen Bankkonten von verbundenen Konten und deren Treasury-Finanzkonten. Mit OutboundPayment
kann über die Stripe API zudem Geld von den Treasury-Finanzkonten der verbundenen Konten an externe Drittkonten übermittelt werden. Alle diese Objekte können dabei PaymentMethods
nutzen und somit Angaben der externen Bankkonten, wie die Routingnummer und die Kontonummer, speichern.
Erläuterungen zu PaymentMethods
Innerhalb der Stripe-API können Sie Angaben zur Zahlungsmethode mit einem PaymentMethod
-Objekt speichern. So könnte Homebox zum Beispiel die Konten seiner Anbieter als PaymentMethods
speichern, um Geld zu senden, ohne die Daten erneut eingeben und erfassen zu müssen.
PaymentMethods
mit externen Kontodaten können mit Kund/innen (für Geldsendungen an Dritte) oder mit einem Stripe-Konto (für Abbuchungen bzw. Überweisungen an das externe Bankkonto von Stripe-Kontoinhaber/innen) verknüpft werden. Der „Kunde“ ist dabei das Customer
-Objekt in der Stripe API und gibt die externe Partei an. In Treasury handelt es sich bei Kunden meist um Verkäufer, die Zahlungen von Stripe-Kontoinhaber/innen erhalten und selbst keine Zahlungen an diese tätigen. Zur Einrichtung kunden- und kontospezifischer PaymentMethod
-Objekte verwenden Sie das SetupIntent
-Objekt.
Die relevanten API-Objekte, die Sie mit einer PaymentMethod
verwenden können, hängen davon ab, wie sie zugeordnet sind:
- Kundenbezogen: Verwenden Sie
OutboundPayments
. - Kontobezogen: Verwenden Sie
InboundTransfers
undOutboundTransfers
.
PaymentMethod-Ablauf
Überblick über InboundTransfers und OutboundTransfers
Per InboundTransfer
können Sie Geld vom externen Bankkonto eines Stripe-Kontos einziehen und dann per OutboundTransfer
an ein anderes externes Bankkonto übertragen.
Damit Geld per InboundTransfer
auf ein Treasury-Finanzkonto eingezogen werden kann, müssen die externen Bankkonten von dem/der Inhaber/in des Stripe-Kontos verifiziert werden. Bei Bankkonten, die für Überweisungen von Finanzkonten per OutboundTransfer
genutzt werden, ist dagegen keine derartige Verifizierung erforderlich.
Wenn ein externes Bankkonto entweder für InboundTransfers
oder OutboundTransfers
verwendet wird, müssen Sie die entsprechende PaymentMethod
dem Stripe-Konto (und nicht einem/einer Kund/in) zuordnen. Sie tun dies, indem Sie den Parameter attach_
anstelle des Parameters customer
verwenden, wenn Sie die PaymentMethod
mit SetupIntent
erstellen.
InboundTransfers
- und OutboundTransfers
-Abläufe
OutboundPayments
Plattformen verwenden die OutboundPayment
API, um Gelder von einem Treasury-Finanzkonto an ein externes von einem Drittanbieter geführtes Bankkonto zu senden.
PaymentMethods
müssen für OutboundPayments
korrekt zugeordnet werden. Die für OutboundPayments
verwendeten Bankkonten müssen nicht verifiziert werden.
OutboundPayments
-Ablauf
Ein externes Konto hinzufügen
Homebox möchte die eigenen externen Bankkonten seiner Kundinnen und Kunden mit deren Treasury-Finanzkonten verknüpfen. Die verbundenen Konten von Homebox wollen ihr gesamtes Geschäftskapital in ihren Finanzkonten belassen und mithilfe von eingehenden Transfers Geld von Ihrem externen Konto auf Ihr Treasury-Finanzkonto übertragen. Um Gelder einzuzahlen und abzuheben, erstellt Homebox einen SetupIntent
mit den erforderlichen Parametern und ordnet diesen einer mit dem Konto verknüpften PaymentMethod
zu:
Um Geld über OutboundTransfers
oder InboundTransfers
zu senden und zu empfangen, muss Homebox ein externes Bankkonto mit dem Parameter payment_
angeben. Bevor der Link zum externen Live-Bankkonto erstellt wird, testet Homebox den Ablauf mit den von Stripe bereitgestellten Testkontonummern.
Wie im vorherigen Beispiel gezeigt, hat Homebox das externe Bankkonto festgelegt (payment_
) und attach_
auf true
gestellt. So können die Bankkontodaten dem/der Stripe-Kontoinhaber/in (anstelle eines Dritten) zugeordnet werden. Wenn die Plattform die Anfrage übermittelt, antwortet die Treasury API mit einem SetupIntent
:
{ "id": "{{SETUP_INTENT_ID}}", "object": "setup_intent", "application": "{{APPLICATION_ID}}", "attach_to_self": true, "cancellation_reason": null, "client_secret": "{{SETUP_INTENT_SECRET}}", "created": 1642520861, "customer": null, "description": null, "flow_directions": [ "inbound", "outbound" ], "last_setup_error": null, "latest_attempt": "{{ATTEMPT_ID}}", "livemode": false, "mandate": "{{MANDATE_ID}}", "metadata": { }, "next_action": { "type": "verify_with_microdeposits", "verify_with_microdeposits": { "arrival_date": 1642579200, "hosted_verification_url": "https://payments.stripe.com/microdeposit/sacs_test_xxx", "microdeposit_type": "amounts" } }, "on_behalf_of": null, "payment_method": "{{PAYMENT_METHOD_ID}}", "payment_method_options": { "us_bank_account": { "verification_method": "automatic" } }, "payment_method_types": [ "us_bank_account" ], "single_use_mandate": null, "status": "requires_confirmation", "usage": "off_session" }
Ein externes Konto verifizieren
Homebox hat im vorherigen Abschnitt ein externes Bankkonto verknüpft. Das Bankkonto muss jedoch verifiziert werden, bevor Homebox es für InboundTransfers
verwenden kann. Anhand der Verifizierung des Bankkontos können Kontoinhaber/innen die Inhaberschaft des externen Bankkontos bestätigen. Zur Verifizierung kann Homebox Stripe Financial Connections für die sofortige Verifizierung oder Testeinzahlungen (die länger dauern) nutzen.
Stripe Financial Connections
Stripe stellt Financial Connections zur Verfügung, damit eigene Bankkonten sofort verifiziert werden können. Financial Connections ist ein von Stripe gehosteter Ablauf, der client- und serverseitig in der Anwendung integriert ist.
Drei Schritte müssen ausgeführt werden, damit Homebox Bankkontodaten mit Financial Connections erheben und verifizieren kann:
Erstellen Sie einen
SetupIntent
mit der Eigenschaftattach_
(ersetzen Sie dabei die Eigenschaftto_ self customer_
) und dem Wertid instant
für die Eigenschaftverification_
.method Geben Sie das
client_
an, damit die Frontend-Anwendung Bankkontodaten mitsecret stripe.
erheben, einecollectBankAccountForSetup PaymentMethod
erstellen und diesePaymentMethod
an denSetupIntent
anhängen kann.Notiz
Der Name der Kontoinhaber/innen im Parameter
billing_
ist erforderlich, um einedetails PaymentMethod
für ein US-Bankkonto zu erstellen.Zeigen Sie die Mandatsbedingungen an, um die Autorisierung für die
PaymentMethod
-Verwendung einzuholen.
Für Schritt 1 entwickelt Homebox den folgenden Code, um serverseitig einen SetupIntent
zu erstellen und die Informationen an eine handlebars.js-Vorlage zu übergeben. Bei diesem Code wird vorausgesetzt, dass Nutzer/innen durch die Anwendung bei Stripe angemeldet sind und die Anwendung die Stripe-Konto-ID mit dem Session
-Objekt (req.
) übergibt.
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY); router.get('/add_bank_account', async (req, res) => { const account = await stripe.accounts.retrieve(req.session.accountId); const setupIntent = await stripe.setupIntents.create({ attach_to_self: true, flow_directions: ['inbound', 'outbound'], payment_method_types: ['us_bank_account'], payment_method_options: {us_bank_account: {verification_method: "automatic"}} },{ stripeAccount: account.id, }); let client_secret= setupIntent.client_secret; res.render('add_bank_account', { account: account, client_secret: client_secret, stripe_pk: process.env.STRIPE_PUBLISHABLE_KEY }); });
Schritt 2 beginnt, wenn Homebox die folgenden Daten an die Render-Funktion übergibt:
- Die Stripe-Konto-ID
- Das vom
SetupIntent
abgerufene Client-Geheimnis, das als Kennung verwendet wird - Den veröffentlichbaren API-Schlüssel der Plattform
Bei diesem Beispiel wird die clientseitige Seite mit einer Schaltfläche gerendert, über die Nutzer/innen ihr Bankkonto mit Financial Connections validieren können.
Modal zum Hinzufügen eines Bankkontos
Homebox erstellt den folgenden Code für die Logik hinter der vorangehenden Schaltfläche.
const getBankAccount = async e => { paymentMethodButton.setAttribute("disabled", "disabled"); // Calling this method triggers the Financial Connections modal to display. const response = await stripe.collectBankAccountForSetup("{{ client_secret }}", { billing_details: { name: "John Doe", email: "test@test.com", }, }); if (response.error) { console.error(response.error); } if (response.status == "requires_confirmation") { //Show confirmation modal AcceptBankAccountModal.classList.remove("hidden"); } };
In diesem Codebeispiel ruft das Skript die Methode collectUsBankAccountForSetup
auf und übergibt das client_
aus dem SetupIntent
. Nutzer/innen werden in einem Anwendungsdialogfeld durch die Verknüpfung ihres Bankkontos geführt.
Workflow zum Hinzufügen eines Bankkontos
Schritt 3 beginnt mit dem erfolgreichen Abschluss des vorherigen Workflows, wenn der SetupIntent
-Status zu requires_
übergeht und ein Modalfenster eine Autorisierungsmeldung für die Bestätigung auf Nutzerseite anzeigt.
Autorisierungsmeldung
Nachdem Nutzer/innen auf Akzeptieren geklickt haben, ruft der Code die Methode confirmUsBankAccountSetup
auf. Dann wird das Bankkonto als verifiziert gespeichert. Jetzt kann das Bankkonto für InboundTransfers
verwendet werden.
const acceptBankAccount = async e => { acceptButton.setAttribute("disabled", "disabled"); const response = await stripe.confirmUsBankAccountSetup("{{ client_secret }}"); if (response.setupIntent.status == "requires_payment_method") { // Confirmation failed. Attempt again with a different payment method. console.log("Requires payment method") } else if (response.setupIntent.status == "succeeded") { // Confirmation succeeded! The account is now saved. // Display a message to customer. AcceptBankAccountModal.classList.add("hidden"); console.log("Account added"); } else if (response.setupIntent.next_action?.type == "verify_with_microdeposits") { // The account needs to be verified via microdeposits. // Display a message to consumer with next steps (consumer waits for // microdeposits, then enters an amount on a page sent to them via email). console.log("The account needs to be verified with microdeposits") } };
Testeinzahlungen
Testeinzahlungen sind kleine Beträge (in der Regel ein Bruchteil eines US-Dollars), die Stripe auf ein externes Bankkonto einzahlt. Kontoinhaber/innen können die Inhaberschaft des Kontos durch Bestätigung der entsprechenden Einzahlungsbeträge verifizieren.
Das von Homebox im vorherigen Abschnitt erstellte SetupIntent
-Objekt enthält eine PaymentMethod
-ID.
{ "id": "{{SETUP_INTENT_ID}}", … "on_behalf_of": null, "payment_method": "{{PAYMENT_METHOD_ID}}", "payment_method_options": { … } }
Der SetupIntent
enthält auch ein next_
-Objekt mit einer URL, die im Wert hosted_
festgelegt ist.
{ "id": "{{SETUP_INTENT_ID}}", … "next_action": { "type": "verify_with_microdeposits", "verify_with_microdeposits": { "arrival_date": 1642579200, "hosted_verification_url": "https://payments.stripe.com/microdeposit/sacs_test_xxx", "microdeposit_type": "amounts" } … }
Homebox stellt dem/der Inhaber/in des verbundenen Kontos die URL bereit, um die Verifizierung abzuschließen. Diese/r muss der URL folgen, um den Erhalt der Testeinzahlungen zu bestätigen, indem er/sie den zugehörigen Beschreibungscode eingibt (im Testmodus sollte der Wert SM11AA
verwendet werden).
Verifizierung einer Mikroeinzahlung
PaymentMethods mit InboundTransfers verwenden
Homebox kann mit der Erstellung von InboundTransfers
beginnen, indem ein Bankkonto verwendet wird, das mit einer der zuvor beschriebenen Methoden verifiziert wurde.
Bei der folgenden Anfrage werden 200 USD mit einer mit einem Konto verknüpften Zahlungsmethode auf das Finanzkonto mit der angegebenen ID überwiesen. Der Stripe-Account
-Header-Wert gibt das verbundene Stripe-Konto an, das sowohl das Finanzkonto als auch die Zahlungsmethode enthält.
Bei Erfolg stellt die Antwort das Objekt InboundTransfer
bereit. Dieses enthält eine hosted_
, die dem Kontoinhaber/der Karteninhaberin weitere Angaben zur Transaktion auf der Homebox Plattform bereitstellt.
{ "id": "{{INBOUND_TRANSFER_ID}}", "object": "inbound_transfer", "amount": 20000, "created": 1648071297, "currency": "usd", "description": "Funds for repair", "financial_account": "{{FINANCIAL_ACCOUNT_ID}}", "hosted_regulatory_receipt_url": "https://payments.stripe.com/regulatory-receipt/{{IBT_URL}}", "linked_flows": null, "livemode": false, "metadata": {}, "origin_payment_method": "{{PAYMENT_METHOD_ID}}", ... "statement_descriptor": "Invoice 12", "status": "processing", ... }
PaymentMethods mit OutboundPayments verwenden
PaymentMethod
kann auch verwendet werden, um über die OutboundPayment
-Objekte Geld an das externe Bankkonto eines Dritten zu senden.
Homebox möchte auf wiederkehrender Basis Gelder an Anbieter/innen eines der verbundenen Konten senden, um Materialien zu bezahlen. Dazu muss die Plattform zunächst die Kunden-ID über den Customers
-Endpoint anfordern.
Die Antwort stellt die Kund/innen für das entsprechende verbundene Konto bereit. Homebox identifiziert die richtigen Kund/innen und erfasst ihre IDs.
{ "id": "{{CUSTOMER_ID}}", "object": "customer", "address": null, "balance": 0, "created": 1642523420, "currency": null, "default_source": null, "delinquent": false, "description": "Test Customer", "discount": null, "email": null, "invoice_prefix": "96A50A92", "invoice_settings": { "custom_fields": null, "default_payment_method": null, "footer": null }, "livemode": false, "metadata": { }, "name": null, "next_invoice_sequence": 1, "phone": null, "preferred_locales": [ ], "shipping": null, "tax_exempt": "none" }
Homebox erstellt dann einen SetupIntent
mithilfe der ID. Da OutboundPayments
für Zahlungen an Dritte verwendet wird, setzt Homebox flow_
auf outbound
und verwendet attach_
nicht, sondern gibt stattdessen eine/n customer
an.
Ein erfolgreicher Aufruf gibt das folgende Objekt zurück, um die Zuordnung der PaymentMethod
zum/zur Kund/in zu bestätigen.
{ "id": "{{SETUP_INTENT_ID}}", "object": "setup_intent", "application": "{{APPLICATION_ID}}", "cancellation_reason": null, "client_secret": "{{SETUP_INTENT_SECRET}}", "created": 1642528487, "customer": "{{CUSTOMER_ID}}", "description": null, "flow_directions": [ "outbound" ], "last_setup_error": null, "latest_attempt": null, "livemode": false, "mandate": null, "metadata": { }, "next_action": null, "on_behalf_of": null, "payment_method": "{{PAYMENT_METHOD_ID}}", "payment_method_options": { }, "payment_method_types": [ "us_bank_account" ], "single_use_mandate": null, "status": "succeeded", "usage": "off_session" }
OutboundPayment ohne PaymentMethod erstellen
PaymentMethods
sind beim Senden/Verwenden von OutboundPayments
nicht erforderlich, wenn das Bankkonto der Empfängerin/des Empfängers nicht gespeichert werden muss (z. B. bei einmaligen Zahlungen).
Homebox musste einem Anbieter 50 USD Materialkosten bezahlen. Dazu ruft die Plattform OutboundPayments
mit den externen Kontodaten auf.
Der erfolgreiche Aufruf gibt das folgende Objekt zurück:
{ "id": "{{OUTBOUNDPAYMENT_ID}}", "object": "treasury.outbound_payment", "amount": 5000, "cancelable": true, "created": 1643033124, "currency": "usd", "customer": null, "description": null, "destination_payment_method": null, "destination_payment_method_details": { "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": "John Doe", "phone": null }, "type": "us_bank_account", "us_bank_account": { "account_holder_type": "individual", "bank_name": "STRIPE TEST BANK", "fingerprint": "SzrMIps1gg91aVKG", "last4": "6789", "network": "ach", "routing_number": "110000000" } }, "end_user_details": { "present": false, "ip_address": null }, "expected_arrival_date": 1643068800, "financial_account": "{{FINANCIAL_ACCOUNT_ID}}", "hosted_regulatory_receipt_url": "https://payments.stripe.com/regulatory-receipt/bot_test_xxx", "livemode": false, "metadata": { }, "statement_descriptor": "payment_1", "status": "processing", "status_transitions": { "canceled_at": null, "failed_at": null, "posted_at": null, "processing_at": 1643033124, "returned_at": null }, "transaction": "{{TRANSACTION_ID}}" }