# Collect an account to build data-powered products Collect your user's account and use data such as balances, ownership details, and transactions to build products. Available in: US Not sure about which Financial Connections integration to use? See our [overview of integration options](https://docs.stripe.com/financial-connections/use-cases.md). Financial Connections lets your users securely share their financial data by linking their external financial accounts to your business. You can use Financial Connections to access user-permissioned financial data such as tokenized account and routing numbers, account balances, account owner information, and historical transactions. Some common examples of how you can use Financial Connections to improve product experiences for your users include: - Mitigate fraud when onboarding a customer or business by verifying the [ownership](https://docs.stripe.com/financial-connections/ownership.md) information of an account, such as the name and address of the bank account holder. - Help your users track expenses, handle bills, manage their finances and take control of their financial well-being with [transactions](https://docs.stripe.com/financial-connections/transactions.md) data. - Speed up underwriting and improve access to credit and other financial services with transactions and balances data. - Enable your users to connect their accounts in fewer steps with Link, allowing them to save and reuse their bank account details across Stripe businesses. ## Configura Stripe [Lado del servidor] [Register](https://dashboard.stripe.com/financial-connections/application) for Financial Connections after we approve your account for live-mode access. Usa nuestras bibliotecas oficiales para acceder a la API de Stripe desde tu aplicación: #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ## Create or retrieve an account holder [Lado del servidor] Create a [Customer object](https://docs.stripe.com/api/customers/object.md) when users create an account with your business. By providing an email address, Financial Connections can optimize the [authentication flow](https://docs.stripe.com/financial-connections/fundamentals.md#authentication-flow) by dynamically showing a streamlined user interface, for returning [Link](https://support.stripe.com/questions/link-for-financial-connections-support-for-businesses) users. ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ -d email={{CUSTOMER_EMAIL}} \ -d name={{CUSTOMER_NAME}} ``` ## Create a Financial Connections Session [Lado del servidor] Before you can retrieve data from a user’s bank account with Financial Connections, your user must authenticate their account with the [authentication flow](https://docs.stripe.com/financial-connections/fundamentals.md#authentication-flow). Your user begins the authentication flow when they want to connect their account to your site or application. Insert a button or link on your site or in your application, which allows a user to link their account—for example, your button might say “Link your bank account”. Create a Financial Connections Session by posting to `/v1/financial_connections/sessions`: ```curl curl https://api.stripe.com/v1/financial_connections/sessions \ -u "<>:" \ -d "account_holder[type]=customer" \ -d "account_holder[customer]={{CUSTOMER_ID}}" \ -d "permissions[]=balances" \ -d "permissions[]=ownership" \ -d "permissions[]=payment_method" \ -d "permissions[]=transactions" ``` 1. Set `account_holder[customer]` to the Customer `id`. 1. Set the data `permissions` parameter to include the data required to fulfill your use case. 1. (Optional) set the `prefetch` parameter for retrieving the data on account creation. The [permissions](https://docs.stripe.com/api/financial_connections/sessions/create.md#financial_connections_create_session-permissions) parameter controls which account data you can access. You must request at least one permission. When completing the authentication flow, your user can see the data you’ve requested access to, and provide their consent to share it. Consider the data required to fulfill your use case and request permission to access only the data you need. Requesting permissions that go well beyond your application’s scope might erode your users’ trust in how you use their data. For example, if you’re building a personal financial management application or a lending product, you might request `transactions` data. If you’re mitigating fraud such as account takeovers, you might want to request `ownership` details. After your user authenticates their account, you can expand data permissions only by creating a new Financial Connections Session and specifying a new value for the `permissions` parameter. Your user must complete the authentication flow again, where they’ll see the additional data you’ve requested permission to access, and provide consent to share their data. The optional [prefetch parameter](https://docs.stripe.com/api/financial_connections/sessions/create.md#financial_connections_create_session-prefetch) controls which data you retrieve immediately after the user connects their account. Use this option if you know you always want a certain type of data. It removes the need to make an extra API call to initiate a [data refresh](https://docs.stripe.com/api/financial_connections/accounts/refresh.md). To preserve the option to [accept ACH Direct Debit payments](https://docs.stripe.com/financial-connections/other-data-powered-products.md#accept-ach-direct-debit), request the `payment_method` permission. ## Collect a Financial Connections account [Lado del cliente] Use the returned `client_secret` with Stripe.js to allow your user to connect their accounts. A `client_secret` allows client-side Stripe SDKs to make changes to the Financial Connections Session. Don’t store it, log it, embed it in URLs, or expose it to anyone other than your end user. Make sure that you have [TLS](https://docs.stripe.com/security/guide.md#tls) enabled on any page that includes the client secret. Use [collectFinancialConnectionsAccounts](https://docs.stripe.com/js/financial_connections/collect_financial_connections_accounts) to collect an account. ```javascript const stripe = new Stripe('<>') const financialConnectionsSessionResult = await stripe.collectFinancialConnectionsAccounts({ clientSecret: "{{SESSION_CLIENT_SECRET}}", }); ``` This method loads the [authentication flow](https://docs.stripe.com/financial-connections/fundamentals.md#authentication-flow), the client-side Stripe.js UI that helps your users link their financial accounts to you and Stripe. The return value of `stripe.collectFinancialConnectionsAccounts` is a Promise. When the user completes the authentication flow, the Promise resolves with an object that contains the list of connected accounts: ```json { "financialConnectionsSession": { "id": "fcsess_123", "accounts": [ { "id": "fca_456", "object": "financial_connections.account", "category": "Checking", "display_name": "Premium Checking", "institution_name": "Test Bank", "last4": "4242" } ] } } ``` If the user connects no accounts, or exits the authentication flow early, the response contains an empty `accounts` array. Successful completion of the authentication flow also sends one `financial_connections.account.created` webhook per account connected. ## Retrieve data on a Financial Connections account [Lado del servidor] After your user has successfully completed the authentication flow, access or refresh the account data you’ve specified in the `permissions` parameter of the Financial Connections Session. To protect the privacy of your user’s data, account data accessible to you is limited to the data you’ve specified in the `permissions` parameter. Follow the guides for [balances](https://docs.stripe.com/financial-connections/balances.md), [ownership](https://docs.stripe.com/financial-connections/ownership.md) and [transactions](https://docs.stripe.com/financial-connections/transactions.md) to start retrieving account data. ## Optional: Accept an ACH Direct Debit payment from a Financial Connections account You can optionally accept ACH Direct Debit payments on a previously collected Financial Connections account as long as the `supported_payment_method_types` attribute on the account includes `us_bank_account`. Only US bank accounts are eligible to accept ACH Direct Debits such as a checking or savings account. To accept an ACH Direct Debit payment on a previously collected account, you must have specified `payment_method` in the [data permissions](https://docs.stripe.com/financial-connections/fundamentals.md#data-permissions) parameter on the Financial Connections Session. ### Create a Payment Intent or Setup Intent Use the *Payment Intents API* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) to accept an ACH Direct payment for an account you want to charge now. Use the *Setup Intents API* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) to save details for future ACH Direct Debit payments. [Learn more about the difference between a](https://support.stripe.com/questions/payment-intents-api-vs-setup-intents-api) Payment Intent and Setup Intent. This path shows you how to accept an ACH Direct Debit payment using the Payment Intents API. Use the Financial Connections account ID and the customer ID to create a Payment Intent: ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d "payment_method_types[]=us_bank_account" \ -d "payment_method_data[us_bank_account][financial_connections_account]={{FINANCIALCONNECTIONSACCOUNT_ID}}" \ -d "payment_method_data[type]=us_bank_account" \ -d "payment_method_data[billing_details][name]=J. Customer" \ -d amount=100 \ -d currency=usd ``` This will return a Payment Intent similar to: ```json { "id": "pi_1GszXf2eZvKYlo2Ce7rjvnPP", "object": "payment_intent", "amount": 100, "amount_capturable": 0, "amount_details": { "tip": { "amount": null } }, "amount_received": 0, "application": null, "application_fee_amount": null, "automatic_payment_methods": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "charges": { "object": "list", "data": [ ], "has_more": false, "total_count": 0, "url": "/v1/charges?payment_intent=pi_1GszXf2eZvKYlo2Ce7rjvnPP" }, "client_secret": "pi_1GszXf2eZvKYlo2Ce7rjvnPP", "confirmation_method": "automatic", "created": 1651010665, "currency": "usd", "customer": null, "description": null, "invoice": null, "last_payment_error": null, "livemode": false, "metadata": { }, "next_action": null, "on_behalf_of": null, "payment_method": "pm_1Mb4UkJGNKiWrCEmJ1PS72Cd", "payment_method_options": { "us_bank_account": { "verification_method": "automatic" } }, "payment_method_types": [ "us_bank_account" ], "processing": null, "receipt_email": null, "review": null, "setup_future_usage": null, "shipping": null, "source": null, "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "requires_confirmation", "transfer_data": null, "transfer_group": null } ``` ### Collect mandate acknowledgement and submit the payment Before you can initiate the payment, you must obtain authorization from your customer by displaying mandate terms for them to accept. To be compliant with Nacha rules, you must obtain authorization from your customer before you can initiate payment by displaying mandate terms for them to accept. For more information on mandates, see [Mandates](https://docs.stripe.com/payments/ach-direct-debit.md#mandates). ### Confirm the Payment Intent To confirm this Payment Intent, you need to provide either a [`mandate` parameter](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-mandate) with an existing Mandate ID, or provide [mandate_data](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-mandate_data) to create a new mandate. For example, if you have a checkout page with a “Place Order” button, clicking that button could trigger a `POST` to an endpoint on your server. That endpoint could extract the request’s User Agent and the client’s IP address, and then make the following request to Stripe’s API: ```curl curl https://api.stripe.com/v1/payment_intents/{{PAYMENTINTENT_ID}}/confirm \ -u "<>:" \ -d "mandate_data[customer_acceptance][accepted_at]=1647448692" \ -d "mandate_data[customer_acceptance][type]=online" \ -d "mandate_data[customer_acceptance][online][ip_address]=71.183.194.54" \ --data-urlencode "mandate_data[customer_acceptance][online][user_agent]=Mozilla/5.0 ..." ``` After successfully confirming the Payment Intent, it will look similar to: ```json { "id": "pi_1GszXf2eZvKYlo2Ce7rjvnPP", "object": "payment_intent", "amount": 100, "amount_capturable": 0, "amount_received": 0, "application": null, "application_fee_amount": null, "automatic_payment_methods": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "charges": { "object": "list", "data": [ { "id": "py_17F8CPDyDglZKgWE3uzOAUe9", "object": "charge", "amount": 100, "amount_captured": 100, "amount_refunded": 0, "application": null, "application_fee": null, "application_fee_amount": null, "balance_transaction": null, "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": "J. Customer", "phone": null }, "calculated_statement_descriptor": null, "captured": true, "created": 1647448692, "currency": "usd", "customer": "cus_LKe65xcPnrCiTZ", "description": null, "destination": null, "dispute": null, "disputed": false, "failure_code": null, "failure_message": null, "fraud_details": { }, "invoice": null, "livemode": false, "metadata": { }, "on_behalf_of": null, "order": null, "outcome": null, "paid": false, "payment_intent": "pi_1GszXf2eZvKYlo2Ce7rjvnPP", "payment_method": "pm_1Mb4UkJGNKiWrCEmJ1PS72Cd", "payment_method_details": { "type": "us_bank_account", "us_bank_account": { "account_holder_type": "individual", "account_type": "checking", "bank_name": "STRIPE TEST BANK", "fingerprint": "QnXqpAeqjjh8pPFa", "last4": "6789", "routing_number": "110000000" } }, "receipt_email": null, "receipt_number": null, "receipt_url": null, "refunded": false, "refunds": { "object": "list", "data": [ ], "has_more": false, "total_count": 0, "url": "/v1/charges/py_17F8CPDyDglZKgWE3uzOAUe9/refunds" }, "review": null, "shipping": null, "source": null, "source_transfer": null, "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "pending", "transfer_data": null, "transfer_group": null } ], "has_more": false, "total_count": 1, "url": "/v1/charges?payment_intent=pi_1GszXf2eZvKYlo2Ce7rjvnPP" }, "client_secret": "pi_1GszXf2eZvKYlo2Ce7rjvnPP_secret_m38BKZvm3vSdpGdra360hPEov", "confirmation_method": "automatic", "created": 1647447792, "currency": "usd", "customer": "cus_LKe65xcPnrCiTZ", "description": null, "invoice": null, "last_payment_error": null, "livemode": false, "metadata": { }, "next_action": null, "on_behalf_of": null, "payment_method": "pm_1Mb4UkJGNKiWrCEmJ1PS72Cd", "payment_method_options": { "us_bank_account": { "verification_method": "automatic" } }, "payment_method_types": [ "us_bank_account" ], "processing": null, "receipt_email": null, "review": null, "setup_future_usage": null, "shipping": null, "source": null, "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "processing", "transfer_data": null, "transfer_group": null } ``` ACH Direct Debit is a *delayed notification payment method* (A payment method that can't immediately return payment status when a customer attempts a transaction (for example, ACH debits). Businesses commonly hold an order in a pending state until payment is successful with these payment methods). This means that it can take up to four business days to receive notification of the success or failure of a payment after you initiate a debit from your customer’s account. The PaymentIntent you create initially has a status of `processing`. After the payment succeeds, the PaymentIntent status is updated from `processing` to `succeeded`. Learn about the events that are sent when the [PaymentIntent status is updated](https://docs.stripe.com/payments/ach-direct-debit/accept-a-payment.md#web-confirm-paymentintent-succeeded). Available in: US Not sure about which Financial Connections integration to use? See our [overview of integration options](https://docs.stripe.com/financial-connections/use-cases.md). Financial Connections lets your users securely share their financial data by linking their external financial accounts to your business. You can use Financial Connections to access user-permissioned financial data such as tokenized account and routing numbers, account balances, account owner information, and historical transactions. Some common examples of how you can use Financial Connections to improve product experiences for your users include: - Mitigate fraud when onboarding a customer or business by verifying the [ownership](https://docs.stripe.com/financial-connections/ownership.md) information of an account, such as the name and address of the bank account holder. - Help your users track expenses, handle bills, manage their finances and take control of their financial well-being with [transactions](https://docs.stripe.com/financial-connections/transactions.md) data. - Speed up underwriting and improve access to credit and other financial services with transactions and balances data. - Enable your users to connect their accounts in fewer steps with Link, allowing them to save and reuse their bank account details across Stripe businesses. ## Configura Stripe [Lado del servidor] [Lado del cliente] [Register](https://dashboard.stripe.com/financial-connections/application) for Financial Connections after your account is approved for live-mode access. ### Lado del servidor Esta integración necesita puntos de conexión de tu servidor que se comuniquen con la API de Stripe. Usa las bibliotecas oficiales para acceder a la API de Stripe desde tu servidor: #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ### Lado del cliente El [SDK para iOS de Stripe](https://github.com/stripe/stripe-ios) es de código abierto, está [plenamente documentado](https://stripe.dev/stripe-ios/index.html) y es compatible con aplicaciones que admiten iOS 13 o posterior. #### Administrador de paquetes Swift Para instalar el SDK, sigue estos pasos: 1. En Xcode, elige **Archivo** > **Añadir dependencias de paquetes…** e introduce `https://github.com/stripe/stripe-ios-spm` como la URL del repositorio. 1. Selecciona el número de versión más reciente en nuestra [página de versiones](https://github.com/stripe/stripe-ios/releases). 1. Añade el producto **StripeFinancialConnections** al [objetivo de tu aplicación](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app). #### CocoaPods 1. Si aún no lo has hecho, instala la última versión de [CocoaPods](https://guides.cocoapods.org/using/getting-started.html). 1. Si no tienes un [Podfile](https://guides.cocoapods.org/syntax/podfile.html), ejecuta el siguiente comando para crear uno: ```bash pod init ``` 1. Añade esta línea a tu `Podfile`: ```podfile pod 'StripeFinancialConnections' ``` 1. Ejecuta el siguiente comando: ```bash pod install ``` 1. De ahora en adelante, no olvides usar el archivo `.xcworkspace` en lugar del archivo `.xcodeproj` para abrir tu proyecto en Xcode. 1. En el futuro, para actualizar a la última versión del SDK, ejecuta lo siguiente: ```bash pod update StripeFinancialConnections ``` #### Carthage 1. Si aún no lo has hecho, instala la última versión de [Carthage](https://github.com/Carthage/Carthage#installing-carthage). 1. Añade esta línea a tu `Cartfile`: ```cartfile github "stripe/stripe-ios" ``` 1. Sigue las [instrucciones de instalación de Carthage](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos). Asegúrate de incrustar todos los frameworks obligatorios enumerados [aquí](https://github.com/stripe/stripe-ios/blob/master/StripeFinancialConnections/README.md#manual-linking). 1. En el futuro, para actualizar a la última versión del SDK, ejecuta el siguiente comando: ```bash carthage update stripe-ios --platform ios ``` #### Plataforma manual 1. Ve a nuestra [página de versiones de GitHub](https://github.com/stripe/stripe-ios/releases/latest) y descarga y descomprime **Stripe.xcframework.zip**. 1. Arrastra **StripeFinancialConnections.xcframework** a la sección **Binarios incrustados** de la configuración **General** de tu proyecto en Xcode. Asegúrate de seleccionar **Copiar elementos si es necesario**. 1. Repite el paso 2 para todos los frameworks obligatorios enumerados [here](https://github.com/stripe/stripe-ios/blob/master/StripeFinancialConnections/README.md#manual-linking). 1. En el futuro, para actualizar a la última versión de nuestro SDK, repite los pasos 1 a 3. > Para obtener más información sobre la versión más reciente y sobre versiones anteriores del SDK, consulta la página [Versiones](https://github.com/stripe/stripe-ios/releases) en GitHub. Para recibir notificaciones cuando se publica una nueva versión, [consulta las versiones](https://help.github.com/en/articles/watching-and-unwatching-releases-for-a-repository#watching-releases-for-a-repository) del repositorio. ## Create or retrieve an account holder [Lado del servidor] Create a [Customer object](https://docs.stripe.com/api/customers/object.md) when users create an account with your business. By providing an email address, Financial Connections can optimize the [authentication flow](https://docs.stripe.com/financial-connections/fundamentals.md#authentication-flow) by dynamically showing a streamlined user interface, for returning [Link](https://support.stripe.com/questions/link-for-financial-connections-support-for-businesses) users. ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ -d email={{CUSTOMER_EMAIL}} \ -d name={{CUSTOMER_NAME}} ``` ## Create a Financial Connections Session [Lado del servidor] > You can find a running implementation of this endpoint [available on Glitch](https://glitch.com/edit/#!/remix/stripe-mobile-connections-example) for quick testing. Before you can retrieve data from a user’s bank account with Financial Connections, your user must authenticate their account with the [authentication flow](https://docs.stripe.com/financial-connections/fundamentals.md#authentication-flow). Your user begins the authentication flow when they want to connect their account to your site or application. Insert a button or link on your site or in your application, which allows a user to link their account—for example, your button might say “Link your bank account”. Create a Financial Connections Session by posting to `/v1/financial_connections/sessions`: ```curl curl https://api.stripe.com/v1/financial_connections/sessions \ -u "<>:" \ -d "account_holder[type]=customer" \ -d "account_holder[customer]={{CUSTOMER_ID}}" \ -d "permissions[]=balances" \ -d "permissions[]=ownership" \ -d "permissions[]=payment_method" \ -d "permissions[]=transactions" ``` 1. Set `account_holder[customer]` to the Customer `id`. 1. Set the data `permissions` parameter to include the data required to fulfill your use case. 1. (Optional) set the `prefetch` parameter for retrieving the data on account creation. The [permissions](https://docs.stripe.com/api/financial_connections/sessions/create.md#financial_connections_create_session-permissions) parameter controls which account data you can access. You must request at least one permission. When completing the authentication flow, your user can see the data you’ve requested access to, and provide their consent to share it. Consider the data required to fulfill your use case and request permission to access only the data you need. Requesting permissions that go well beyond your application’s scope might erode your users’ trust in how you use their data. For example, if you’re building a personal financial management application or a lending product, you might request `transactions` data. If you’re mitigating fraud such as account takeovers, you might want to request `ownership` details. After your user authenticates their account, you can expand data permissions only by creating a new Financial Connections Session and specifying a new value for the `permissions` parameter. Your user must complete the authentication flow again, where they’ll see the additional data you’ve requested permission to access, and provide consent to share their data. The optional [prefetch parameter](https://docs.stripe.com/api/financial_connections/sessions/create.md#financial_connections_create_session-prefetch) controls which data you retrieve immediately after the user connects their account. Use this option if you know you always want a certain type of data. It removes the need to make an extra API call to initiate a [data refresh](https://docs.stripe.com/api/financial_connections/accounts/refresh.md). To preserve the option to [accept ACH Direct Debit payments](https://docs.stripe.com/financial-connections/other-data-powered-products.md#accept-ach-direct-debit), request the `payment_method` permission. ## Set up a return URL [Client-side] Es posible que el cliente salga de tu aplicación para autenticarse (por ejemplo, en Safari o en su aplicación bancaria). Para permitirles volver automáticamente a tu aplicación después de la autenticación, [configura un esquema de URL personalizado](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app) y configura el delegado de la aplicación para que envíe la URL al SDK. Stripe no admite [enlaces universales](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content). > Stripe podría agregar parámetros adicionales a la URL de retorno proporcionada. Asegúrate de que tu código no rechace las URL de retorno con parámetros adicionales. #### SceneDelegate #### Swift ```swift // This method handles opening custom URL schemes (for example, "your-app://stripe-redirect") func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { guard let url = URLContexts.first?.url else { return } let stripeHandled = StripeAPI.handleURLCallback(with: url) if (!stripeHandled) { // This was not a Stripe url – handle the URL normally as you would } } ``` #### AppDelegate #### Swift ```swift // This method handles opening custom URL schemes (for example, "your-app://stripe-redirect") func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { let stripeHandled = StripeAPI.handleURLCallback(with: url) if (stripeHandled) { return true } else { // This was not a Stripe url – handle the URL normally as you would } return false } ``` #### SwiftUI #### Swift ```swift @main struct MyApp: App { var body: some Scene { WindowGroup { Text("Hello, world!").onOpenURL { incomingURL in let stripeHandled = StripeAPI.handleURLCallback(with: incomingURL) if (!stripeHandled) { // This was not a Stripe url – handle the URL normally as you would } } } } } ``` ## Integrate FinancialConnectionsSheet [Lado del cliente] Before displaying the Financial Connections flow, your page should include a **Connect Financial Account** button to present the Stripe’s UI. In your app, retrieve the `FinancialConnectionsSession` *client secret* (A client secret is used with your publishable key to authenticate a request for a single object. Each client secret is unique to the object it's associated with) and publishable key from the endpoint you created in the previous step. Set your publishable key using `StripeAPI.shared` and initialize `FinancialConnectionsSheet`. Pass the `returnURL` you set up in the previous step. #### Swift ```swift import StripeFinancialConnections class ViewController: UIViewController { @IBOutlet weak var connectFinancialAccountButton: UIButton! var financialConnectionsSheet: FinancialConnectionsSheet? let backendCheckoutUrl = URL(string: "Your backend endpoint")! // Your backend endpoint override func viewDidLoad() { super.viewDidLoad() connectFinancialAccountButton.addTarget(self, action: #selector(didTapConnectFinancialAccountButton), for: .touchUpInside) connectFinancialAccountButton.isEnabled = false // MARK: Fetch the FinancialConnectionsSession client secret and publishable key var request = URLRequest(url: backendCheckoutUrl) request.httpMethod = "POST" let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any], let clientSecret = json["client_secret"] as? String, let publishableKey = json["publishable_key"] as? String, let self = self else { // Handle error return } // MARK: Set your Stripe publishable key - this allows the SDK to make requests to Stripe for your account STPAPIClient.shared.publishableKey = publishableKey self.financialConnectionsSheet = FinancialConnectionsSheet( financialConnectionsSessionClientSecret: clientSecret, returnURL: "https://your-app-domain.com/stripe-redirect" ) DispatchQueue.main.async { self.connectFinancialAccountButton.isEnabled = true } }) task.resume() } @objc func didTapConnectFinancialAccountButton() { // implemented in the next steps } } ``` When the customer taps the **Connect Financial Account** button, call `FinancialConnectionsSheet#present` to present the financial connections sheet. After the customer completes the financial connections flow, the sheet is dismissed and the completion block is called with a `FinancialConnectionsSheetResult`. #### Swift ```swift @objc func didTapConnectFinancialAccountButton() {// MARK: Start the financial connections flow financialConnectionsSheet?.present( from: self, completion: { result in switch result { case .completed(session: let financialConnectionsSession): let accounts = financialConnectionsSession.accounts.data.filter { $0.last4 != nil } let accountInfos = accounts.map { "\($0.institutionName) ....\($0.last4!)" } print("Completed with \(accountInfos.joined(separator: "\n")) accounts") case .canceled: print("Canceled!") case .failed(let error): print("Failed!") print(error) } }) } ``` ## Retrieve data on a Financial Connections account [Lado del servidor] After your user has successfully completed the authentication flow, access or refresh the account data you’ve specified in the `permissions` parameter of the Financial Connections Session. To protect the privacy of your user’s data, account data accessible to you is limited to the data you’ve specified in the `permissions` parameter. Follow the guides for [balances](https://docs.stripe.com/financial-connections/balances.md), [ownership](https://docs.stripe.com/financial-connections/ownership.md) and [transactions](https://docs.stripe.com/financial-connections/transactions.md) to start retrieving account data. ## Optional: Customize the sheet [Client-side] All customization configurations use the `FinancialConnectionsSheet.Configuration` object. ### Dark mode `FinancialConnectionsSheet` automatically adapts to the user’s system-wide appearance settings (light and dark mode). If your app doesn’t support dark mode, you can set `style` to `alwaysLight` or `alwaysDark` mode. ```swift var configuration = FinancialConnectionsSheet.Configuration() configuration.style = .alwaysLight ``` > When `FinancialConnectionsSheet` is launched through the [PaymentSheet SDK](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=mobile&platform=ios), the [style](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=mobile&platform=ios#dark-mode) specified in the `PaymentSheet.Configuration` is automatically inherited. ## Optional: Accept an ACH Direct Debit payment from a Financial Connections account You can optionally accept ACH Direct Debit payments on a previously collected Financial Connections account as long as the `supported_payment_method_types` attribute on the account includes `us_bank_account`. Only US bank accounts are eligible to accept ACH Direct Debits such as a checking or savings account. To accept an ACH Direct Debit payment on a previously collected account, you must have specified `payment_method` in the [data permissions](https://docs.stripe.com/financial-connections/fundamentals.md#data-permissions) parameter on the Financial Connections Session. ### Create a Payment Intent or Setup Intent Use the *Payment Intents API* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) to accept an ACH Direct payment for an account you want to charge now. Use the *Setup Intents API* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) to save details for future ACH Direct Debit payments. [Learn more about the difference between a](https://support.stripe.com/questions/payment-intents-api-vs-setup-intents-api) Payment Intent and Setup Intent. This path shows you how to accept an ACH Direct Debit payment using the Payment Intents API. Use the Financial Connections account ID and the customer ID to create a Payment Intent: ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d "payment_method_types[]=us_bank_account" \ -d "payment_method_data[us_bank_account][financial_connections_account]={{FINANCIALCONNECTIONSACCOUNT_ID}}" \ -d "payment_method_data[type]=us_bank_account" \ -d "payment_method_data[billing_details][name]=J. Customer" \ -d amount=100 \ -d currency=usd ``` This will return a Payment Intent similar to: ```json { "id": "pi_1GszXf2eZvKYlo2Ce7rjvnPP", "object": "payment_intent", "amount": 100, "amount_capturable": 0, "amount_details": { "tip": { "amount": null } }, "amount_received": 0, "application": null, "application_fee_amount": null, "automatic_payment_methods": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "charges": { "object": "list", "data": [ ], "has_more": false, "total_count": 0, "url": "/v1/charges?payment_intent=pi_1GszXf2eZvKYlo2Ce7rjvnPP" }, "client_secret": "pi_1GszXf2eZvKYlo2Ce7rjvnPP", "confirmation_method": "automatic", "created": 1651010665, "currency": "usd", "customer": null, "description": null, "invoice": null, "last_payment_error": null, "livemode": false, "metadata": { }, "next_action": null, "on_behalf_of": null, "payment_method": "pm_1Mb4UkJGNKiWrCEmJ1PS72Cd", "payment_method_options": { "us_bank_account": { "verification_method": "automatic" } }, "payment_method_types": [ "us_bank_account" ], "processing": null, "receipt_email": null, "review": null, "setup_future_usage": null, "shipping": null, "source": null, "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "requires_confirmation", "transfer_data": null, "transfer_group": null } ``` ### Collect mandate acknowledgement and submit the payment Before you can initiate the payment, you must obtain authorization from your customer by displaying mandate terms for them to accept. To be compliant with Nacha rules, you must obtain authorization from your customer before you can initiate payment by displaying mandate terms for them to accept. For more information on mandates, see [Mandates](https://docs.stripe.com/payments/ach-direct-debit.md#mandates). ### Confirm the Payment Intent To confirm this Payment Intent, you need to provide either a [`mandate` parameter](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-mandate) with an existing Mandate ID, or provide [mandate_data](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-mandate_data) to create a new mandate. For example, if you have a checkout page with a “Place Order” button, clicking that button could trigger a `POST` to an endpoint on your server. That endpoint could extract the request’s User Agent and the client’s IP address, and then make the following request to Stripe’s API: ```curl curl https://api.stripe.com/v1/payment_intents/{{PAYMENTINTENT_ID}}/confirm \ -u "<>:" \ -d "mandate_data[customer_acceptance][accepted_at]=1647448692" \ -d "mandate_data[customer_acceptance][type]=online" \ -d "mandate_data[customer_acceptance][online][ip_address]=71.183.194.54" \ --data-urlencode "mandate_data[customer_acceptance][online][user_agent]=Mozilla/5.0 ..." ``` After successfully confirming the Payment Intent, it will look similar to: ```json { "id": "pi_1GszXf2eZvKYlo2Ce7rjvnPP", "object": "payment_intent", "amount": 100, "amount_capturable": 0, "amount_received": 0, "application": null, "application_fee_amount": null, "automatic_payment_methods": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "charges": { "object": "list", "data": [ { "id": "py_17F8CPDyDglZKgWE3uzOAUe9", "object": "charge", "amount": 100, "amount_captured": 100, "amount_refunded": 0, "application": null, "application_fee": null, "application_fee_amount": null, "balance_transaction": null, "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": "J. Customer", "phone": null }, "calculated_statement_descriptor": null, "captured": true, "created": 1647448692, "currency": "usd", "customer": "cus_LKe65xcPnrCiTZ", "description": null, "destination": null, "dispute": null, "disputed": false, "failure_code": null, "failure_message": null, "fraud_details": { }, "invoice": null, "livemode": false, "metadata": { }, "on_behalf_of": null, "order": null, "outcome": null, "paid": false, "payment_intent": "pi_1GszXf2eZvKYlo2Ce7rjvnPP", "payment_method": "pm_1Mb4UkJGNKiWrCEmJ1PS72Cd", "payment_method_details": { "type": "us_bank_account", "us_bank_account": { "account_holder_type": "individual", "account_type": "checking", "bank_name": "STRIPE TEST BANK", "fingerprint": "QnXqpAeqjjh8pPFa", "last4": "6789", "routing_number": "110000000" } }, "receipt_email": null, "receipt_number": null, "receipt_url": null, "refunded": false, "refunds": { "object": "list", "data": [ ], "has_more": false, "total_count": 0, "url": "/v1/charges/py_17F8CPDyDglZKgWE3uzOAUe9/refunds" }, "review": null, "shipping": null, "source": null, "source_transfer": null, "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "pending", "transfer_data": null, "transfer_group": null } ], "has_more": false, "total_count": 1, "url": "/v1/charges?payment_intent=pi_1GszXf2eZvKYlo2Ce7rjvnPP" }, "client_secret": "pi_1GszXf2eZvKYlo2Ce7rjvnPP_secret_m38BKZvm3vSdpGdra360hPEov", "confirmation_method": "automatic", "created": 1647447792, "currency": "usd", "customer": "cus_LKe65xcPnrCiTZ", "description": null, "invoice": null, "last_payment_error": null, "livemode": false, "metadata": { }, "next_action": null, "on_behalf_of": null, "payment_method": "pm_1Mb4UkJGNKiWrCEmJ1PS72Cd", "payment_method_options": { "us_bank_account": { "verification_method": "automatic" } }, "payment_method_types": [ "us_bank_account" ], "processing": null, "receipt_email": null, "review": null, "setup_future_usage": null, "shipping": null, "source": null, "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "processing", "transfer_data": null, "transfer_group": null } ``` ACH Direct Debit is a *delayed notification payment method* (A payment method that can't immediately return payment status when a customer attempts a transaction (for example, ACH debits). Businesses commonly hold an order in a pending state until payment is successful with these payment methods). This means that it can take up to four business days to receive notification of the success or failure of a payment after you initiate a debit from your customer’s account. The PaymentIntent you create initially has a status of `processing`. After the payment succeeds, the PaymentIntent status is updated from `processing` to `succeeded`. Learn about the events that are sent when the [PaymentIntent status is updated](https://docs.stripe.com/payments/ach-direct-debit/accept-a-payment.md#web-confirm-paymentintent-succeeded). Available in: US Not sure about which Financial Connections integration to use? See our [overview of integration options](https://docs.stripe.com/financial-connections/use-cases.md). Financial Connections lets your users securely share their financial data by linking their external financial accounts to your business. You can use Financial Connections to access user-permissioned financial data such as tokenized account and routing numbers, account balances, account owner information, and historical transactions. Some common examples of how you can use Financial Connections to improve product experiences for your users include: - Mitigate fraud when onboarding a customer or business by verifying the [ownership](https://docs.stripe.com/financial-connections/ownership.md) information of an account, such as the name and address of the bank account holder. - Help your users track expenses, handle bills, manage their finances and take control of their financial well-being with [transactions](https://docs.stripe.com/financial-connections/transactions.md) data. - Speed up underwriting and improve access to credit and other financial services with transactions and balances data. - Enable your users to connect their accounts in fewer steps with Link, allowing them to save and reuse their bank account details across Stripe businesses. ## Configura Stripe [Lado del servidor] [Lado del cliente] [Register](https://dashboard.stripe.com/financial-connections/application) for Financial Connections after your account is approved for live-mode access. ### Lado del servidor This integration requires endpoints on your server that communicate with the Stripe API. Use the official libraries for access to the Stripe API from your server: #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ### Lado del cliente El [SDK para Android de Stripe](https://github.com/stripe/stripe-android) es de código abierto y está [completamente documentado](https://stripe.dev/stripe-android/). Para instalar el SDK, añade `financial-connections` al bloque `dependencies` de tu archivo [app/build.gradle](https://developer.android.com/studio/build/dependencies): #### Kotlin ```kotlin plugins { id("com.android.application") } android { ... } dependencies { // ... // Financial Connections Android SDK implementation("com.stripe:financial-connections:23.2.0") } ``` > Para conocer detalles de la última versión y de versiones anteriores del SDK, consulta la página [Versiones](https://github.com/stripe/stripe-android/releases) de GitHub. Para recibir una notificación cuando se publique una nueva versión, [mira las versiones del repositorio](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository). ## Create or retrieve an account holder [Lado del servidor] Create a [Customer object](https://docs.stripe.com/api/customers/object.md) when users create an account with your business. By providing an email address, Financial Connections can optimize the [authentication flow](https://docs.stripe.com/financial-connections/fundamentals.md#authentication-flow) by dynamically showing a streamlined user interface, for returning [Link](https://support.stripe.com/questions/link-for-financial-connections-support-for-businesses) users. ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ -d email={{CUSTOMER_EMAIL}} \ -d name={{CUSTOMER_NAME}} ``` ## Create a Financial Connections Session [Lado del servidor] > You can find a running implementation of this endpoint [available on Glitch](https://glitch.com/edit/#!/remix/stripe-mobile-connections-example) for quick testing. Before you can retrieve data from a user’s bank account with Financial Connections, your user must authenticate their account with the [authentication flow](https://docs.stripe.com/financial-connections/fundamentals.md#authentication-flow). Your user begins the authentication flow when they want to connect their account to your site or application. Insert a button or link on your site or in your application, which allows a user to link their account—for example, your button might say “Link your bank account”. Create a Financial Connections Session by posting to `/v1/financial_connections/sessions`: ```curl curl https://api.stripe.com/v1/financial_connections/sessions \ -u "<>:" \ -d "account_holder[type]=customer" \ -d "account_holder[customer]={{CUSTOMER_ID}}" \ -d "permissions[]=balances" \ -d "permissions[]=ownership" \ -d "permissions[]=payment_method" \ -d "permissions[]=transactions" ``` 1. Set `account_holder[customer]` to the Customer `id`. 1. Set the data `permissions` parameter to include the data required to fulfill your use case. 1. (Optional) set the `prefetch` parameter for retrieving the data on account creation. The [permissions](https://docs.stripe.com/api/financial_connections/sessions/create.md#financial_connections_create_session-permissions) parameter controls which account data you can access. You must request at least one permission. When completing the authentication flow, your user can see the data you’ve requested access to, and provide their consent to share it. Consider the data required to fulfill your use case and request permission to access only the data you need. Requesting permissions that go well beyond your application’s scope might erode your users’ trust in how you use their data. For example, if you’re building a personal financial management application or a lending product, you might request `transactions` data. If you’re mitigating fraud such as account takeovers, you might want to request `ownership` details. After your user authenticates their account, you can expand data permissions only by creating a new Financial Connections Session and specifying a new value for the `permissions` parameter. Your user must complete the authentication flow again, where they’ll see the additional data you’ve requested permission to access, and provide consent to share their data. The optional [prefetch parameter](https://docs.stripe.com/api/financial_connections/sessions/create.md#financial_connections_create_session-prefetch) controls which data you retrieve immediately after the user connects their account. Use this option if you know you always want a certain type of data. It removes the need to make an extra API call to initiate a [data refresh](https://docs.stripe.com/api/financial_connections/accounts/refresh.md). To preserve the option to [accept ACH Direct Debit payments](https://docs.stripe.com/financial-connections/other-data-powered-products.md#accept-ach-direct-debit), request the `payment_method` permission. ## Integrate FinancialConnectionsSheet [Lado del servidor] [Lado del cliente] Before displaying the Financial Connections flow, your page should include a **Connect Financial Account** button to present the Stripe’s UI. [Initialize](https://stripe.dev/stripe-android/financial-connections/com.stripe.android.financialconnections/-financial-connections-sheet/-companion/index.html) a `FinancialConnectionsSheet` instance inside `onCreate` of your checkout Activity, passing a method to handle the result. #### Kotlin ```kotlin import com.stripe.android.financialconnections.FinancialConnectionsSheet class MyHostActivity : AppCompatActivity() { lateinit var financialConnectionsSheet: FinancialConnectionsSheet override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) financialConnectionsSheet = FinancialConnectionsSheet.create(this, ::onFinancialConnectionsSheetResult) } fun onFinancialConnectionsSheetResult(result: FinancialConnectionsSheetResult) { // implemented in the next steps } } ``` Next, fetch the `FinancialConnectionsSession` *client secret* (A client secret is used with your publishable key to authenticate a request for a single object. Each client secret is unique to the object it's associated with), and publishable key from the endpoint you created in the previous step. Set these fields using the [FinancialConnectionsSheet.Configuration](https://stripe.dev/stripe-android/financial-connections/com.stripe.android.financialconnections/-financial-connections-sheet/-configuration/index.html) and store the others for use when you present the [FinancialConnectionsSheet](https://stripe.dev/stripe-android/financial-connections/com.stripe.android.financialconnections/-financial-connections-sheet/index.html). #### Kotlin ```kotlin import com.stripe.android.financialconnections.FinancialConnectionsSheet// Add the following lines to build.gradle to use this example's networking library: // implementation 'com.github.kittinunf.fuel:fuel:2.3.1' // implementation 'com.github.kittinunf.fuel:fuel-json:2.3.1' import com.github.kittinunf.fuel.httpPost import com.github.kittinunf.fuel.json.responseJson import com.github.kittinunf.result.Result class MyHostActivity : AppCompatActivity() { lateinit var financialConnectionsSheet: FinancialConnectionsSheetlateinit var clientSecret: String lateinit var publishableKey: String override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) financialConnectionsSheet = FinancialConnectionsSheet.create(this, ::onFinancialConnectionsSheetResult)"Your backend endpoint/connections-sheet".httpPost().responseJson { _, _, result -> if (result is Result.Success) { val responseJson = result.get().obj() clientSecret = responseJson.getString("financialConnectionsSessionClientSecret") publishableKey = responseJson.getString("publishableKey") } } } fun onFinancialConnectionsSheetResult(result: FinancialConnectionsSheetResult) { // implemented in the next steps } } ``` When the customer taps your **Connect Financial Account** button, call [FinancialConnectionsSheet#present](https://stripe.dev/stripe-android/financial-connections/com.stripe.android.financialconnections/-financial-connections-sheet/present.html) to present the Financial Connections Sheet. After the customer completes the connection, the sheet closes. The [FinancialConnectionsSheetResultCallback](https://stripe.dev/stripe-android/financial-connections/com.stripe.android.financialconnections/-financial-connections-sheet-result-callback/index.html) that you declared in the preceding step is called with [FinancialConnectionsSheetResult](https://stripe.dev/stripe-android/financial-connections/com.stripe.android.financialconnections/-financial-connections-sheet-result/index.html). #### Kotlin ```kotlin // ... class MyHostActivity : AppCompatActivity() { lateinit var financialConnectionsSheet: FinancialConnectionsSheet lateinit var clientSecret: String lateinit var publishableKey: String // ...fun presentFinancialConnectionsSheet() { financialConnectionsSheet.present( configuration = FinancialConnectionsSheet.Configuration( financialConnectionsSessionClientSecret = clientSecret, publishableKey = publishableKey ) ) } fun onFinancialConnectionsSheetResult(result: FinancialConnectionsSheetResult) {when(result) { is FinancialConnectionsSheetResult.Canceled -> { print("Canceled") } is FinancialConnectionsSheetResult.Failed -> { print("Failed") print("${result.error}") } is FinancialConnectionsSheetResult.Completed -> { // Display for example, a list of accounts. val accountInfos = result.financialConnectionsSession.accounts.data .map { "${it.institutionName} ${it.last4}" } print("Completed with ${accountInfos.joinToString("\n")} accounts") } } } } ``` ## Retrieve data on a Financial Connections account [Lado del servidor] After your user has successfully completed the authentication flow, access or refresh the account data you’ve specified in the `permissions` parameter of the Financial Connections Session. To protect the privacy of your user’s data, account data accessible to you is limited to the data you’ve specified in the `permissions` parameter. Follow the guides for [balances](https://docs.stripe.com/financial-connections/balances.md), [ownership](https://docs.stripe.com/financial-connections/ownership.md) and [transactions](https://docs.stripe.com/financial-connections/transactions.md) to start retrieving account data. ## Optional: Customize the sheet [Client-side] ### Dark mode By default, `FinancialConnectionsSheet` automatically adapts to the user’s system-wide appearance settings (light and dark mode). You can change this by setting light or dark mode on your app: #### Kotlin ```kotlin // force dark AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) // force light AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) ``` ## Optional: Accept an ACH Direct Debit payment from a Financial Connections account You can optionally accept ACH Direct Debit payments on a previously collected Financial Connections account as long as the `supported_payment_method_types` attribute on the account includes `us_bank_account`. Only US bank accounts are eligible to accept ACH Direct Debits such as a checking or savings account. To accept an ACH Direct Debit payment on a previously collected account, you must have specified `payment_method` in the [data permissions](https://docs.stripe.com/financial-connections/fundamentals.md#data-permissions) parameter on the Financial Connections Session. ### Create a Payment Intent or Setup Intent Use the *Payment Intents API* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) to accept an ACH Direct payment for an account you want to charge now. Use the *Setup Intents API* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) to save details for future ACH Direct Debit payments. [Learn more about the difference between a](https://support.stripe.com/questions/payment-intents-api-vs-setup-intents-api) Payment Intent and Setup Intent. This path shows you how to accept an ACH Direct Debit payment using the Payment Intents API. Use the Financial Connections account ID and the customer ID to create a Payment Intent: ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d "payment_method_types[]=us_bank_account" \ -d "payment_method_data[us_bank_account][financial_connections_account]={{FINANCIALCONNECTIONSACCOUNT_ID}}" \ -d "payment_method_data[type]=us_bank_account" \ -d "payment_method_data[billing_details][name]=J. Customer" \ -d amount=100 \ -d currency=usd ``` This will return a Payment Intent similar to: ```json { "id": "pi_1GszXf2eZvKYlo2Ce7rjvnPP", "object": "payment_intent", "amount": 100, "amount_capturable": 0, "amount_details": { "tip": { "amount": null } }, "amount_received": 0, "application": null, "application_fee_amount": null, "automatic_payment_methods": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "charges": { "object": "list", "data": [ ], "has_more": false, "total_count": 0, "url": "/v1/charges?payment_intent=pi_1GszXf2eZvKYlo2Ce7rjvnPP" }, "client_secret": "pi_1GszXf2eZvKYlo2Ce7rjvnPP", "confirmation_method": "automatic", "created": 1651010665, "currency": "usd", "customer": null, "description": null, "invoice": null, "last_payment_error": null, "livemode": false, "metadata": { }, "next_action": null, "on_behalf_of": null, "payment_method": "pm_1Mb4UkJGNKiWrCEmJ1PS72Cd", "payment_method_options": { "us_bank_account": { "verification_method": "automatic" } }, "payment_method_types": [ "us_bank_account" ], "processing": null, "receipt_email": null, "review": null, "setup_future_usage": null, "shipping": null, "source": null, "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "requires_confirmation", "transfer_data": null, "transfer_group": null } ``` ### Collect mandate acknowledgement and submit the payment Before you can initiate the payment, you must obtain authorization from your customer by displaying mandate terms for them to accept. To be compliant with Nacha rules, you must obtain authorization from your customer before you can initiate payment by displaying mandate terms for them to accept. For more information on mandates, see [Mandates](https://docs.stripe.com/payments/ach-direct-debit.md#mandates). ### Confirm the Payment Intent To confirm this Payment Intent, you need to provide either a [`mandate` parameter](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-mandate) with an existing Mandate ID, or provide [mandate_data](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-mandate_data) to create a new mandate. For example, if you have a checkout page with a “Place Order” button, clicking that button could trigger a `POST` to an endpoint on your server. That endpoint could extract the request’s User Agent and the client’s IP address, and then make the following request to Stripe’s API: ```curl curl https://api.stripe.com/v1/payment_intents/{{PAYMENTINTENT_ID}}/confirm \ -u "<>:" \ -d "mandate_data[customer_acceptance][accepted_at]=1647448692" \ -d "mandate_data[customer_acceptance][type]=online" \ -d "mandate_data[customer_acceptance][online][ip_address]=71.183.194.54" \ --data-urlencode "mandate_data[customer_acceptance][online][user_agent]=Mozilla/5.0 ..." ``` After successfully confirming the Payment Intent, it will look similar to: ```json { "id": "pi_1GszXf2eZvKYlo2Ce7rjvnPP", "object": "payment_intent", "amount": 100, "amount_capturable": 0, "amount_received": 0, "application": null, "application_fee_amount": null, "automatic_payment_methods": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "charges": { "object": "list", "data": [ { "id": "py_17F8CPDyDglZKgWE3uzOAUe9", "object": "charge", "amount": 100, "amount_captured": 100, "amount_refunded": 0, "application": null, "application_fee": null, "application_fee_amount": null, "balance_transaction": null, "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": "J. Customer", "phone": null }, "calculated_statement_descriptor": null, "captured": true, "created": 1647448692, "currency": "usd", "customer": "cus_LKe65xcPnrCiTZ", "description": null, "destination": null, "dispute": null, "disputed": false, "failure_code": null, "failure_message": null, "fraud_details": { }, "invoice": null, "livemode": false, "metadata": { }, "on_behalf_of": null, "order": null, "outcome": null, "paid": false, "payment_intent": "pi_1GszXf2eZvKYlo2Ce7rjvnPP", "payment_method": "pm_1Mb4UkJGNKiWrCEmJ1PS72Cd", "payment_method_details": { "type": "us_bank_account", "us_bank_account": { "account_holder_type": "individual", "account_type": "checking", "bank_name": "STRIPE TEST BANK", "fingerprint": "QnXqpAeqjjh8pPFa", "last4": "6789", "routing_number": "110000000" } }, "receipt_email": null, "receipt_number": null, "receipt_url": null, "refunded": false, "refunds": { "object": "list", "data": [ ], "has_more": false, "total_count": 0, "url": "/v1/charges/py_17F8CPDyDglZKgWE3uzOAUe9/refunds" }, "review": null, "shipping": null, "source": null, "source_transfer": null, "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "pending", "transfer_data": null, "transfer_group": null } ], "has_more": false, "total_count": 1, "url": "/v1/charges?payment_intent=pi_1GszXf2eZvKYlo2Ce7rjvnPP" }, "client_secret": "pi_1GszXf2eZvKYlo2Ce7rjvnPP_secret_m38BKZvm3vSdpGdra360hPEov", "confirmation_method": "automatic", "created": 1647447792, "currency": "usd", "customer": "cus_LKe65xcPnrCiTZ", "description": null, "invoice": null, "last_payment_error": null, "livemode": false, "metadata": { }, "next_action": null, "on_behalf_of": null, "payment_method": "pm_1Mb4UkJGNKiWrCEmJ1PS72Cd", "payment_method_options": { "us_bank_account": { "verification_method": "automatic" } }, "payment_method_types": [ "us_bank_account" ], "processing": null, "receipt_email": null, "review": null, "setup_future_usage": null, "shipping": null, "source": null, "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "processing", "transfer_data": null, "transfer_group": null } ``` ACH Direct Debit is a *delayed notification payment method* (A payment method that can't immediately return payment status when a customer attempts a transaction (for example, ACH debits). Businesses commonly hold an order in a pending state until payment is successful with these payment methods). This means that it can take up to four business days to receive notification of the success or failure of a payment after you initiate a debit from your customer’s account. The PaymentIntent you create initially has a status of `processing`. After the payment succeeds, the PaymentIntent status is updated from `processing` to `succeeded`. Learn about the events that are sent when the [PaymentIntent status is updated](https://docs.stripe.com/payments/ach-direct-debit/accept-a-payment.md#web-confirm-paymentintent-succeeded). Available in: US Not sure about which Financial Connections integration to use? See our [overview of integration options](https://docs.stripe.com/financial-connections/use-cases.md). Financial Connections lets your users securely share their financial data by linking their external financial accounts to your business. You can use Financial Connections to access user-permissioned financial data such as tokenized account and routing numbers, account balances, account owner information, and historical transactions. Some common examples of how you can use Financial Connections to improve product experiences for your users include: - Mitigate fraud when onboarding a customer or business by verifying the [ownership](https://docs.stripe.com/financial-connections/ownership.md) information of an account, such as the name and address of the bank account holder. - Help your users track expenses, handle bills, manage their finances and take control of their financial well-being with [transactions](https://docs.stripe.com/financial-connections/transactions.md) data. - Speed up underwriting and improve access to credit and other financial services with transactions and balances data. - Enable your users to connect their accounts in fewer steps with Link, allowing them to save and reuse their bank account details across Stripe businesses. ## Configurar Stripe [Lado del servidor] [Lado del cliente] ### Lado del servidor Esta integración necesita puntos de conexión en tu servidor que se comuniquen con la API de Stripe. Usa nuestras librerías oficiales para acceder a la API de Stripe desde tu servidor: #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ### Lado del cliente El [SDK para React Native](https://github.com/stripe/stripe-react-native) es de código abierto y está plenamente documentado. Internamente, utiliza el SDK de [iOS nativo](https://github.com/stripe/stripe-ios) y [Android](https://github.com/stripe/stripe-android). Para instalar el SDK para React Native de Stripe, ejecuta uno de los siguientes comandos en el directorio del proyecto (en función del administrador de paquetes que utilices): #### hilado ```bash yarn add @stripe/stripe-react-native ``` #### npm ```bash npm install @stripe/stripe-react-native ``` A continuación, instala otras dependencias necesarias: - Para iOS, navega hasta el directorio de **ios** y ejecuta `pod install` para asegurarte de instalar también las dependencias nativas necesarias. - Para Android, no hay más dependencias para instalar. > Recomendamos seguir la [guía oficial de TypeScript](https://reactnative.dev/docs/typescript#adding-typescript-to-an-existing-project) para añadir compatibilidad con TypeScript. ### Inicialización de Stripe Para inicializar Stripe en tu aplicación React Native, ajusta tu pantalla de pago con el componente `StripeProvider` o usa el método de inicialización `initStripe`. Solo se requiere la [clave publicable](https://docs.stripe.com/keys.md#obtain-api-keys) de la API en `publishableKey`. El siguiente ejemplo muestra cómo inicializar Stripe mediante el componente `StripeProvider`. ```jsx import { useState, useEffect } from 'react'; import { StripeProvider } from '@stripe/stripe-react-native'; function App() { const [publishableKey, setPublishableKey] = useState(''); const fetchPublishableKey = async () => { const key = await fetchKey(); // fetch key from your server here setPublishableKey(key); }; useEffect(() => { fetchPublishableKey(); }, []); return ( {/* Your app code here */} ); } ``` > Usa las [claves de prueba](https://docs.stripe.com/keys.md#obtain-api-keys) de la API durante las pruebas y las tareas de desarrollo, y las claves del [modo activo](https://docs.stripe.com/keys.md#test-live-modes) cuando publiques tu aplicación. ## Create or retrieve an account holder [Lado del servidor] Create a [Customer object](https://docs.stripe.com/api/customers/object.md) when users create an account with your business. By providing an email address, Financial Connections can optimize the [authentication flow](https://docs.stripe.com/financial-connections/fundamentals.md#authentication-flow) by dynamically showing a streamlined user interface, for returning [Link](https://support.stripe.com/questions/link-for-financial-connections-support-for-businesses) users. ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ -d email={{CUSTOMER_EMAIL}} \ -d name={{CUSTOMER_NAME}} ``` ## Create a Financial Connections Session [Lado del servidor] > You can find a running implementation of this endpoint [available on Glitch](https://glitch.com/edit/#!/remix/stripe-mobile-connections-example) for quick testing. Before you can retrieve data from a user’s bank account with Financial Connections, your user must authenticate their account with the [authentication flow](https://docs.stripe.com/financial-connections/fundamentals.md#authentication-flow). Your user begins the authentication flow when they want to connect their account to your site or application. Insert a button or link on your site or in your application, which allows a user to link their account—for example, your button might say “Link your bank account”. Create a Financial Connections Session by posting to `/v1/financial_connections/sessions`: ```curl curl https://api.stripe.com/v1/financial_connections/sessions \ -u "<>:" \ -d "account_holder[type]=customer" \ -d "account_holder[customer]={{CUSTOMER_ID}}" \ -d "permissions[]=balances" \ -d "permissions[]=ownership" \ -d "permissions[]=payment_method" \ -d "permissions[]=transactions" ``` 1. Set `account_holder[customer]` to the Customer `id`. 1. Set the data `permissions` parameter to include the data required to fulfill your use case. 1. (Optional) set the `prefetch` parameter for retrieving the data on account creation. The [permissions](https://docs.stripe.com/api/financial_connections/sessions/create.md#financial_connections_create_session-permissions) parameter controls which account data you can access. You must request at least one permission. When completing the authentication flow, your user can see the data you’ve requested access to, and provide their consent to share it. Consider the data required to fulfill your use case and request permission to access only the data you need. Requesting permissions that go well beyond your application’s scope might erode your users’ trust in how you use their data. For example, if you’re building a personal financial management application or a lending product, you might request `transactions` data. If you’re mitigating fraud such as account takeovers, you might want to request `ownership` details. After your user authenticates their account, you can expand data permissions only by creating a new Financial Connections Session and specifying a new value for the `permissions` parameter. Your user must complete the authentication flow again, where they’ll see the additional data you’ve requested permission to access, and provide consent to share their data. The optional [prefetch parameter](https://docs.stripe.com/api/financial_connections/sessions/create.md#financial_connections_create_session-prefetch) controls which data you retrieve immediately after the user connects their account. Use this option if you know you always want a certain type of data. It removes the need to make an extra API call to initiate a [data refresh](https://docs.stripe.com/api/financial_connections/accounts/refresh.md). To preserve the option to [accept ACH Direct Debit payments](https://docs.stripe.com/financial-connections/other-data-powered-products.md#accept-ach-direct-debit), request the `payment_method` permission. ## Collect a Financial Connections account [Lado del cliente] Import the `collectFinancialConnectionsAccounts` function from Stripe’s React Native SDK. ```javascript import {collectFinancialConnectionsAccounts} from '@stripe/stripe-react-native'; ``` Use `collectFinancialConnectionsAccounts` to collect the bank account by passing in the `client_secret` from above, and then handle the result appropriately: ```javascript // Assume you have a