Creating separate charges and transfers Public Beta

    With Connect, you can make charges on your platform account on behalf of connected accounts, perform transfers separately, and retain funds in the process.

    Separate charges and transfers are recommended for Express or Custom accounts where you collect charges that can be a different amount than what’s paid out to your connected accounts. The platform is responsible for Stripe fees, refunds, and chargebacks. For more information about the different types of Connect charges, see the documentation on choosing an approach.

    To create a charge and set up the associated transfer, you create a transfer_group to assign the charge to:

    # Create a Charge: curl https://api.stripe.com/v1/charges \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=10000 \ -d currency=usd \ -d source=tok_visa \ -d transfer_group="{ORDER10}" # Create a Transfer to a connected account (later): curl https://api.stripe.com/v1/transfers \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=7000 \ -d currency=usd \ -d destination="{{CONNECTED_STRIPE_ACCOUNT_ID}}" \ -d transfer_group="{ORDER10}" # Create a second Transfer to another connected account (later): curl https://api.stripe.com/v1/transfers \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=2000 \ -d currency=usd \ -d destination="{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}" \ -d transfer_group="{ORDER10}"
    # 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' # Create a Charge: charge = Stripe::Charge.create({ amount: 10000, currency: 'usd', source: 'tok_visa', transfer_group: '{ORDER10}', }) # Create a Transfer to a connected account (later): transfer = Stripe::Transfer.create({ amount: 7000, currency: 'usd', destination: '{{CONNECTED_STRIPE_ACCOUNT_ID}}', transfer_group: '{ORDER10}', }) # Create a second Transfer to another connected account (later): transfer = Stripe::Transfer.create({ amount: 2000, currency: 'usd', destination: '{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}', transfer_group: '{ORDER10}', })
    # 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' # Create a Charge: charge = stripe.Charge.create( amount=10000, currency='usd', source='tok_visa', transfer_group='{ORDER10}', ) # Create a Transfer to a connected account (later): transfer = stripe.Transfer.create( amount=7000, currency='usd', destination='{{CONNECTED_STRIPE_ACCOUNT_ID}}', transfer_group='{ORDER10}', ) # Create a second Transfer to another connected account (later): transfer = stripe.Transfer.create( amount=2000, currency='usd', destination='{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}', transfer_group='{ORDER10}', )
    // 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'); // Create a Charge: $charge = \Stripe\Charge::create([ 'amount' => 10000, 'currency' => 'usd', 'source' => 'tok_visa', 'transfer_group' => '{ORDER10}', ]); // Create a Transfer to a connected account (later): $transfer = \Stripe\Transfer::create([ 'amount' => 7000, 'currency' => 'usd', 'destination' => '{{CONNECTED_STRIPE_ACCOUNT_ID}}', 'transfer_group' => '{ORDER10}', ]); // Create a second Transfer to another connected account (later): $transfer = \Stripe\Transfer::create([ 'amount' => 2000, 'currency' => 'usd', 'destination' => '{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}', 'transfer_group' => '{ORDER10}', ]);
    // 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"; // Create a Charge: Map<String, Object> chargeParams = new HashMap<String, Object>(); chargeParams.put("amount", 10000); chargeParams.put("currency", "usd"); chargeParams.put("source", "tok_visa"); chargeParams.put("transfer_group", "{ORDER10}"); Charge charge = Charge.create(chargeParams); // Create a Transfer to a connected account (later): Map<String, Object> transferParams = new HashMap<String, Object>(); transferParams.put("amount", 7000); transferParams.put("currency", "usd"); transferParams.put("destination", "{{CONNECTED_STRIPE_ACCOUNT_ID}}"); transferParams.put("transfer_group", "{ORDER10}"); Transfer transfer = Transfer.create(transferParams); // Create a second Transfer to another connected account (later): Map<String, Object> secondTransferParams = new HashMap<String, Object>(); secondTransferParams.put("amount", 2000); secondTransferParams.put("currency", "usd"); secondTransferParams.put("destination", "{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}"); secondTransferParams.put("transfer_group", "{ORDER10}"); Transfer secondTransfer = Transfer.create(secondTransferParams);
    // 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'); // Create a Charge: stripe.charges.create({ amount: 10000, currency: 'usd', source: 'tok_visa', transfer_group: '{ORDER10}', }).then(function(charge) { // asynchronously called }); // Create a Transfer to the connected account (later): stripe.transfers.create({ amount: 7000, currency: 'usd', destination: '{{CONNECTED_STRIPE_ACCOUNT_ID}}', transfer_group: '{ORDER10}', }).then(function(transfer) { // asynchronously called }); // Create a second Transfer to another connected account (later): stripe.transfers.create({ amount: 2000, currency: 'usd', destination: '{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}', transfer_group: '{ORDER10}', }).then(function(second_transfer) { // asynchronously called });
    // 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" // Create a Charge: chargeParams := &stripe.ChargeParams{ Amount: stripe.Int64(10000), Currency: stripe.String(string(stripe.CurrencyUSD)), TransferGroup: stripe.String("{ORDER10}"), } params.SetSource("tok_visa") charge, err := charge.New(chargeParams) // Create a Transfer to the connected account (later): transferParams := &stripe.TransferParams{ Amount: stripe.Int64(7000), Currency: stripe.String(string(stripe.CurrencyUSD)), Destination: stripe.String("{{CONNECTED_STRIPE_ACCOUNT_ID}}"), TransferGroup: stripe.String("{ORDER10}"), } tr, err := transfer.New(transferParams) // Create a second Transfer to another connected account (later): secondTransferParams := &stripe.TransferParams{ Amount: stripe.Int64(2000), Currency: stripe.String(string(stripe.CurrencyUSD)), Destination: stripe.String("{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}"), TransferGroup: stripe.String("{ORDER10}"), } secondTransfer, err := transfer.New(secondTransferParams)
    // 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"; // Create a Charge: var chargeOptions = new ChargeCreateOptions { Amount = 10000, Currency = "usd", TransferGroup = "{ORDER10}", }; var chargeService = new ChargeService(); var charge = chargeService.Create(chargeOptions); // Create a Transfer to the connected account (later): var transferOptions = new TransferCreateOptions { Amount = 7000, Currency = "usd", Destination = "{{CONNECTED_STRIPE_ACCOUNT_ID}}", TransferGroup = "{ORDER10}", }; var transferService = new TransferService(); var transfer = transferService.Create(transferOptions); // Create a second Transfer to another connected account (later): var secondTransferOptions = new TransferCreateOptions { Amount = 2000, Currency = "usd", Destination = "{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}", TransferGroup = "{ORDER10}", }; var secondTransfer = transferService.Create(secondTransferOptions);

    This example uses a test tokentok_visa—but you could tokenize a test card using Stripe.js and Elements instead.

    For a more detailed walkthrough, see the documentation on how to accept a payment.

    This example shows how to specify the connected account as part of the larger payment flow required by the new Payments APIs.

    # Create a PaymentIntent: curl https://api.stripe.com/v1/payment_intents \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=10000 \ -d currency=usd \ -d "payment_method_types[]"=card \ -d transfer_group="{ORDER10}" # Create a Transfer to a connected account (later): curl https://api.stripe.com/v1/transfers \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=7000 \ -d currency=usd \ -d destination="{{CONNECTED_STRIPE_ACCOUNT_ID}}" \ -d transfer_group="{ORDER10}" # Create a second Transfer to another connected account (later): curl https://api.stripe.com/v1/transfers \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=2000 \ -d currency=usd \ -d destination="{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}" \ -d transfer_group="{ORDER10}"
    # 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' # Create a PaymentIntent: payment_intent = Stripe::PaymentIntent.create({ amount: 10000, currency: 'usd', payment_method_types: ['card'], transfer_group: '{ORDER10}', }) # Create a Transfer to a connected account (later): transfer = Stripe::Transfer.create({ amount: 7000, currency: 'usd', destination: '{{CONNECTED_STRIPE_ACCOUNT_ID}}', transfer_group: '{ORDER10}', }) # Create a second Transfer to another connected account (later): transfer = Stripe::Transfer.create({ amount: 2000, currency: 'usd', destination: '{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}', transfer_group: '{ORDER10}', })
    # 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' # Create a PaymentIntent: payment_intent = stripe.PaymentIntent.create( amount=10000, currency='usd', payment_method_types=['card'], transfer_group='{ORDER10}', ) # Create a Transfer to a connected account (later): transfer = stripe.Transfer.create( amount=7000, currency='usd', destination='{{CONNECTED_STRIPE_ACCOUNT_ID}}', transfer_group='{ORDER10}', ) # Create a second Transfer to another connected account (later): transfer = stripe.Transfer.create( amount=2000, currency='usd', destination='{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}', transfer_group='{ORDER10}', )
    // 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'); // Create a PaymentIntent: $paymentIntent = \Stripe\PaymentIntent::create([ 'amount' => 10000, 'currency' => 'usd', 'payment_method_types' => ['card'], 'transfer_group' => '{ORDER10}', ]); // Create a Transfer to a connected account (later): $transfer = \Stripe\Transfer::create([ 'amount' => 7000, 'currency' => 'usd', 'destination' => '{{CONNECTED_STRIPE_ACCOUNT_ID}}', 'transfer_group' => '{ORDER10}', ]); // Create a second Transfer to another connected account (later): $transfer = \Stripe\Transfer::create([ 'amount' => 2000, 'currency' => 'usd', 'destination' => '{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}', 'transfer_group' => '{ORDER10}', ]);
    // 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"; // Create a PaymentIntent: ArrayList paymentMethodTypes = new ArrayList(); paymentMethodTypes.add("card"); Map<String, Object> params = new HashMap<String, Object>(); params.put("payment_method_types", paymentMethodTypes); params.put("amount", 1000); params.put("currency", "usd"); params.put("transfer_group", "{ORDER10}"); PaymentIntent paymentIntent = PaymentIntent.create(params); // Create a Transfer to a connected account (later): Map<String, Object> transferParams = new HashMap<String, Object>(); transferParams.put("amount", 7000); transferParams.put("currency", "usd"); transferParams.put("destination", "{{CONNECTED_STRIPE_ACCOUNT_ID}}"); transferParams.put("transfer_group", "{ORDER10}"); Transfer transfer = Transfer.create(transferParams); // Create a second Transfer to another connected account (later): Map<String, Object> secondTransferParams = new HashMap<String, Object>(); secondTransferParams.put("amount", 2000); secondTransferParams.put("currency", "usd"); secondTransferParams.put("destination", "{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}"); secondTransferParams.put("transfer_group", "{ORDER10}"); Transfer secondTransfer = Transfer.create(secondTransferParams);
    // 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'); // Create a PaymentIntent: stripe.paymentIntents.create({ amount: 10000, currency: 'usd', payment_method_types: ['card'], transfer_group: '{ORDER10}', }).then(function(charge) { // asynchronously called }); // Create a Transfer to the connected account (later): stripe.transfers.create({ amount: 7000, currency: 'usd', destination: '{{CONNECTED_STRIPE_ACCOUNT_ID}}', transfer_group: '{ORDER10}', }).then(function(transfer) { // asynchronously called }); // Create a second Transfer to another connected account (later): stripe.transfers.create({ amount: 2000, currency: 'usd', destination: '{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}', transfer_group: '{ORDER10}', }).then(function(second_transfer) { // asynchronously called });
    // 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" // Create a PaymentIntent: params := &stripe.PaymentIntentParams{ Amount: stripe.Int64(10000), Currency: stripe.String(string(stripe.CurrencyUSD)), PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), TransferGroup: stripe.String("{ORDER10}"), } pi, err := paymentintent.New(params) // Create a Transfer to the connected account (later): transferParams := &stripe.TransferParams{ Amount: stripe.Int64(7000), Currency: stripe.String(string(stripe.CurrencyUSD)), Destination: stripe.String("{{CONNECTED_STRIPE_ACCOUNT_ID}}"), TransferGroup: stripe.String("{ORDER10}"), } tr, err := transfer.New(transferParams) // Create a second Transfer to another connected account (later): secondTransferParams := &stripe.TransferParams{ Amount: stripe.Int64(2000), Currency: stripe.String(string(stripe.CurrencyUSD)), Destination: stripe.String("{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}"), TransferGroup: stripe.String("{ORDER10}"), } secondTransfer, err := transfer.New(secondTransferParams)
    // 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"; // Create a PaymentIntent: var paymentIntentOptions = new PaymentIntentCreateOptions { Amount = 10000, Currency = "usd", PaymentMethodTypes = new List<string> { "card", }, TransferGroup = "{ORDER10}", }; var paymentIntentService = new PaymentIntentService(); var paymentIntent = paymentIntentService.Create(paymentIntentOptions); // Create a Transfer to the connected account (later): var transferOptions = new TransferCreateOptions { Amount = 7000, Currency = "usd", Destination = "{{CONNECTED_STRIPE_ACCOUNT_ID}}", TransferGroup = "{ORDER10}", }; var transferService = new TransferService(); var transfer = transferService.Create(transferOptions); // Create a second Transfer to another connected account (later): var secondTransferOptions = new TransferCreateOptions { Amount = 2000, Currency = "usd", Destination = "{{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}}", TransferGroup = "{ORDER10}", }; var secondTransfer = transferService.Create(secondTransferOptions);

    For the complete flow, see the documentation on how to Accept a payment.

    Transfer options

    You can assign any value to the transfer_group string, but it must represent a single business action. You can also make a transfer without either an associated charge or a transfer_group – for example, when you must pay a provider but there’s no associated customer payment.

    The platform:

    • Does not have to transfer the same amount as the original charge
    • Can transfer a maximum of the platform’s available account balance (with an exception when using source_transaction)
    • Must be configured to use manual payouts or a combination of automatic payouts and the source_transaction parameter to ensure the account has sufficient funds to cover the transfer

    You can group together multiple charges with a single transfer or multiple transfers with a single charge. You can also perform transfers and charges in any order.

    Collecting fees

    When creating charges on your platform and separately creating a transfer, the platform can earn money by allocating less of the charge amount to the destination Stripe account, as in the above code example. Assuming that represents a delivery service transaction, with a charge to the customer of $100, a transfer of $20 to the delivery person, and a transfer of $70 to the restaurant:

    • The charge amount less the Stripe fees is added to the platform account’s pending balance
    • When the platform’s available balance is sufficient (at least $90), the transfers can be made, reducing the platform’s available balance by the specified amounts and increasing both connected account’s available balances by that same amount
    • The platform retains an additional $6.80 ($100.00 - $70.00 - $20.00 - $3.20, assuming standard U.S. Stripe fees).

    If you process payments in multiple currencies, you should also read how that is handled in Connect.

    Refunding charges

    Charges created on your platform can be refunded using your platform's secret key. However, refunding a charge has no impact on any associated transfers. It's up to your platform to reconcile any amount owed back to your platform by reducing subsequent transfer amounts or by reversing transfers (as explained next).

    curl https://api.stripe.com/v1/refunds \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d charge="{CHARGE_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' refund = Stripe::Refund.create({ charge: '{CHARGE_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' refund = stripe.Refund.create( charge='{CHARGE_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'); $refund = \Stripe\Refund::create([ 'charge' => '{CHARGE_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<String, Object>(); params.put("charge", "{CHARGE_ID}"); Refund refund = Refund.create(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 const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); stripe.refunds.create({ charge: '{CHARGE_ID}', }).then(function(refund) { // asynchronously called });
    // 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.RefundParams{ Charge: stripe.String("{CHARGE_ID}"), } refund, err := refund.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 RefundCreateOptions { Charge = "{CHARGE_ID}", }; var service = new RefundService(); var refund = service.Create(options);

    Reversing transfers

    Connect supports the ability to reverse transfers made to connected accounts, either entirely or partially (by setting an amount value):

    curl https://api.stripe.com/v1/transfers/{TRANSFER_ID}/reversals \ -u {PLATFORM_SECRET_KEY}: \ -d amount=500
    # 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' Stripe::Transfer.create_reversal( '{TRANSFER_ID}', { amount: 500, } )
    # 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' stripe.Transfer.createReversal( '{TRANSFER_ID}', amount=500 );
    // 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'); \Stripe\Transfer::createReversal( '{TRANSFER_ID}', [ 'amount' => 500, ] );
    // 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"; Transfer transfer = Transfer.retrieve("{TRANSFER_ID}"); Map<String, Object> params = new HashMap<String, Object>(); params.put("amount", 500); transfer.getReversals().create(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 const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); stripe.transfers.createReversal( '{TRANSFER_ID}', { amount: 500, }, ).then(function(reversal) { // asynchronously called });
    // 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.ReversalParams{ Amount: stripe.Int64(500), Transfer: stripe.String("{TRANSFER_ID}"), } reversal, _ := reversal.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 TransferReversalCreateOptions { Amount = 500, }; var service = new TransferReversalService(); var reversal = service.Create("{TRANSFER_ID}", options);

    Transfer reversals add the specified (or entire) amount back to the platform’s available balance, reducing the connected account’s available balance accordingly. It is only possible to reverse a transfer if the connected account’s available balance is greater than the reversal amount or has connected reserves enabled.

    Using on_behalf_of

    With separate charges and transfers, by default:

    • Charges are settled in the platform’s country
    • The fee structure for the platform’s country is used
    • The platform’s information is displayed on the customer’s credit card statement

    To use the connected account’s country, and to display their information instead, use the on_behalf_of argument. This makes the connected account the settlement merchant.

    curl https://api.stripe.com/v1/charges \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=1000 \ -d currency=usd \ -d source=tok_visa \ -d on_behalf_of="{{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' charge = Stripe::Charge.create({ amount: 1000, currency: "usd", source: "tok_visa", on_behalf_of: "{{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' charge = stripe.Charge.create( amount=1000, currency="usd", source="tok_visa", on_behalf_of="{{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'); $charge = \Stripe\Charge::create([ "amount" => 1000, "currency" => "usd", "source" => "tok_visa", "on_behalf_of" => "{{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<String, Object>(); params.put("amount", 1000); params.put("currency", "usd"); params.put("source", "tok_visa"); params.put("on_behalf_of", "{{CONNECTED_STRIPE_ACCOUNT_ID}}"); Charge charge = Charge.create(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 const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); stripe.charges.create({ amount: 1000, currency: "usd", source: "tok_visa", on_behalf_of: "{{CONNECTED_STRIPE_ACCOUNT_ID}}" }).then(function(charge) { // asynchronously called });
    // 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.ChargeParams{ Amount: stripe.Int64(1000), Currency: stripe.String(string(stripe.CurrencyUSD)), OnBehalfOf: stripe.String("{{CONNECTED_STRIPE_ACCOUNT_ID}}"), } params.SetSource("tok_visa") charge, err := charge.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 service = new ChargeService(); var createOptions = new ChargeCreateOptions { Amount = 1000, Currency = "usd", Source = "tok_visa", OnBehalfOf = "{{CONNECTED_STRIPE_ACCOUNT_ID}}", } service.Create(createOptions);
    curl https://api.stripe.com/v1/payment_intents \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d "payment_method_types[]"=card \ -d amount=1000 \ -d currency=usd \ -d on_behalf_of="{{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' payment_intent = Stripe::PaymentIntent.create({ payment_method_types: ['card'], amount: 1000, currency: 'usd', on_behalf_of: '{{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' payment_intent = stripe.PaymentIntent.create( payment_method_types: ['card'], amount=1000, currency='usd', on_behalf_of='{{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'); $payment_intent = \Stripe\PaymentIntent::create([ 'payment_method_types' => ['card'], 'amount' => 1000, 'currency' => 'usd', 'on_behalf_of' => '{{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"; ArrayList paymentMethodTypes = new ArrayList(); paymentMethodTypes.add("card"); Map<String, Object> params = new HashMap<String, Object>(); params.put("payment_method_types", paymentMethodTypes); params.put("amount", 1000); params.put("currency", "usd"); params.put("on_behalf_of", "{{CONNECTED_STRIPE_ACCOUNT_ID}}"); PaymentIntent paymentIntent = PaymentIntent.create(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 const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); stripe.paymentIntents.create({ payment_method_types: ['card'], amount: 1000, currency: 'usd', on_behalf_of: '{{CONNECTED_STRIPE_ACCOUNT_ID}}' }).then(function(paymentIntent) { // asynchronously called });
    // 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.PaymentIntentParams{ PaymentMethodTypes: stripe.StringSlice([]string{ "card", }), Amount: stripe.Int64(1000), Currency: stripe.String(string(stripe.CurrencyUSD)), OnBehalfOf: stripe.String("{{CONNECTED_STRIPE_ACCOUNT_ID}}"), } pi, err := paymentintent.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 service = new PaymentIntentService(); var createOptions = new PaymentIntentCreateOptions { PaymentMethodTypes = new List<string> { "card", }, Amount = 2000, Currency = "usd", OnBehalfOf = "{{CONNECTED_STRIPE_ACCOUNT_ID}}", }; service.Create(createOptions);

    Transfer availability

    When creating separate charges and transfers, your platform can inadvertently attempt a transfer without having a sufficient available balance. Doing so raises an error and the transfer attempt fails. If you’re commonly experiencing this problem, you can use the source_transaction parameter to tie a transfer to an existing charge. By using source_transaction, the transfer request succeeds regardless of your available balance and the transfer itself only occurs once the charge’s funds become available.

    curl https://api.stripe.com/v1/transfers \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -d amount=1000 \ -d currency=usd \ -d source_transaction="{CHARGE_ID}" \ -d destination="{{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' transfer = Stripe::Transfer.create({ amount: 900, currency: "usd", source_transaction: "{CHARGE_ID}", destination: "{{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' transfer = stripe.Transfer.create( amount=1000, currency="usd", source_transaction="{CHARGE_ID}", destination={{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'); $transfer = \Stripe\Transfer::create([ "amount" => 1000, "currency" => "usd", "source_transaction" => "{CHARGE_ID}", "destination" => "{{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<String, Object>(); params.put("amount", 1000); params.put("currency", "usd"); params.put("source_transaction", "{CHARGE_ID}"); params.put("destination", "{{CONNECTED_STRIPE_ACCOUNT_ID}}"); Transfer transfer = Transfer.create(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 const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); stripe.transfers.create({ amount: 1000, currency: "usd", source_transaction: "{CHARGE_ID}", destination: "{{CONNECTED_STRIPE_ACCOUNT_ID}}", }).then(function(transfer) { // asynchronously called });
    // 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.TransferParams{ Amount: stripe.Int64(1000), Currency: stripe.String(string(stripe.CurrencyUSD)), SourceTransaction: stripe.String("{CHARGE_ID}"), Destination: stripe.String("{{CONNECTED_STRIPE_ACCOUNT_ID}}"), } tr, err := transfer.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 TransferCreateOptions { Amount = 1000, Currency = "usd", SourceTransaction = "{CHARGE_ID}", Destination = "{{CONNECTED_STRIPE_ACCOUNT_ID}}" }; var service = new TransferService(); var Transfer = service.Create(options);

    When using this parameter:

    • The amount of the transfer must not exceed the amount of the source charge
    • You may create multiple transfers with the same source_transaction, as long as the sum of the transfers doesn’t exceed the source charge
    • The transfer takes on the pending status of the associated charge: if the funds from the charge become available in N days, the payment that the destination Stripe account receives from the transfer also becomes available in N days
    • Stripe automatically creates a transfer_group for you

    Certain payment methods, like ACH, can fail asynchronously. For these payments, you should avoid using source_transaction and wait until a charge.succeeded event is triggered before transferring the funds. If you have to use source_transaction with these payments, you’ll have to implement functionality to manage payment failures.

    When a payment used as a source_transaction fails, funds from your platform’s account balance are transferred to the connected account to cover the payment. To recover these funds, reverse the transfer associated with the failed source_transaction.

    Further reading

    Discover what other Connect functionality is available.

    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