# Transférer des fonds à l'aide d'objets OutboundTransfer En savoir plus sur le transfert de fonds depuis des comptes financiers vers des comptes externes. Un objet `OutboundTransfer` permet de faciliter les transferts de fonds depuis un compte financier. Utilisez un `OutboundTransfer` pour envoyer des fonds via le réseau ACH ou via un virement bancaire national vers un compte bancaire externe détenu par un de compte connecté. En règle générale, les transferts sortants arrivent à la banque destinataire dans un délai maximal de 2 jours ouvrables, qu’il s’agisse d’un virement bancaire ou ACH. > (Multi FA beta) Si vous participez à la version bêta de la fonctionnalité Comptes financiers multiples, vous pouvez utiliser un `OutboundTransfer` pour envoyer des fonds vers un autre compte financier associé au même compte connecté via le réseau `stripe`. Les fonds sont disponibles sur le compte financier de destination en quelques minutes. Pour en savoir plus, consultez le guide sur la [chronologie de transfert de fonds](https://docs.stripe.com/financial-accounts/connect/money-movement/timelines.md#outboundpayment-and-outboundtransfer-transactions). Les `OutboundTransfers` prennent en charge les moyens de paiement de type `us_bank_account`. Vous pouvez également utiliser un [BankAccount](https://docs.stripe.com/payments/ach-direct-debit/migrating-from-charges.md) existant qui appartient à l’entreprise en tant qu’[ExternalAccount](https://docs.stripe.com/api/external_accounts.md). ## Créer un OutboundTransfer Utilisez `POST /v1/treasury/outbound_transfers` pour créer un [OutboundTransfer](https://docs.stripe.com/api/treasury/outbound_transfers/create.md) pour le compte financier avec l’ID associé. Sur l’ensemble des paramètres disponibles, quatre sont obligatoires : - `amount` : montant du transfert en centimes. - `currency` : code de devise ISO à trois lettres. - `financial_account` : l’ID du compte financier source d’où proviennent les fonds. - `destination_payment_method` : l’ID du `PaymentMethod` de destination ou du `BankAccount` qui va recevoir les fonds. - `destination_payment_method_data` : compte financier utilisé pour la réception des fonds. ```json { // The source financial account to pull funds from. "financial_account": "{{FINANCIAL_ACCOUNT_ID}}", // The amount to send. 10.00 USD in this case. "amount": 1000, "currency": "usd", // The destination PaymentMethod or BankAccount. // This should be nil if destination_payment_method is set. destination_payment_method_data: { type: "financial_account", // us_bank_account is not supported financial_account: "{{FINANCIAL_ACCOUNT_ID}}", }, // This should be nil if destination_payment_method_data is set. "destination_payment_method": "{{PAYMENT_METHOD_ID}}" | "{{BANK_ACCOUNT_ID}}", // Optionally, to explicitly specify a network, override the `network` value // This should be nil if destination_payment_method_data is set. "destination_payment_method_options": { "us_bank_account": { "network": "ach" | "us_domestic_wire" } }, // A description visible on the external bank statement. "statement_descriptor": "Bank xfer", // An optional internal description to identify this OutboundTransfer "description": "Transfer to my external account", // Stripe doesn't support updating originated transfers after creation. // You can only set metadata at creation. "metadata": nil | Hash, } ``` La requête suivante permet de créer un `OutboundTransfer` sur un `PaymentMethod` associé à un compte et dont les fonds proviennent du compte financier identifié. ```curl curl https://api.stripe.com/v1/treasury/outbound_transfers \ -u "<>:" \ -H "Stripe-Account: {{CONNECTEDACCOUNT_ID}}" \ -d "financial_account={{TREASURYFINANCIALACCOUNT_ID}}" \ -d amount=1000 \ -d currency=usd \ -d "destination_payment_method={{PAYMENTMETHOD_ID}}" \ -d "statement_descriptor=Test xfer" \ -d "destination_payment_method_options[us_bank_account][network]=ach" ``` Sauf échec de l’opération, la réponse renvoie le nouvel objet `OutboundTransfer`. ```json { "id": "{{OUTBOUND_TRANSFER_ID}}", "object": "outbound_transfer", "amount": 1000, "cancelable": true, "created": 1648479987, "currency": "usd", "description": null, "destination_payment_method": "{{PAYMENT_METHOD_ID}}" | null, "destination_payment_method_details": { "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": null, "phone": null }, "type": "financial_account", "financial_account": { "id": "{{FINANCIAL_ACCOUNT_ID}}", "network": "stripe", }, }, "expected_arrival_date": 1648512000, "financial_account": "{{FINANCIAL_ACCOUNT_ID}}", "hosted_regulatory_receipt_url": "https://payments.stripe.com/regulatory-receipt/{{URL_ID}}", "livemode": false, "metadata": {}, "returned_details": null, "statement_descriptor": "Test xfer", "status": "processing", "status_transitions": { "canceled_at": null, "failed_at": null, "posted_at": null, "returned_at": null }, "transaction": "{{TRANSACTION_ID}}" } ``` ### ACH le jour même > ACH le jour même existe actuellement en version bêta avec une disponibilité limitée, sous réserve de l’examen et de l’approbation de Stripe. Pour demander un accès, envoyez un e-mail à [treasury-support@stripe.com](mailto:treasury-support@stripe.com). > > Si vous n’y avez pas accès, les appels à l’API qui incluent des fonctionnalités ou des paramètres ACH le jour même renvoient une erreur. L’utilisation de la fonctionnalité ACH le jour même permet d’envoyer des fonds qui arrivent le jour ouvrable même si l’appel `OutboundTransfer` aboutit avant l’[heure limite](https://docs.stripe.com/financial-accounts/connect/money-movement/timelines.md#bank-partner-timelines--outbound). Pour utiliser la fonctionnalité ACH le jour même, définissez le paramètre `destination_payment_method_options.us_bank_account.network` sur `ach` et le paramètre `destination_payment_method_options.us_bank_account.ach.submission` sur `same_day`. ### Virement bancaire : numéros de routage Pour les virements bancaires, certaines banques peuvent utiliser un numéro de routage distinct des virements ACH. Par conséquent, vous pourriez recevoir une erreur lors de la création du virement si le numéro de routage du moyen de paiement ne prend pas en charge les virements bancaires. Le cas échéant, vous devez ajouter un nouveau moyen de paiement avec le numéro de routage de votre banque. ### Virement bancaire : adresse du bénéficiaire Les virements bancaires nécessitent des métadonnées ACH ainsi que le nom du bénéficiaire et son adresse de facturation. L’adresse est celle du titulaire du compte recevant le virement et non l’adresse de sa banque. Lorsque vous saisissez l’adresse `billing_details.address` pour un moyen de paiement, tous les champs d’adresse doivent être renseignés. Si vous tentez d’effectuer un virement et que les champs de l’adresse `billing_details.address` sont incomplets, une erreur se produit. > Lors de l’envoi d’un virement à l’aide d’un `OutboundTransfer`, si vous ne remplissez pas les champs d’adresse, Stripe définit par défaut l’entité juridique du titulaire principal du compte Stripe. ## Récupérer un OutboundTransfer Utilisez `GET /v1/treasury/outbound_transfers/{{OUTBOUND_TRANSFER_ID}}` pour récupérer les informations de l’`OutboundTransfer` avec l’ID associé. La requête suivante permet de récupérer l’`OutboundTransfer` avec l’ID associé en développant les informations de la `Transaction`. ```curl curl -G https://api.stripe.com/v1/treasury/outbound_transfers/{{OUTBOUND_TRANSFER_ID}} \ -u "<>:" \ -H "Stripe-Account: {{CONNECTEDACCOUNT_ID}}" \ -d "expand[]=transaction" ``` Sauf échec de l’opération, la réponse renvoie l’objet `OutboundTransfer` et l’ID associé. Certains des paramètres de la réponse comportent des informations supplémentaires qui ne sont renvoyées que si vous les ajoutez comme valeurs au paramètre `expand[]`. Les champs que vous pouvez développer affichent le commentaire “Expandable”, comme illustré dans l’exemple de réponse suivant. Pour en savoir plus sur le développement des objets renvoyés, consultez la section [consacrée à ce sujet](https://docs.stripe.com/api/expanding_objects.md). #### JSON (commenté) ```json { "id": "{{OUTBOUND_TRANSFER_ID}}", "object": "outbound_transfer", "livemode": Boolean, "created": Timestamp, "financial_account": "{{FINANCIAL_ACCOUNT_ID}}", // Expandable "amount": 1000, "currency": "usd", "destination_payment_method": "{{PAYMENT_METHOD_ID}}", "description": "Transfer to my external account", "statement_descriptor": "Bank xfer", // For more information about status, see [OutboundTransfer states](#outbound-transfer-states) "status": "processing" | "failed" | "posted" | "returned" | "canceled", "status_transitions": { "canceled_at": nil | Timestamp, "failed_at": nil | Timestamp, "posted_at": nil | Timestamp, "returned_at": nil | Timestamp, }, // The local date when funds are expected to arrive in the // destination account // Set once the status is processing // Can change once set (for example, due to a partner delay) - Stripe fires a // `treasury.outbound_transfer.expected_arrival_date_updated` webhook when it does "expected_arrival_date": Timestamp, // Transaction representing balance impact of the OutboundTransfer, created // synchronously with the OutboundTransfer // OutboundTransfer always have a Transaction from creation (the funds are // held immediately). // If the OutboundTransfer fails, the Transaction will be voided // If the OutboundTransfer is returned, its Transaction remains posted // Funds are returned to the balance with returned_details.transaction "transaction": "{{TRANSACTION_ID}}", // Expandable // A unique, Stripe-hosted direct link to the regulatory receipt for this OutboundTransfer "hosted_regulatory_receipt_url": Url, "destination_payment_method_details": nil | { "type": "us_bank_acount", "billing_details": { "name": nil | String, "phone": nil | String, "email": nil | String, "address": nil | { "line1": nil | String, "line2": nil | String, "city": nil | String, "state": nil | String, "postal_code": nil | String, "country": nil | String } } }, // If the OutboundTransfer hasn't yet been sent, this field is `true`, indicating // that the user may still cancel through the cancel endpoint (POST v1/outbound_transfers/obt_123/cancel) "cancelable": Boolean, // If the OutboundTransfer has been returned, this field will be included with more // information about the return, including the transaction that returns the funds // The possible return codes and messages are listed below // See the "Handling Returned Funds" section below for more details on Returns. "returned_details": { "code": "account_closed" | "account_frozen" | "bank_account_restricted" | "bank_ownership_changed" | "could_not_process" | "invalid_account_number" | "incorrect_account_holder_name" | "invalid_currency" | "no_account" | "declined" // Generic fallback code // Human readable reason for the return. This message is geared towards the // end user, to help them determine next steps. "message": "The destination has been closed." | "The destination has been frozen." | "The destination bank account has restrictions on either the type or number of transfers allowed. This normally indicates that the bank account is a savings or other non-checking account." | "The destination bank account is no longer valid because its branch has changed ownership." | "The destination could not process this OutboundTransfer." | "The destination bank account details on file are probably incorrect. The routing number seems correct, but the account number is invalid." | "The destination bank account details on file may be incorrect." | "The destination was unable to process this OutboundTransfer because of its currency." | "The details of the destination may be incorrect." | "The destination has declined this OutboundTransfer." "transaction": "{{TRANSACTION_ID}}" // Expandable }, // If available, this field shows network-specific tracking information. // Tracking details can appear anytime after the object is no longer cancelable. // Stripe sends the `treasury.outbound_transfer.tracking_details_updated` event // when this field is updated. "tracking_details": nil | { "type": "ach" | "us_domestic_wire", // Only set for ACH transfers "ach": nil | { "trace_id": "12345678901234" }, // Only set for wire transfers "us_domestic_wire": nil | { "imad": "20230101MMQFMPD1001234", "omad": "20230101MMQFMPD1002345" } }, "metadata": {}, } ``` ## Annuler un OutboundTransfer Utilisez `POST /v1/treasury/outbound_transfers/{{OUTBOUND_TRANSFER_ID}}/cancel` pour annuler l’`OutboundTransfer` avec l’ID associé. L’objet `OutboundTransfer` inclut un paramètre `cancelable` dont la valeur booléenne indique si vous pouvez ou non annuler le transfert. Une fois que vous avez soumis un `OutboundTransfer` au réseau, la valeur `cancelable` bascule sur `false` et cet endpoint envoie une erreur pour le transfert. ```curl curl -X POST https://api.stripe.com/v1/treasury/outbound_transfers/{{OUTBOUND_TRANSFER_ID}}/cancel \ -u "<>:" \ -H "Stripe-Account: {{CONNECTEDACCOUNT_ID}}" ``` Sauf échec de l’opération, la réponse renvoie l’objet `OutboundTransfer` avec l’état `canceled`. ```json { "id": "{{OUTBOUND_TRANSFER_ID}} ", "object": "outbound_transfer", "amount": 1000, "cancelable": false, "created": 1648487177, "currency": "usd", ... "status": "canceled", "status_transitions": { "canceled_at": 1648487198, "failed_at": null, "posted_at": null, "returned_at": null }, "transaction": "{{TRANSACTION_ID}}" } ``` ## Répertorier les OutboundTransfers Utilisez `GET /v1/treasury/outbound_transfers` pour répertorier les `OutboundTransfers` envoyés depuis le compte financier avec l’ID du paramètre `financial_account`. Vous pouvez filtrer la liste en utilisant les paramètres de liste standard ou par `status`. ```json { // Standard list parameters "limit", "starting_after", "ending_before", // Filter by status "status": "processing" | "posted" | "failed" | "returned" | "canceled", // Filter by FinancialAccount (Required) "financial_account": "{{FINANCIAL_ACCOUNT_ID}}", } ``` La requête suivante permet de récupérer les `OutboundTransfers` provenant du compte financier identifié. Les paramètres inclus limitent la réponse aux trois premiers transferts suivant l’`OutboundTransfer` dont vous avez fourni l’ID. ```curl curl -G https://api.stripe.com/v1/treasury/outbound_transfers \ -u "<>:" \ -H "Stripe-Account: {{CONNECTEDACCOUNT_ID}}" \ -d "financial_account={{TREASURYFINANCIALACCOUNT_ID}}" \ -d limit=3 \ -d starting_after={{OUTBOUND_TRANSFER_ID}} ``` Sauf échec de l’opération, la réponse renvoie la liste des [objets OutboundTransfer](https://docs.stripe.com/api/treasury/outbound_transfers/object.md) qui respectent les critères de filtre. ## États OutboundTransfer Le tableau suivant détaille chaque `status` ainsi que les éventuels états de transition des `OutboundTransfers`. | ÉTAT | DESCRIPTION | PASSE À L’ÉTAT | | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | | `processing` | L’état initial de l’`OutboundTransfer`. Les fonds sont attribués à une transaction en attente (mais sont toujours conservés sur le solde actuel). L’utilisateur peut annuler l’`OutboundTransfer` tant que le paramètre `cancelable` est défini sur `true`. | `posted`, `canceled`, `failed` | | `canceled` (définitif) | Un utilisateur a annulé l’`OutboundTransfer` avant sa comptabilisation. Stripe annule la transaction en cours et restitue les fonds à l’utilisateur. | S.O. | | `posted` | Stripe a ajusté le solde du compte financier et a déterminé que le `OutboundTransfer` n’est pas susceptible d’être retourné. | `returned` | | `returned` (définitif) | L’`OutboundTransfer` n’a pas pu arriver à destination (en raison de coordonnées bancaires erronées par exemple). Stripe restitue les fonds à l’utilisateur avec `returned_details[transaction]`. | S.O. | | `failed` (définitif) | L’`OutboundTransfer` n’a pas pu être envoyé sur le réseau. Stripe annule la transaction en cours et restitue les fonds à l’utilisateur. Stripe peut utiliser cet état pour signaler des erreurs internes. | S.O. | ## Tester les OutboundTransfers En mode test, vous pouvez indiquer le `destination_payment_method` comme moyen de paiement de test. Lorsque vous testez votre intégration, vous pouvez créer vos propres [PaymentMethods](https://docs.stripe.com/api/payment_methods.md) en mode test ou utiliser nos ID de test. | TYPE | RÉSULTAT | MOYEN DE PAIEMENT | | ----------------- | ------------------------------------------------------------------------- | --------------------------------------------- | | `us_bank_account` | Par défaut, passe à `posted`. | `pm_usBankAccount` | | `us_bank_account` | Passe à `posted`, ajoute une journée à la date `expected_arrival_date`. | `pm_usBankAccount_expectedArrivalDateUpdated` | | `us_bank_account` | Reste sur `processing`. | `pm_usBankAccount_processing` | | `us_bank_account` | Passe à `canceled`. | `pm_usBankAccount_canceledByUser` | | `us_bank_account` | Passe à `failed`. | `pm_usBankAccount_internalFailure` | | `us_bank_account` | Passe à `returned` avec `returned_details.code="no_account"`. | `pm_usBankAccount_noAccount` | | `us_bank_account` | Passe à `returned` avec `returned_details.code="account_closed"`. | `pm_usBankAccount_accountClosed` | | `us_bank_account` | Passe à `returned` avec `returned_details.code="invalid_account_number"`. | `pm_usBankAccount_invalidAccountNumber` | Dans tous les cas, la réponse de l’objet `OutboundTransfer` présente l’état `processing`. Stripe déclenche des [webhooks](https://docs.stripe.com/webhooks.md) pour les changements d’état pertinents, et la récupération de l’objet `OutboundTransfer` après sa création renvoie l’état attendu. ### Endpoints d’aide au test des objets OutboundTransfer Stripe fournit des endpoints qui vous aident à tester des `OutboundTransfers` dans différents états. Après avoir créé un `OutboundTransfer`, utilisez ces endpoints pour le faire directement passer à l’état `posted`, `failed`, `canceled` ou `returned`. - Utilisez l’[endpoint de publication de test](https://docs.stripe.com/api/treasury/outbound_transfers/test_mode_post.md) pour faire passer l’état de l’objet `OutboundTransfer` identifié de `processing` (en cours de traitement) à `posted` (publié). `POST /v1/test_helpers/treasury/outbound_transfers/{{OUTBOUND_TRANSFER_ID}}/post` - Utilisez l’[endpoint d’échec de test](https://docs.stripe.com/api/treasury/outbound_transfers/test_mode_fail.md) pour faire passer l’état de l’objet `OutboundTransfer` identifié de `processing` (en cours de traitement) à `failed` (en échec). `POST /v1/test_helpers/treasury/outbound_transfers/{{OUTBOUND_TRANSFER_ID}}/fail` - Utilisez l’[endpoint de renvoi de test](https://docs.stripe.com/api/treasury/outbound_transfers/test_mode_return.md) pour faire passer l’état de l’objet `OutboundTransfer` identifié de `posted` (publié) à `returned` (renvoyé). `POST /v1/test_helpers/treasury/outbound_transfers/{{OUTBOUND_TRANSFER_ID}}/return` Ces endpoints sont particulièrement utiles pour tester des scénarios d’erreur, tels que des restitutions, qui nécessiteraient autrement une action extérieure. Pour l’endpoint `return`, incluez le paramètre facultatif `returned_details.code` dans le corps de la requête pour indiquer le motif de la restitution du transfert. Si vous ne fournissez pas ce paramètre, le transfert affiche par défaut le code de retour `declined`. ```json { "returned_details": { "code": "account_closed" | "account_frozen" | "bank_account_restricted" | "bank_ownership_changed" | "could_not_process" | "invalid_account_number" | "incorrect_account_holder_name" | "invalid_currency" | "no_account" | "declined" } } ``` Nous fournissons également un [endpoint de modification de test](https://docs.stripe.com/api/treasury/outbound_transfers/test_mode_update.md) pour simuler la publication des informations de suivi d’un `Outbound Transfer` de test. Le champ `tracking_details` peut uniquement être défini pour les objets de test. Dans tous les cas, Stripe déclenche des [webhooks](https://docs.stripe.com/webhooks.md) pour chaque changement d’état pertinent. La récupération de l’objet `OutboundTransfer` après le changement d’état renvoie l’état attendu. ## Webhooks OutboundTransfer Stripe émet les événements `OutboundTransfer` suivants à votre endpoint de [webhook](https://docs.stripe.com/webhooks.md) : - `treasury.outbound_transfer.created` à la création d’un OutboundTransfer. - `treasury.outbound_transfer.{{new_status}}` lorsqu’un OutboundTransfer change d’état. Il peut prendre les états suivants : - `treasury.outbound_transfer.posted` - `treasury.outbound_transfer.failed` - `treasury.outbound_transfer.returned` - `treasury.outbound_transfer.canceled` - `treasury.outbound_transfer.expected_arrival_date_updated` en cas de modification de la date `expected_arrival_date` d’un OutboundTransfer. - `treasury.outbound_transfer.tracking_details_updated` lorsque les informations de suivi d’un `OutboundTransfer` sont mis à jour.