Skip to content
Create account
or
Sign in
The Stripe Docs logo
/
Ask AI
Create account
Sign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer resources
Overview
About Stripe payments
Upgrade your integration
Payments analytics
Online payments
OverviewFind your use caseManaged Payments
Use Payment Links
Build a checkout page
Build an advanced integration
Build an in-app integration
Payment Methods
Add payment methods
Manage payment methods
Faster checkout with Link
Payment interfaces
Payment Links
Checkout
Web Elements
In-app Payments
Payment scenarios
Handle multiple currencies
Custom payment flows
Flexible acquiring
Orchestration
In-person payments
Terminal
Beyond payments
Incorporate your company
Crypto
Financial Connections
    Overview
    Get started
    Use cases
    Fundamentals
    Testing
    Supported institutions
    Collect accounts for data
    ACH Direct Debit payments
    Connect payouts
    Other data-powered products
    Access account data
    Balances
    Ownership
    Transactions
    Ownership match
    Manage accounts
    Disconnections
    Webhooks
Climate
Understand fraud
Radar fraud protection
Manage disputes
Verify identities
HomePaymentsFinancial Connections

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:

Not sure about which Financial Connections integration to use? See our overview of integration options.

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 tokenised 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 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 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 quickly reuse their bank account details across Stripe merchants.

Set up Stripe
Server-side
Client-side

Register for Financial Connections after your account is approved for live-mode access.

Server-side

This integration requires endpoints on your server that talk to the Stripe API. Use the official libraries for access to the Stripe API from your server:

Command Line
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
# Available as a gem sudo gem install stripe
Gemfile
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
# If you use bundler, you can add this line to your Gemfile gem 'stripe'

Client-side

The Stripe iOS SDK is open source, fully documented, and compatible with apps supporting iOS 13 or above.

To install the SDK, follow these steps:

  1. In Xcode, select File > Add Package Dependencies… and enter https://github.com/stripe/stripe-ios-spm as the repository URL.
  2. Select the latest version number from our releases page.
  3. Add the StripeFinancialConnections product to the target of your app.

Note

For details on the latest SDK release and past versions, see the Releases page on GitHub. To receive notifications when a new release is published, watch releases for the repository.

Create or retrieve an account holder
Server-side

Create a Customer object when users create an account with your business. By providing an email address, Financial Connections can optimise the authentication flow by dynamically showing a streamlined user interface, for returning Link users.

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/customers \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d email={{CUSTOMER_EMAIL}} \ -d name={{CUSTOMER_NAME}}

Create a Financial Connections Session
Server-side

Note

You can find a running implementation of this endpoint available on Glitch 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.

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:

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/financial_connections/sessions \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -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.
  2. Set the data permissions parameter to include the data required to fulfil your use case.
  3. (Optional) set the prefetch parameter for retrieving the data on account creation.

The 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 fulfil 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 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.

To preserve the option to accept ACH Direct Debit payments, request the payment_method permission.

Set up a return URL
Client-side

The customer might navigate away from your app to authenticate (for example, in Safari or their banking app). To allow them to automatically return to your app after authenticating, configure a custom URL scheme and set up your app delegate to forward the URL to the SDK. Stripe doesn’t support universal links.

Note

Stripe might append additional parameters to the provided return URL. Make sure that return URLs with extra parameters aren’t rejected by your code.

SceneDelegate.swift
Swift
Objective C
No results
// This method handles opening custom URL schemes (for example, "your-app://stripe-redirect") func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { 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 } }

Integrate FinancialConnectionsSheet
Client-side

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 and publishable key from the endpoint you created in the previous step. Set your publishable key using StripeAPI.shared and initialise FinancialConnectionsSheet. Pass the returnURL you set up in the previous step.

ViewController.swift
Swift
No results
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.

ViewController.swift
Swift
No results
@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
Server-side

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, ownership and transactions to start retrieving account data.

OptionalCustomise the sheet
Client-side

All customisation 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.

var configuration = FinancialConnectionsSheet.Configuration() configuration.style = .alwaysLight

Note

When FinancialConnectionsSheet is launched through the PaymentSheet SDK, the style specified in the PaymentSheet.Configuration is automatically inherited.

OptionalAccept 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 parameter on the Financial Connections Session.

Create a Payment Intent or Setup Intent

Use the Payment Intents API to accept an ACH Direct payment for an account you want to charge now. Use the Setup Intents API to save details for future ACH Direct Debit payments. Learn more about the difference between a 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:

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/payment_intents \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d customer=
{{CUSTOMER_ID}}
\ -d "payment_method_types[]"=us_bank_account \ -d "payment_method_data[us_bank_account][financial_connections_account]"=
{{ACCOUNT_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:

{ "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": [

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 authorisation from your customer before you can initiate payment by displaying mandate terms for them to accept. For more information on mandates, see Mandates.

Confirm the Payment Intent

To confirm this Payment Intent, you need to provide either a mandate parameter with an existing Mandate ID, or provide 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:

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/payment_intents/
{{PAYMENT_INTENT_ID}}
/confirm
\ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -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:

{ "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,

ACH Direct Debit is a delayed notification payment method. 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.

Was this page helpful?
YesNo
  • Need help? Contact Support.
  • Join our early access programme.
  • Check out our changelog.
  • Questions? Contact Sales.
  • LLM? Read llms.txt.
  • Powered by Markdoc