Utilisation de Treasury pour le transfert de fonds
Découvrez comment utiliser les SetupIntents, les PaymentMethods et comment vérifier les comptes bancaires avec Stripe Treasury.
Homebox est un SaaS vertical fictif qui conçoit des logiciels pour les entreprises de services à domicile telles que les entreprises de CVC, de nettoyage et de plomberie. Cette intégration présente quelques opérations financières de base réalisées à l’aide des endpoints Treasury de l’API Stripe. Pour découvrir comment l’entreprise a pu créer un compte financier Treasury et émettre des cartes de paiement, consultez la documentation relative à l’utilisation de Treasury pour configurer des comptes financiers et des cartes bancaires.
Utilisation de comptes bancaires externes
Stripe Treasury met à la disposition des plateformes un ensemble de endpoints API pour la création de comptes et le transfert de fonds permettant d’optimiser la conservation, la gestion et le transfert des fonds des comptes connectés. Les plateformes peuvent alimenter un compte financier et transférer des fonds entre des comptes financiers Treasury et des comptes bancaires externes.
L’API Stripe propose les fonctions InboundTransfer
et OutboundTransfer
pour faciliter le transfert d’argent entre les comptes bancaires externes des comptes connectés et leurs comptes financiers Treasury. Elle propose également l’objet OutboundPayment
qui permet des transferts d’argent simplifiés entre les comptes financiers Treasury des comptes connectés et les comptes bancaires externes de tiers. Tous ces objets peuvent utiliser PaymentMethods
pour stocker des informations de comptes bancaires externes, par exemple 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 référence à l’objet Customer
de l’API Stripe, qui définit tout tiers. Dans le cas de Treasury, 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 desOutboundTransfers
.
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 Treasury à 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_
plutôt que le paramètre customer
lors de la création de l’objet PaymentMethod
en utilisant SetupIntent
.
Flux InboundTransfers
et OutboundTransfers
.
OutboundPayments
Les plateformes utilisent l’API OutboundPayment
pour envoyer des fonds d’un compte financier Treasury vers un compte bancaire externe détenu par un tiers.
Vous devez associer les PaymentMethods
à un client pour les utiliser avec des OutboundPayments
. Les comptes bancaires utilisés pour des OutboundPayments
n’ont pas besoin d’être vérifiés.
Flux OutboundPayments
Ajout d’un compte bancaire externe
Homebox souhaite associer les comptes bancaires externes de ses clients à leurs comptes financiers Treasury. 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 Treasury. 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 l’associe à un PaymentMethod
associé à un compte :
Pour envoyer et recevoir des fonds par OutboundTransfers
ou InboundTransfers
, Homebox doit spécifier un compte bancaire externe dans le paramètre payment_
. 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 fournis par Stripe.
Comme indiqué dans l’exemple précédent, Homebox a paramétré un compte bancaire externe (payment_
) et défini le paramètre attach_
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 Treasury répond par un 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" }
Vérification d’un compte bancaire externe
Dans la section précédente, Homebox a associé un compte bancaire externe. Pour que Homebox puisse l’utiliser dans le cadre d’InboundTransfers
, ce compte doit cependant d’abord être vérifié. La vérification du compte bancaire permet au titulaire du compte de confirmer la propriété du compte bancaire externe. Homebox peut effectuer cette vérification à l’aide de Stripe Financial Connections pour un effet instantané, ou de micro-dépôts, qui prennent plus de temps.
Stripe Financial Connections
Stripe vous propose d’utiliser Financial Connections pour vérifier instantanément votre compte bancaire. Financial Connections est un flux hébergé par Stripe, intégré aux côtés client et serveur de l’application.
Le processus de collecte et de vérification des informations de compte bancaire avec Financial Connections effectué par Homebox comporte trois étapes obligatoires :
Créez un
SetupIntent
avec la propriétéattach_
(en remplacement de la propriététo_ self customer_
), et la valeurid instant
pour la propriétéverification_
.method Fournissez le
client_
à l’application front-end afin d’utilisersecret stripe.
pour collecter les informations de compte bancaire, créercollectBankAccountForSetup PaymentMethod
un objetPaymentMethod
et l’associer auSetupIntent
.Note
Le nom du titulaire du compte, trouvable dans le paramètre
billing_
, est nécessaire pour créer ledetails PaymentMethod
d’un compte bancaire aux États-Unis.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
(req.
).
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.
Fenêtre modale d’ajout de compte bancaire
Homebox créé le code suivant afin d’exécuter la logique du bouton précédent.
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 client_
du SetupIntent
. Une boîte de dialogue explique à l’utilisateur comment lier son compte bancaire.
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_
. Une fenêtre modale affiche alors un message d’autorisation permettant à l’utilisateur de confirmer.
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
.
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") } };
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
.
{ "id": "{{SETUP_INTENT_ID}}", … "on_behalf_of": null, "payment_method": "{{PAYMENT_METHOD_ID}}", "payment_method_options": { … } }
Le SetupIntent
inclut également un objet next_
doté d’une URL indiquée dans la valeur hosted_
.
{ "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 l’URL au propriétaire du compte connecté afin de terminer 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 (en mode test, utiliser la valeur SM11AA
).
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.
Sauf échec de l’opération, la réponse renvoie l’objet InboundTransfer
qui inclut une hosted_
permettant au titulaire du compte de consulter les informations relatives à la transaction sur laHomebox plateforme.
{ "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
.
La réponse indique les clients du compte connecté correspondant. Homebox identifie le client concerné et note son ID.
{ "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_
sur outbound
et n’utilise pas attach_
plutôt que de spécifier un customer
.
Un appel réussi renverra l’objet suivant pour signifier que le PaymentMethod
a bien été associé au client.
{ "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.
Si l’appel réussit, il renvoie l’objet suivant :
{ "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}}" }