# Utiliser Financial Accounts pour les plateformes pour transférer des fonds Découvrez comment utiliser les SetupIntents et les PaymentMethods, et comment vérifier les comptes bancaires avec les Financial Accounts pour les plateformes. Homebox est un SaaS vertical fictif qui développe des logiciels pour les entreprises de services à domicile, telles que les entreprises de chauffage, de ventilation et de climatisation, de nettoyage et de plomberie. Cet exemple d’intégration décrit certains mouvements financiers de base à l’aide des points de terminaison de trésorerie de l’[API Stripe](https://docs.stripe.com/api.md). Pour savoir comment l’entreprise créerait un compte financier et émettrait des cartes de paiement, consultez la section sur l’[utilisation de Financial Accounts pour les plateformes afin de créer des comptes financiers et des cartes](https://docs.stripe.com/financial-accounts/connect/examples/financial-accounts.md). ## Utilisation de comptes bancaires externes Financial Accounts pour les plateformes met à la disposition des plateformes un ensemble d’endpoints API permettant la création de comptes et les transferts d’argent afin de faciliter la sauvegarde, la gestion et les transferts de fonds entre les comptes connectés. Les plateformes peuvent approvisionner un compte financier et transférer des fonds entre des comptes financiers et des comptes bancaires externes. L’API Stripe fournit les options de `InboundTransfer` et de `OutboundTransfer` pour faciliter le transfert d’argent entre les comptes bancaires externes des comptes connectés et leurs comptes financiers. L’API Stripe fournit également les options de `OutboundPayment` pour faciliter le transfert d’argent entre les comptes financiers des comptes connectés et les comptes financiers externes de tiers. Tous ces objets peuvent utiliser le `PaymentMethods` pour sauvegarder les informations du compte bancaire externe, telles que les numéros de routage et les numéros de compte. ## Fonctionnement des PaymentMethods Dans l’API Stripe, vous pouvez enregistrer les informations relatives aux moyens de paiement à l’aide d’un objet `PaymentMethod`. Par exemple, Homebox peut enregistrer les comptes de ses vendeurs en tant que `PaymentMethods` pour envoyer de l’argent sans avoir à saisir et collecter à nouveau leurs informations. Vous pouvez associer des `PaymentMethods` contenant des informations de comptes bancaires externes à un client (pour virer des fonds à un tiers) ou à un compte Stripe (pour prélever ou envoyer de l’argent sur un compte bancaire externe appartenant au titulaire du compte Stripe). Le « client » fait généralement référence à l’objet `Customer` de l’API Stripe, qui définit tout tiers. Dans le cas de Financial Accounts pour les plateformes, le client est généralement un fournisseur qui reçoit des paiements du titulaire du compte Stripe (plutôt que l’inverse). Utilisez l’objet `SetupIntent` pour définir les objets `PaymentMethod` qu’ils soient associés au client ou au compte. Les objets API que vous pouvez utiliser avec un `PaymentMethod` dépendent de ce à quoi il est associé : - Dans le cas d’une association à un client : utilisez des `OutboundPayments`. - Dans le cas d’une association à un compte : utilisez des `InboundTransfers` et des `OutboundTransfers`. ![Organigramme avec un compte bancaire externe à gauche et un flux se déplaçant vers SetupIntent, puis PaymentMethod et associé au client ou au compte.](https://b.stripecdn.com/docs-statics-srv/assets/paymentmethods.f429ec4e87b87636c0e2b34c26a69c83.png) Flux PaymentMethod ## Présentation des InboundTransfers et OutboundTransfers Vous pouvez prélever des fonds (« pull ») sur le compte bancaire externe d’un compte Stripe à l’aide d’un `InboundTransfer` et y virer des fonds (« push ») à l’aide d’un `OutboundTransfer`. Les comptes de banques externes doivent être vérifiés par le titulaire du compte Stripe afin de pouvoir prélever de l’argent sur un compte financier à l’aide d’un `InboundTransfer`. Les comptes bancaires utilisés pour virer des fonds depuis un compte financier à l’aide d’un `OutboundTransfer` ne sont pas concernés. Lorsqu’un compte bancaire externe est utilisé pour des `InboundTransfers` ou `OutboundTransfers`, vous devez associer le `PaymentMethod` correspondant au compte Stripe plutôt qu’à un client. Pour ce faire, vous devez utiliser le paramètre `attach_to_self=true` plutôt que le paramètre `customer` lors de la création de l’objet `PaymentMethod` en utilisant `SetupIntent`. ![Organigramme avec une banque externe à gauche et un flux pointant vers SetupIntent to PaymentMethod et se rattachant au compte Stripe.](https://b.stripecdn.com/docs-statics-srv/assets/iot.38c049d39deca401a3341b34d72189fe.png) Les flux InboundTransfers et OutboundTransfers ## OutboundPayments Les plateformes utilisent l’API `OutboundPayment` pour envoyer des fonds d’un compte financier vers un compte bancaire externe détenu par un tiers. Vous devez attacher les `PaymentMethods` à un client pour les utiliser avec les `OutboundPayments`. Vous n’avez pas besoin de vérifier les comptes bancaires utilisés pour les `OutboundPayments`. ![](https://b.stripecdn.com/docs-statics-srv/assets/iot-customer.5476c499693c606ead280fbae61ebe4a.png) Flux `OutboundPayments` ## Ajout d’un compte bancaire externe Homebox souhaite associer les comptes bancaires externes de ses clients à leurs comptes financiers. Les comptes connectés de Homebox souhaitent conserver l’intégralité du capital de leur entreprise dans leurs comptes financiers et utiliser des transferts entrants pour transférer des fonds de leurs comptes externes vers leur compte financier. Afin de permettre à ses comptes connectés de transférer des fonds vers et à partir de leurs comptes externes, Homebox crée un objet `SetupIntent` doté des paramètres requis et le joint à un `PaymentMethod` associé à un compte : ```curl curl https://api.stripe.com/v1/setup_intents \ -u "<>:" \ -H "Stripe-Account: {{CONNECTEDACCOUNT_ID}}" \ -d attach_to_self=true \ -d "flow_directions[]=inbound" \ -d "flow_directions[]=outbound" \ -d "payment_method_types[]=us_bank_account" \ -d "payment_method_data[type]=us_bank_account" \ -d "payment_method_data[us_bank_account][routing_number]=110000000" \ -d "payment_method_data[us_bank_account][account_number]=000123456789" \ -d "payment_method_data[us_bank_account][account_holder_type]=company" \ -d "payment_method_data[billing_details][name]=Company Corp" \ -d confirm=true \ -d "mandate_data[customer_acceptance][type]=online" \ -d "mandate_data[customer_acceptance][online][ip_address]=123.123.123.123" \ --data-urlencode "mandate_data[customer_acceptance][online][user_agent]=curl/1.2.3" ``` Pour envoyer et recevoir des fonds par `OutboundTransfers` ou `InboundTransfers`, Homebox doit spécifier un compte bancaire externe dans le paramètre `payment_method_data[us_bank_account]`. Avant de créer un lien vers le compte bancaire externe en mode production, Homebox teste le flux à l’aide des [numéros de comptes de test](https://docs.stripe.com/payments/ach-direct-debit/set-up-payment.md?platform=web&payment-ui=stripe-hosted#test-account-numbers) fournis par Stripe. Comme indiqué dans l’exemple précédent, Homebox a paramétré un compte bancaire externe (`payment_method_data[us_bank_account]`) et défini le paramètre `attach_to_self` sur `true`, ce qui permet d’associer les coordonnées bancaires au titulaire du compte Stripe (plutôt qu’à un tiers). Lorsque la plateforme envoie la requête, l’API répond par un `SetupIntent` : ```json { "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" } ``` ## Vérification d’un compte bancaire externe Homebox a associé un compte bancaire externe dans la section précédente. Le compte bancaire doit être vérifié avant que Homebox puisse l’utiliser pour `InboundTransfers`. La vérification du compte bancaire permet au propriétaire du compte de confirmer la propriété du compte bancaire externe. Pour la vérification, Homebox peut utiliser [Stripe Financial Connections](https://docs.stripe.com/financial-accounts/connect/examples/moving-money.md#connections) pour une vérification instantanée, ou [microversements](https://docs.stripe.com/financial-accounts/connect/examples/moving-money.md#microdeposits) (qui prennent plus de temps). ### Stripe Financial Connections Vous pouvez utiliser [Financial Connections](https://docs.stripe.com/financial-connections.md) pour vérifier instantanément un compte connecté. Financial Connections est un flux hébergé par Stripe et connecté côté client et côté serveur de l’application. Trois étapes nécessaires pour que Homebox puisse collecter et vérifier les informations relatives aux comptes bancaires auprès de Financial Connections : 1. Créez un `SetupIntent` avec la propriété `attach_to_self` (en remplacement de la propriété `customer_id`), et la valeur `instant` pour la propriété `verification_method`. 1. Fournissez la clé sécrète client `client_secret` à l’application front-end afin d’utiliser `stripe.collectBankAccountForSetup` pour collecter les informations de compte bancaire, créez un `PaymentMethod` et associez l’objet `PaymentMethod` au `SetupIntent`. > Le nom du titulaire du compte, trouvable dans le paramètre `billing_details`, est nécessaire pour créer le `PaymentMethod` d’un compte bancaire aux États-Unis. 1. Affichez les conditions du mandat afin de collecter l’autorisation pour l’utilisation de `PaymentMethod`. Pour l’étape 1, Homebox développe le code suivant afin de créer un `SetupIntent` côté serveur et de transmettre l’information au modèle handlebars.js. Ce code suppose qu’une application a un utilisateur connecté à Stripe et qu’elle transmet l’ID du compte Stripe dans l’[objet `Session`](https://docs.stripe.com/api/financial_connections/sessions/object.md) (`req.session.accountId`). ```javascript 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 }); }); ``` L’étape 2 commence lorsque Homebox transmet les données suivantes à la fonction de rendu : - L’ID du compte Stripe. - La clé secrète du client obtenue à partir du `SetupIntent` utilisé comme identifiant. - La clé API publiable de la plateforme. Dans cet exemple, la page côté client s’affiche avec un bouton permettant à l’utilisateur de valider son compte bancaire avec Financial Connections. ![Capture d'écran d'une fenêtre modale intitulée Ajouter un compte bancaire avec un bouton intitulé Enregistrer les informations de paiement](https://b.stripecdn.com/docs-statics-srv/assets/add-bank-account-modal.0b727f65d3c6691f3bef211c1a45cb83.png) Fenêtre modale d’ajout de compte bancaire Homebox créé le code suivant afin d’exécuter la logique du bouton précédent. ```javascript 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"); } }; ``` Dans cet exemple de code, le script appelle la méthode `collectUsBankAccountForSetup` et transmet le paramètre `client_secret` depuis le `SetupIntent`. Une boîte de dialogue explique à l’utilisateur comment lier son compte bancaire. ![Capture d'écran d'une fenêtre modale effectuant l'ajout d'un compte bancaire. Le premier état de la fenêtre modale affiche l'étape d'autorisation avec un bouton Accepter et l'état suivant affiche le compte en surbrillance avec un bouton d'association de comptes.](https://b.stripecdn.com/docs-statics-srv/assets/add-account-flow.cfd2209695ca186cd617f682319e564c.png) Flux d’ajout d’un compte bancaire L’étape 3 commence par la réussite du flux précédent, quand l’état `SetupIntent` passe à `requires_confirmation`. Une fenêtre modale affiche alors un [message d’autorisation](https://docs.stripe.com/payments/ach-direct-debit/set-up-payment.md?platform=web#web-collect-mandate-and-submit) permettant à l’utilisateur de confirmer. ![Capture d'écran d'une fenêtre modale affichant la langue de la confirmation de l'autorisation avec un bouton Accepter en bas et une croix (x) en haut à gauche pour annuler.](https://b.stripecdn.com/docs-statics-srv/assets/accept-modal.6db14c686b9ec87ff471a18d2f9d2abf.png) Message d’autorisation Une fois que l’utilisateur a cliqué sur **Accepter**, le code appelle la méthode `confirmUsBankAccountSetup` et le compte bancaire est vérifié. Ce compte bancaire peut à présent être utilisé pour les `InboundTransfers`. ```javascript 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 through microdeposits. // Display a message to consumer with next steps (consumer waits for // microdeposits, then enters an amount on a page sent to them through email). console.log("The account needs to be verified with microdeposits") } }; ``` ### Microdépôts Les microdépôts sont de petites sommes d’argent, généralement bien inférieures à 1 USD, versées par Stripe à un compte bancaire externe. Pour vérifier la propriété du compte bancaire, les titulaires du compte doivent confirmer le montant exact de ces dépôts. L’objet `SetupIntent` créé par Homebox à la section précédente comporte un ID de `PaymentMethod`. ```json { "id": "{{SETUP_INTENT_ID}}", … "on_behalf_of": null,"payment_method": "{{PAYMENT_METHOD_ID}}", "payment_method_options": { … } } ``` Le `SetupIntent` inclut également un objet `next_action` doté d’une URL indiquée dans la valeur `hosted_verification_url`. ```json { "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 fournit cette URL au titulaire du compte connecté, qui peut alors finaliser la vérification. Le propriétaire doit suivre cette URL pour vérifier la réception en saisissant le code de description associé du microversement (dans des environnements de test, utilisez la valeur `SM11AA`). ![Boîte de dialogue de vérification des micro-dépôts montrant un centime déposé sur un compte, une invite à saisir un code de libellé et un bouton de vérification.](https://b.stripecdn.com/docs-statics-srv/assets/microdeposits.0b67c00bb4028265c9ed9dbe300f5b81.png) Vérification des microversements ## Utilisation de PaymentMethods avec des InboundTransfers Homebox peut commencer à créer des `InboundTransfers` en utilisant un compte bancaire vérifié et en optant pour l’une des méthodes décrites précédemment. La requête suivante déclenche un virement de 200 USD sur le compte financier correspondant à l’ID fourni à l’aide d’un moyen de paiement associé au compte. La valeur de l’en-tête `Stripe-Account` permet d’identifier le compte Stripe qui détient le compte financier et le moyen de paiement. ```curl curl https://api.stripe.com/v1/treasury/inbound_transfers \ -u "<>:" \ -H "Stripe-Account: {{CONNECTEDACCOUNT_ID}}" \ -d "origin_payment_method={{PAYMENTMETHOD_ID}}" \ -d "financial_account={{TREASURYFINANCIALACCOUNT_ID}}" \ -d amount=20000 \ -d currency=usd \ -d "description=Funds for repair" \ -d "statement_descriptor=Invoice 12" ``` Sauf échec de l’opération, la réponse renvoie l’objet `InboundTransfer` qui inclut une `hosted_regulatory_receipt_url` permettant au titulaire du compte de consulter les informations relatives à la transaction sur laHomebox plateforme. ```json { "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", ... } ``` ## Utilisation de PaymentMethods avec OutboundPayments Les objets `OutboundPayment` permettent également d’utiliser un `PaymentMethod` pour envoyer des fonds vers un compte bancaire externe appartenant à un tiers. Homebox souhaite envoyer des fonds de manière récurrente aux fournisseurs de l’un de comptes connectés pour des règlements de fournitures. Pour cela, la plateforme doit d’abord obtenir l’ID du client à l’aide du endpoint `Customers`. ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ -H "Stripe-Account: {{CONNECTEDACCOUNT_ID}}" \ -d "description=Test Customer" ``` La réponse indique les clients du compte connecté correspondant. Homebox identifie le client concerné et note son ID. ```json {"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 crée ensuite un `SetupIntent` en utilisant cet ID. Les transferts de fonds vers les tiers se font à l’aide de `OutboundPayments`, Homebox veille donc à définir `flow_directions` sur `outbound` et n’utilise pas `attach_to_self` plutôt que de spécifier un `customer`. ```curl curl https://api.stripe.com/v1/setup_intents \ -u "<>:" \ -H "Stripe-Account: {{CONNECTEDACCOUNT_ID}}" \ -d "customer={{CUSTOMER_ID}}" \ -d "flow_directions[]=outbound" \ -d "payment_method_types[]=us_bank_account" \ -d "payment_method_data[type]=us_bank_account" \ -d "payment_method_data[us_bank_account][routing_number]=110000000" \ -d "payment_method_data[us_bank_account][account_number]=000123456789" \ -d "payment_method_data[us_bank_account][account_holder_type]=individual" \ -d "payment_method_data[billing_details][name]=John doe" \ -d confirm=true ``` Un appel réussi renverra l’objet suivant pour signifier que le `PaymentMethod` a bien été associé au client. ```json { "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" } ``` ## Création d’OutboundPayment sans PaymentMethod Lorsqu’il n’est pas nécessaire de conserver le compte bancaire du destinataire (par exemple, pour un paiement ponctuel), vous pouvez utiliser des `OutboundPayments` sans recourir à des `PaymentMethods`. Homebox devait payer 50 USD à un fournisseur en règlement de fournitures. Pour effectuer le règlement, la plateforme appelle `OutboundPayments` en fournissant les informations du compte bancaire externe. ```curl curl https://api.stripe.com/v1/treasury/outbound_payments \ -u "<>:" \ -H "Stripe-Account: {{CONNECTEDACCOUNT_ID}}" \ -d "destination_payment_method_data[type]=us_bank_account" \ -d "destination_payment_method_data[us_bank_account][routing_number]=110000000" \ -d "destination_payment_method_data[us_bank_account][account_number]=000123456789" \ -d "destination_payment_method_data[us_bank_account][account_holder_type]=individual" \ -d "destination_payment_method_data[billing_details][name]=John Doe" \ -d "financial_account={{TREASURYFINANCIALACCOUNT_ID}}" \ -d statement_descriptor=payment_1 \ -d amount=5000 \ -d currency=usd ``` Si l’appel réussit, il renvoie l’objet suivant : ```json { "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}}" } ``` ## See also - [Utilisation de Financial Accounts pour les plateformes afin de configurer des comptes financiers et des cartes](https://docs.stripe.com/financial-accounts/connect/examples/financial-accounts.md) - [Documentation de l’API](https://docs.stripe.com/api/treasury/financial_accounts.md)