Funding Connected Accounts for Issuing Invite Only

    Fund cards on connected accounts from your user's bank accounts.

    In order to spend money on issued cards, you must first top up funds to the Issuing balance on each of your connected accounts. This balance represents funds earmarked for Issuing, and is safely separated from your earnings, payouts, and funds from other Stripe activities.

    Before you can top up a connected account from your user’s bank account, you must first collect and verify their bank account. Stripe provides the option of collection via Stripe.js with delayed-verification using micro-deposits.

    Using Plaid

    To create instantly verified bank account tokens, first integrate Plaid into your application. As your users connect their bank accounts, you can call plaidClient.createStripeToken via Plaid’s API to receive a Stripe bank account token (e.g., btok_1FhKKBIzqKMxmFpfAOqBQSrJ).

    Once you have a bank account token, create a Source on your connected account. The bank account owner’s information must be included, and should match the connected account’s ownership information.

    curl https://api.stripe.com/v1/sources \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d type=ach_debit \ -d currency=usd \ -d token=btok_4XNshPRgmDRCVi \ -d "owner[address][line1]"="510 Townsend Street" \ -d "owner[address][city]"="San Francisco" \ -d "owner[address][state]"=California \ -d "owner[address][country]"=US \ -d "owner[email]"="jenny.rosen@example.com" \ -d "owner[name]"="Jenny Rosen" \ -d "owner[phone]"=5554443333 \ -H "Stripe-Account: {{CONNECTED_STRIPE_ACCOUNT_ID}}"
    # Set your secret key: remember to change this to your live secret key in production # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' source = Stripe::Source.create({ type: 'ach_debit', currency: 'usd', token: 'btok_4XNshPRgmDRCVi', owner: { address: { line1: '510 Townsend Street', city: 'San Francisco', state: 'California', country: 'US' }, email: 'jenny.rosen@example.com', name: 'Jenny Rosen', phone: '5554443333' }, }, {:stripe_account => "{{CONNECTED_STRIPE_ACCOUNT_ID}}"});
    # Set your secret key: remember to change this to your live secret key in production # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' source = stripe.Source.create( type='ach_debit', currency='usd', token='btok_4XNshPRgmDRCVi', owner={ address: { line1: '510 Townsend Street', city: 'San Francisco', state: 'California', country: 'US' }, email: 'jenny.rosen@example.com', name: 'Jenny Rosen', phone: '5554443333' }, stripe_account='{{CONNECTED_STRIPE_ACCOUNT_ID}}', );
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $source = \Stripe\Source::create([ "type" => "ach_debit", "currency" => "usd", "token" => "btok_4XNshPRgmDRCVi", "owner" => { "address" => { "line1" => "510 Townsend Street", "city" => "San Francisco", "state" => "California", "country" => "US" }, "email" => "jenny.rosen@example.com", "name" => "Jenny Rosen", "phone" => "5554443333", }, ], ["stripe_account" => "{{CONNECTED_STRIPE_ACCOUNT_ID}}"]);
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; Map<String, Object> params = new HashMap<>(); params.put("type", "ach_debit"); params.put("currency", "usd"); params.put("token", "btok_4XNshPRgmDRCVi"); Map<String, Object> address = new HashMap<>(); address.put("line1", "510 Townsend Street"); address.put("city", "San Francisco"); address.put("state", "California"); address.put("country", "US"); Map<String, Object> owner = new HashMap<>(); owner.put("address", address); owner.put("email", "jenny.rosen@example.com"); owner.put("name", "Jenny Rosen"); owner.put("phone", "5554443333"); RequestOptions requestOptions = RequestOptions.builder().setStripeAccount("{{CONNECTED_STRIPE_ACCOUNT_ID}}").build(); Source source = Source.create(params, requestOptions);
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); let source = await stripe.sources.create({ type: "ach_debit", currency: "usd", token: "btok_4XNshPRgmDRCVi", owner: { address: { line1: "510 Townsend Street", city: "San Francisco", state: "California", country: "US" }, email: "jenny.rosen@example.com", name: "Jenny Rosen", phone: "5554443333" }, }, { stripe_account: "{{CONNECTED_STRIPE_ACCOUNT_ID}}" });

    Once your source is created, its status will be set to chargeable, and you can use it for top ups.

    Using manual verifications

    Your users’ banks may not support Plaid, so Stripe also supports bank account tokenization with standard account & routing numbers.

    Step 1: Collecting your users' information

    To debit the user’s bank account for funding, you will need to collect their bank account information and submit evidence of their authorization to debit their account. This is known as a mandate, and ensures both you and Stripe remain compliant with ACH network rules, as well as provide you with access to evidence to ease in any dispute resolution.

    Create a form that captures the following information:

    Name The full name of the debtor
    Routing Number The US routing number of the debtor bank account (eg. 00000111)
    Account Number The debtor bank account number (eg. 000123456789)

    As your customers submit the mandate, you should record the following information:

    IP Address The IP address of the client authorizing the mandate
    User Agent The User-Agent of the client authorizing the mandate
    Date The timestamp of the mandate submission

    If instead you prefer to collect mandates from your users offline (such as via phone or a paper agreement), you won’t upload evidence of acceptance to Stripe. Instead, you should maintain your own record of the acceptance and provide us information to contact you if evidence is requested:

    Contact Email An email to contact you with if a copy of the mandate is requested.

    Step 2: Creating the token and source

    You can create a token with this information using the Bank Account Token API, and then use it to create a source. Although you can create your bank account token on your top-level account, the Source must be created on the connected account you wish to fund. You can do this by specifying a stripe_account as shown below.

    # Set your secret key: remember to change this to your live secret key in production # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' token = Stripe::Token.create({ bank_account: { country: "US", currency: "usd", account_holder_name: "Jenny Rosen", account_holder_type: "individual", routing_number: "110000000", account_number: "000123456789", } }); source = Stripe::Source.create({ type: "ach_debit", currency: "usd", token: token.id, owner: { address: { line1: "510 Townsend Street", city: "San Francisco", state: "California", country: "US" }, email: "jenny@example.com", name: "Jenny Rosen", phone: "5554443333" }, mandate: { reference: "PBX765TU8945Z", url: "https://acme.foo.bar/mandates/ach_debit/PBX765TU8945Z", amount: 1000, currency: "usd", interval: "variable", acceptance: { status: "accepted", type: "online", online: { date: 1516716818, ip: "91.121.146.224", user_agent: "Mozilla/5.0 (Macintosh%3B Intel Mac OS X 10_13_2) AppleWebKit/537.36" } }, notification_method: "stripe_email" }, }, stripe_account: "{{CONNECTED_STRIPE_ACCOUNT_ID}}")
    # Set your secret key: remember to change this to your live secret key in production # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' token = stripe.Token.create( bank_account={ country: "US", currency: "usd", account_holder_name: "Jenny Rosen", account_holder_type: "individual", routing_number: "110000000", account_number: "000123456789", } ); source = stripe.Source.create( type="ach_debit", currency="usd", token=token.id, owner={ address: { line1: "510 Townsend Street", city: "San Francisco", state: "California", country: "US" }, email="jenny@example.com", name="Jenny Rosen", phone="5554443333", }, mandate={ reference: "PBX765TU8945Z", url: "https://acme.foo.bar/mandates/ach_debit/PBX765TU8945Z", amount: 1000, currency: "usd", interval: "variable", acceptance: { status: "accepted", type: "online", online={ date: 1516716818, ip: "91.121.146.224", user_agent: "Mozilla/5.0 (Macintosh%3B Intel Mac OS X 10_13_2) AppleWebKit/537.36" } }, notification_method: "stripe_email" }, stripe_account: "{{CONNECTED_STRIPE_ACCOUNT_ID}}", )
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $token = \Stripe\Token::create([ 'bank_account' => [ 'country' => 'US', 'currency' => 'usd', 'account_holder_name' => 'Jenny Rosen', 'account_holder_type' => 'individual', 'routing_number' => '110000000', 'account_number' => '000123456789', ] ]); $source = \Stripe\Source::create([ 'type' => "ach_debit", 'currency' => "usd", 'token' => token.id, 'owner' => [ 'address' => [ 'line1' => '510 Townsend Street', 'city' => 'San Francisco', 'state' => 'California', 'country' => 'US' ], 'email' => 'jenny@example.com', 'name' => 'Jenny Rosen', 'phone' => '5554443333' ], 'mandate' => [ 'reference' => "PBX765TU8945Z", 'url' => "https://acme.foo.bar/mandates/ach_debit/PBX765TU8945Z", 'amount' => 1000, 'currency' => "usd", 'interval' => "variable", 'acceptance' => [ 'status' => "accepted", 'type' => "online", 'online' => [ 'date' => 1516716818, 'ip' => "91.121.146.224", 'user_agent' => "Mozilla/5.0 (Macintosh%3B Intel Mac OS X 10_13_2) AppleWebKit/537.36" ] ], 'notification_method' => "stripe_email", ], ], ['stripe_account' => CONNECTED_STRIPE_ACCOUNT_ID]);
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const token = await stripe.tokens.create({ bank_account: { country: 'US', currency: 'usd', account_holder_name: 'Jenny Rosen', account_holder_type: 'individual', routing_number: '110000000', account_number: '000123456789', } }); const source = await stripe.sources.create({ type: "ach_debit", currency: "usd", token: token.id, owner: { address: { line1: '510 Townsend Street', city: 'San Francisco', state: 'California', country: 'US' }, email: 'jenny@example.com', name: 'Jenny Rosen', phone: '5554443333' }, mandate: { reference: "PBX765TU8945Z", url: "https://acme.foo.bar/mandates/ach_debit/PBX765TU8945Z", amount: 1000, currency: "usd", interval: "variable", acceptance: { status: "accepted", type: "online", online: { date: 1516716818, ip: "91.121.146.224", user_agent: "Mozilla/5.0 (Macintosh%3B Intel Mac OS X 10_13_2) AppleWebKit/537.36" } }, notification_method: "stripe_email" }, }, { stripe_account: "{{CONNECTED_STRIPE_ACCOUNT_ID}}", });

    Step 3: Verifying sources with microdeposits

    Now that you have a source with a status set to pending, it must be verified. Verification is done via two small deposits into the bank account that Stripe will automatically send. These deposits will take 1–2 business days to appear on the customer’s online statement. The statement description for these deposits will be AMTS: and then the values of the two microdeposits that were sent. Your customer will need to relay the value of the two deposits to you.

    When accepting these values, be sure to note that there is a limit of 10 failed verification attempts. Once this limit has been crossed, the bank account will be unable to be verified. Careful messaging about what these microdeposits are and how they are used can help your end customers avoid this issue. Once you have these values, you can verify the bank account:

    # Set your secret key: remember to change this to your live secret key in production # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' source = Stripe::Source.retrieve('src_18eYalAHEMiOZZp1l9ZTjSU0') source.verify({values: [32, 45]});
    # Set your secret key: remember to change this to your live secret key in production # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' source = stripe.Source.retrieve('src_18eYalAHEMiOZZp1l9ZTjSU0') source.verify(values=[32, 45])
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $source = \Stripe\Source::retrieve("src_18eYalAHEMiOZZp1l9ZTjSU0"); $source->verify(["values" => [32, 45]]);
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; Source source = Source.retrieve("src_18eYalAHEMiOZZp1l9ZTjSU0"); Map<String, Object> verifyParams = new HashMap<String, Object>(); Integer[] values = {32, 45}; verifyParams.put("values", values); source.verify(verifyParams);
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); let source = await stripe.sources.verify('src_18eYalAHEMiOZZp1l9ZTjSU0', { values: [32, 45] });

    Topping up connected account’s Issuing balances

    Now that you have a verified source, your set up is done! You can now fund your connected accounts with top ups by passing in the source that was made and setting the destination_balance to issuing.

    curl https://api.stripe.com/v1/topups \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -H "Stripe-Account: {{CONNECTED_STRIPE_ACCOUNT_ID}}" \ -d amount=2000 \ -d currency=usd \ -d description="Top-up for week of May 31" \ -d destination_balance=issuing \ -d statement_descriptor=Top-up \ -d source=src_18eYalAHEMiOZZp1l9ZTjSU0
    # Set your secret key: remember to change this to your live secret key in production # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' topup = Stripe::Topup.create({ amount: 2000, currency: 'usd', description: 'Top-up for week of May 31', destination_balance: 'issuing', statement_descriptor: 'Top-up', source: 'src_18eYalAHEMiOZZp1l9ZTjSU0', }, {stripe_account: CONNECTED_STRIPE_ACCOUNT_ID})
    # Set your secret key: remember to change this to your live secret key in production # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' topup = stripe.Topup.create( amount=2000, currency='usd', description='Top-up for week of May 31', destination_balance='issuing', statement_descriptor='Top-up', source='src_18eYalAHEMiOZZp1l9ZTjSU0', stripe_account=CONNECTED_STRIPE_ACCOUNT_ID, )
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); $topup = \Stripe\Topup::create([ 'amount' => 2000, 'currency' => 'usd', 'description' => 'Top-up for week of May 31', 'description' => 'issuing', 'statement_descriptor' => 'Top-up', 'source' => 'src_18eYalAHEMiOZZp1l9ZTjSU0', ], ['stripe_account' => CONNECTED_STRIPE_ACCOUNT_ID]);
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; RequestOptions requestOptions = RequestOptions.builder().setStripeAccount(CONNECTED_STRIPE_ACCOUNT_ID).build(); Map<String, Object> params = new HashMap<>(); params.put("amount", 2000); params.put("currency", "usd"); params.put("description", "Top-up for week of May 31"); params.put("destination_balance", "issuing"); params.put("statement_descriptor", "Top-up"); params.put("source", "src_18eYalAHEMiOZZp1l9ZTjSU0"); Topup topup = Topup.create(params, requestOptions);
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); const topup = stripe.topups.create({ amount: 2000, currency: 'usd', description: 'Top-up for week of May 31', description: 'issuing', statement_descriptor: 'Top-up', source: 'src_18eYalAHEMiOZZp1l9ZTjSU0', }, { stripe_account: '{{CONNECTED_STRIPE_ACCOUNT_ID}}', });
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" params := &stripe.TopupParams{ Amount: stripe.Int64(2000), Currency: stripe.String(string(stripe.CurrencyUSD)), Description: stripe.String("Top-up for week of May 31"), DestinationBalance: stripe.String("issuing"), StatementDescriptor: stripe.String("Top-up"), } top, _ := topup.New(params)
    // Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new TopupCreateOptions { Amount = 2000, Currency = "usd", Description = "Top-up for week of May 31", DestinationBalance = "issuing", StatementDescriptor = "Top-up", }; var service = new TopupService(); Topup topup = service.Create(options);

    Was this page helpful?

    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.

    On this page