Debiting Express and Custom accounts Public Beta

    With Connect, your platform can directly debit the Stripe balance of an Express or Custom account.

    At times, your platform might need to transfer funds from its connected accounts to your platform account:

    • To charge the connected account directly for products or services
    • To recover funds for a previous refund
    • To make other adjustments to connected account balances (e.g., to correct an error)

    When using Express or Custom accounts, you can debit a connected account’s Stripe balance to credit to your platform account’s Stripe balance. Stripe supports two approaches for doing so:

    Both approaches create the same flow of funds: a Transfer is created on the connected account and a Payment is created on the platform account. To ensure that the transactions are reported appropriately for tax purposes, create a charge for activity that increases your revenue and create a transfer when making adjustments.


    This functionality is only supported for Express and Custom. Additionally:

    • The connected account and the platform must be in the same region (i.e., both must be in Europe or in the U.S.)
    • The currency value must match the default currency of the connected account
    • Debiting an account cannot make the connected account balance become negative unless you have reserves enabled (on by default for all new platforms created after January 31st, 2017) and have a bank account in the same currency as the debit

    To allow for the most seamless experience, we strongly recommend verifying the connected account’s bank before using Account Debits.

    Charging a connected account

    The create a charge API call supports providing a connected account ID as the source value:

    curl \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=1500 \ -d currency=usd \ -d source="{{CONNECTED_STRIPE_ACCOUNT_ID}}"
    charge = Stripe::Charge.create({ amount: 1500, currency: 'usd', source: '{{CONNECTED_STRIPE_ACCOUNT_ID}}', })
    charge = stripe.Charge.create( amount=1500, currency='usd', source='{{CONNECTED_STRIPE_ACCOUNT_ID}}' )
    $charge = \Stripe\Charge::create([ 'amount' => 1500, 'currency' => 'usd', 'source' => '{{CONNECTED_STRIPE_ACCOUNT_ID}}' ]);
    ChargeCreateParams params = ChargeCreateParams.builder() .setAmount(1500L) .setCurrency("usd") .setSource("{{CONNECTED_STRIPE_ACCOUNT_ID}}") .build(); Charge charge = Charge.create(params);
    const charge = await stripe.charges.create({ amount: 1500, currency: "usd", source: "{{CONNECTED_STRIPE_ACCOUNT_ID}}" });
    params := &stripe.ChargeParams{ Amount: stripe.Int64(1500), Currency: stripe.String(string(stripe.CurrencyUSD)), } params.SetSource("{{CONNECTED_STRIPE_ACCOUNT_ID}}") ch, _ := charge.New(params)
    // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new ChargeCreateOptions { Amount = 1500, Currency = "usd", Source = "{{CONNECTED_STRIPE_ACCOUNT_ID}}", }; var chargeService = new ChargeService(); var charge = chargeService.Create(options);

    The API call returns the Payment created on the platform account (note: it does not return a Charge).

    This approach is appropriate for platforms that charge their connected accounts for goods and services (i.e., for using the platform). For example, a platform can charge its connected accounts for additional fees or services through their Stripe balance, minimizing any need to collect an additional payment method and allowing for nearly instant availability of the funds.

    To help keep track of this additional revenue source, Stripe makes sure this revenue is appropriately added to the right tax forms (e.g., 1099).

    Transferring from a connected account

    The second method for debiting a connected account is to make a transfer from the connected account to your platform account. Use the Stripe-Account header to authenticate as the connected account and provide your platform’s Stripe account ID as the destination:

    curl \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -H "Stripe-Account: {{CONNECTED_STRIPE_ACCOUNT_ID}}" \ -d amount=1500 \ -d currency=usd \ -d destination="{{PLATFORM_STRIPE_ACCOUNT_ID}}"
    Stripe::Transfer.create({ amount: 1000, currency: 'usd', destination: '{{PLATFORM_STRIPE_ACCOUNT_ID}}', }, { stripe_account: '{{CONNECTED_STRIPE_ACCOUNT_ID}}', })
    stripe.Transfer.create( amount=1000, currency='usd', destination='{{PLATFORM_STRIPE_ACCOUNT_ID}}', stripe_account='{{CONNECTED_STRIPE_ACCOUNT_ID}}' )
    \Stripe\Transfer::create([ 'amount' => 1000, 'currency' => 'usd', 'destination' => '{{PLATFORM_STRIPE_ACCOUNT_ID}}' ], [ 'stripe_account' => '{{CONNECTED_STRIPE_ACCOUNT_ID}}', ]);
    TransferCreateParams params = TransferCreateParams.builder() .setAmount(1000L) .setCurrency("usd") .setDestination("{{PLATFORM_STRIPE_ACCOUNT_ID}}") .build(); RequestOptions requestOptions = RequestOptions.builder() .setStripeAccount("{{CONNECTED_STRIPE_ACCOUNT_ID}}") .build(); Transfer.create(transferParams, requestOptions);
    const transfer = await stripe.transfers.create({ amount: 1000, currency: 'usd', destination: '{{PLATFORM_STRIPE_ACCOUNT_ID}}' }, { stripe_account: '{{CONNECTED_STRIPE_ACCOUNT_ID}}', });
    params := &stripe.TransferParams{ Amount: stripe.Int64(1000), Currency: stripe.String(string(stripe.CurrencyUSD)), Destination: stripe.String("{PLATFORM_STRIPE_ACCOUNT_ID}"), } params.SetStripeAccount("{{CONNECTED_STRIPE_ACCOUNT_ID}}") t, _ := transfer.New(params)
    // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var options = new TransferCreateOptions { Amount = 1000, Currency = "usd", Destination = "{PLATFORM_STRIPE_ACCOUNT_ID}", }; var requestOptions = new RequestOptions(); requestOptions.StripeAccount = "{{CONNECTED_STRIPE_ACCOUNT_ID}}"; var service = new TransferService(); var transfer = service.Create(options, requestOptions);

    This API call returns the Transfer created on the connected account.

    This approach is best for making adjustments within a platform (e.g., correcting a mis-payment or recovering any fees you paid to Stripe). Account Debits created as transfers are not reported as revenue (i.e., do not appear on a 1099 tax form).

    Note that you do need your platform’s Stripe account ID to perform this request. If you don’t know that value already, perform a retrieve account API call using your platform’s API key:

    curl \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc:
    account = Stripe::Account.retrieve
    account = stripe.Account.retrieve()
    $account = \Stripe\Account::retrieve();
    Account account = Account.retrieve();
    const account = await stripe.accounts.retrieve();
    acct, _ := account.Get()
    // Set your secret key. Remember to switch to your live secret key in production! // See your keys here: StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; var accountService = new AccountService(); Account account = accountService.Get();

    This API call returns the Account object that represents your platform account.

    Further reading

    Discover what other Connect functionality is available!

    Was this page helpful?

    Feedback about this page?

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

    On this page