Creating destination charges on your platform

    With Connect, you can create charges on your platform account, take fees, and then transfer remaining funds to your connected accounts.

    Destination charges are recommended for Express or Custom accounts. Destination charges are created on the platform, but as part of the charge operation, funds are transferred to the connected account specified in the transfer_data[destination] parameter of the charge. The platform is responsible for the cost of the 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 destination charge, specify the ID of the connected account that should receive the funds as the value of the transfer_data[destination] parameter:

    curl https://api.stripe.com/v1/charges \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -d amount=1000 \
      -d currency=usd \
      -d source=tok_visa \
      -d "transfer_data[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'
    
    charge = Stripe::Charge.create({
      amount: 1000,
      currency: "usd",
      source: "tok_visa",
      transfer_data: {
        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'
    
    charge = stripe.Charge.create(
      amount=1000,
      currency="usd",
      source="tok_visa",
      transfer_data={
        "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');
    
    $charge = \Stripe\Charge::create([
      "amount" => 1000,
      "currency" => "usd",
      "source" => "tok_visa",
      "transfer_data" => [
        "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", "tok_visa");
    Map<String, Object> transferDataParams = new HashMap<String, Object>();
    transferDataParams.put("destination", "{{CONNECTED_STRIPE_ACCOUNT_ID}}");
    params.put("transfer_data", transferDataParams);
    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",
      transfer_data: {
        destination: "{{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)),
      TransferData: &stripe.DestinationParams{
        Destination: 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",
      TransferData = new ChargeTransferDataOptions 
      {
        Destination = "{{CONNECTED_STRIPE_ACCOUNT_ID}}",
      },
    }
    service.Create(createOptions);
    

    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.

    curl https://api.stripe.com/v1/payment_intents \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -d "payment_method_types[]"=card \
      -d amount=1000 \
      -d currency=usd \
      -d "transfer_data[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'
    
    payment_intent = Stripe::PaymentIntent.create({
      payment_method_types: ['card'],
      amount: 1000,
      currency: 'usd',
      transfer_data: {
        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'
    
    payment_intent = stripe.PaymentIntent.create(
      payment_method_types: ['card'],
      amount=1000,
      currency='usd',
      transfer_data={
        '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');
    
    $payment_intent = \Stripe\PaymentIntent::create([
      'payment_method_types' => ['card'],
      'amount' => 1000,
      'currency' => 'usd',
      'transfer_data' => [
        '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";
    
    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");
    Map<String, Object> transferDataParams = new HashMap<String, Object>();
    transferDataParams.put("destination", "{{CONNECTED_STRIPE_ACCOUNT_ID}}");
    params.put("transfer_data", transferDataParams);
    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',
      transfer_data: {
        destination: '{{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)),
      TransferData: &stripe.PaymentIntentTransferDataParams{
        Destination: 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",
      TransferData = new PaymentIntentTransferDataOptions 
      {
        Destination = "{{CONNECTED_STRIPE_ACCOUNT_ID}}",
      },
    };
    service.Create(createOptions);
    

    The payment method must be created using the platform’s publishable key. If charging a Customer object, the Customer must exist within the platform account.

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

    Specifying the settlement merchant

    The settlement merchant is dependent on the capabilities set on an account and how a charge is created. The settlement merchant determines whose information is used to make the charge. This includes the statement descriptor (either the platform’s or the connected account’s) that’s displayed on the customer’s credit card or bank statement for that charge. When using destination charges, you have some flexibility for specifying the settlement merchant.

    By default, creating a charge with transfer_data[destination] makes the platform the settlement merchant. You can change this behavior and make the connected account the settlement merchant by using the on_behalf_of attribute on the charge.

    Specifying the settlement merchant allows you to be more explicit about who charges are created for. For example, some platforms prefer to be the settlement merchant because the end customer interacts directly with their platform (e.g., on-demand platforms). However, some platforms have connected accounts that interact directly with end customers instead (e.g., a storefront on an e-commerce platform). In these scenarios, it makes more sense for the connected account to be the settlement merchant.

    Collecting fees with application_fee_amount

    When creating charges with an application_fee_amount, the full charge amount is immediately transferred from the platform to the transfer_data[destination] account after the charge is captured. The application_fee_amount (capped at the full amount of the charge) is then transferred back to the platform.

    curl https://api.stripe.com/v1/charges \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -d amount=1000 \
      -d currency=usd \
      -d source=tok_visa \
      -d application_fee_amount=123 \
      -d "transfer_data[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'
    
    charge = Stripe::Charge.create({
      amount: 1000,
      currency: "usd",
      source: "tok_visa",
      application_fee_amount: 123,
      transfer_data: {
        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'
    
    charge = stripe.Charge.create(
      amount=1000,
      currency="usd",
      source="tok_visa",
      application_fee_amount=123,
      transfer_data={
        "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');
    
    $charge = \Stripe\Charge::create([
      "amount" => 1000,
      "currency" => "usd",
      "source" => "tok_visa",
      "application_fee_amount" => 123,
      "transfer_data" => [
        "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", "tok_visa");
    params.put("application_fee_amount", 123);
    Map<String, Object> transferDataParams = new HashMap<String, Object>();
    transferDataParams.put("destination", "{{CONNECTED_STRIPE_ACCOUNT_ID}}");
    params.put("transfer_data", transferDataParams);
    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",
      application_fee_amount: 123,
      transfer_data: {
        destination: "{{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)),
      ApplicationFeeAmount: stripe.Int64(123),
      TransferData: &stripe.DestinationParams{
        Destination: 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",
      ApplicationFeeAmount = 123,
      TransferData = new ChargeTransferDataOptions 
      {
        Destination = "{{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 application_fee_amount=123 \
      -d "transfer_data[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'
    
    payment_intent = Stripe::PaymentIntent.create({
      payment_method_types: ['card'],
      amount: 1000,
      currency: 'usd',
      application_fee_amount: 123,
      transfer_data: {
        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'
    
    payment_intent = stripe.PaymentIntent.create(
      payment_method_types: ['card'],
      amount=1000,
      currency='usd',
      application_fee_amount=123,
      transfer_data={
        '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');
    
    $payment_intent = \Stripe\PaymentIntent::create([
      'payment_method_types' => ['card'],
      'amount' => 1000,
      'currency' => 'usd',
      'application_fee_amount' => 123,
      'transfer_data' => [
        '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";
    
    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("application_fee_amount", 123);
    Map<String, Object> transferDataParams = new HashMap<String, Object>();
    transferDataParams.put("destination", "{{CONNECTED_STRIPE_ACCOUNT_ID}}");
    params.put("transfer_data", transferDataParams);
    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',
      application_fee_amount: 123,
      transfer_data: {
        destination: '{{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)),
      ApplicationFeeAmount: stripe.Int64(123),
      TransferData: &stripe.PaymentIntentTransferDataParams{
        Destination: 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",
      ApplicationFeeAmount = 123,
      TransferData = new PaymentIntentTransferDataOptions 
      {
        Destination = "{{CONNECTED_STRIPE_ACCOUNT_ID}}",
      },
    };
    service.Create(createOptions);
    

    To provide a better reporting experience, an application fee object is created once the application fee is collected. Use the amount property on the application fee object for reporting. You can then access these objects with the Application Fees endpoint.

    When using an application_fee_amount, know that:

    • The amount collected as an application fee is capped at the total transaction amount.
    • An application fee object is created and can be accessed in the charge object’s application_fee field.
    • The application_fee_amount is always processed in the same currency as the transaction.
    • Your platform pays the Stripe fee after the application_fee_amount is transferred to your account.
    • No additional Stripe fees are applied to the amount.

    Flow of funds

    With the above code, the full charge amount ($10.00) is added to the connected account’s pending balance. The application_fee_amount ($1.23) is subtracted from the charge amount and is transferred to your platform. Then, Stripe fees ($0.59) are subtracted from the application_fee_amount and the remaining funds ($0.64) are added to your platform account’s balance.

    The application_fee_amount becomes available on the connected account’s normal transfer schedule, just like funds from regular Stripe charges.

    Collecting fees with transfer_data[amount]

    You can also take a fee by using transfer_data[amount].

    The transfer_data[amount] is a positive integer reflecting the amount of the charge to be transferred to the transfer_data[destination]. You subtract your platform’s fees from the charge amount, then pass the result of this calculation as the transfer_data[amount]:

    curl https://api.stripe.com/v1/charges \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -d amount=1000 \
      -d currency=usd \
      -d source=tok_visa \
      -d "transfer_data[amount]"=877 \
      -d "transfer_data[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'
    
    charge = Stripe::Charge.create({
      amount: 1000,
      currency: "usd",
      source: "tok_visa",
      transfer_data: {
        amount: 877,
        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'
    
    charge = stripe.Charge.create(
      amount=1000,
      currency="usd",
      source="tok_visa",
      transfer_data={
        "amount": 877,
        "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');
    
    $charge = \Stripe\Charge::create([
      "amount" => 1000,
      "currency" => "usd",
      "source" => "tok_visa",
      "transfer_data" => [
        "amount" => 877,
        "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", "tok_visa");
    Map<String, Object> transferDataParams = new HashMap<String, Object>();
    transferDataParams.put("amount", 877);
    transferDataParams.put("destination", "{{CONNECTED_STRIPE_ACCOUNT_ID}}");
    params.put("transfer_data", transferDataParams);
    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",
      transfer_data: {
        amount: 877,
        destination: "{{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)),
      TransferData: &stripe.DestinationParams{
        Amount: stripe.Int64(877),
        Destination: 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",
      TransferData = new ChargeTransferDataOptions 
      {
        Amount = 877,
        Destination = "{{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 "transfer_data[amount]"=877 \
      -d "transfer_data[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'
    
    payment_intent = Stripe::PaymentIntent.create({
      payment_method_types: ['card'],
      amount: 1000,
      currency: 'usd',
      transfer_data: {
        amount: 877,
        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'
    
    payment_intent = stripe.PaymentIntent.create(
      payment_method_types: ['card'],
      amount=1000,
      currency='usd',
      transfer_data={
        'amount': 877,
        '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');
    
    $payment_intent = \Stripe\PaymentIntent::create([
      'payment_method_types' => ['card'],
      'amount' => 1000,
      'currency' => 'usd',
      'transfer_data' => [
        'amount' => 877,
        '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";
    
    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");
    Map<String, Object> transferDataParams = new HashMap<String, Object>();
    transferDataParams.put("amount", 877);
    transferDataParams.put("destination", "{{CONNECTED_STRIPE_ACCOUNT_ID}}");
    params.put("transfer_data", transferDataParams);
    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',
      transfer_data: {
        amount: 877,
        destination: '{{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)),
      TransferData: &stripe.PaymentIntentTransferDataParams{
        Amount: stripe.Int64(877),
        Destination: 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",
      TransferData = new PaymentIntentTransferDataOptions 
      {
        Amount = 877,
        Destination = "{{CONNECTED_STRIPE_ACCOUNT_ID}}",
      },
    };
    service.Create(createOptions);
    

    When using transfer_data[amount], know that:

    • The amount is capped at the total transaction amount.
    • The amount is always processed in the same currency as the transaction.
    • Your platform separately pays the Stripe fees on the charge.
    • No additional Stripe fees are applied to the amount.
    • To calculate fees after charges are created (often for reporting purposes), you need to retrieve the charge and subtract the transfer_data[amount] from the amount on the charge.

    If you need a more robust reporting experience, or if you plan to charge the same fee on all charges, an application fee amount might be a better fit for your integration.

    Flow of funds

    With the above code, the transfer_data[amount] ($8.77) is added to the connected account’s pending balance. The charge total less the Stripe fees (on the charge amount) less the transfer_data[amount] is added to the platform account’s pending balance ($0.64, which is $10.00 - $0.59 - $8.77).

    The transfer_data[amount] becomes available on the connected account’s normal transfer schedule, just like funds from regular Stripe charges.

    Platforms can track how much they retain from transfer_data[amount] charges by looking at the Destination Platform Fee column in the Balance history export.

    Differences between transfer_data[destination] and destination[account]

    The destination[account] parameter is deprecated, and replaced with transfer_data[destination]. You should be aware of the following differences:

    • When using destination[account], on_behalf_of is automatically set to the same value as destination[account].
    • When using transfer_data[destination], the settlement merchant can be specified with on_behalf_of. If you need to retain the behavior of destination[account], on_behalf_of must be explicitly set to the same value as transfer_data[destination].
    • When using transfer_data[destination], the platform’s statement descriptor is used unless on_behalf_of is set.

    Issuing refunds

    If you are using the Payment Intents API, refunds should be issued against the most recent charge that is created.

    Charges created on the platform account can be refunded using the platform account’s secret key. When refunding a charge that has a transfer_data[destination], by default the destination account keeps the funds that were transferred to it, leaving the platform account to cover the negative balance from the refund. To pull back the funds from the connected account to cover the refund, set the reverse_transfer parameter to true when creating the refund:

    curl https://api.stripe.com/v1/refunds \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -d charge="{CHARGE_ID}" \
      -d reverse_transfer=true
    
    # 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}",
      reverse_transfer: true,
    })
    # 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}",
      reverse_transfer=True,
    )
    // 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}",
      "reverse_transfer" => true,
    ]);
    // 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}");
    params.put("reverse_transfer", true);
    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}",
      reverse_transfer: true,
    }).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}"),
      ReverseTransfer: stripe.Bool(true),
    }
    refund, err := refund.New(params)
    

    By default, the entire charge is refunded, but you can create a partial refund by setting an amount value as a positive integer.

    If the refund results in the entire charge being refunded, the entire transfer is reversed. Otherwise, a proportional amount of the transfer is reversed.

    Refunding application fees

    When refunding a charge with an application fee, by default the platform account keeps the funds from the application fee. To push the application fee funds back to the connected account, set the refund_application_fee parameter to true when creating the refund:

    curl https://api.stripe.com/v1/refunds \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -d charge="{CHARGE_ID}" \
      -d reverse_transfer=true \
      -d refund_application_fee=true
    
    # 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}",
      reverse_transfer: true,
      refund_application_fee: true,
    })
    # 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}",
      reverse_transfer=True,
      refund_application_fee=True,
    )
    // 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}",
      "reverse_transfer" => true,
      "refund_application_fee" => true,
    ]);
    // 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}");
    params.put("reverse_transfer", true);
    params.put("refund_application_fee", true);
    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}",
      reverse_transfer: true,
      refund_application_fee: true,
    }).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}"),
      RefundApplicationFee: stripe.Bool(true),
      ReverseTransfer: stripe.Bool(true),
    }
    refund, err := refund.New(params)
    

    Note that if you refund the application fee for a destination charge, you must also reverse the transfer. If the refund results in the entire charge being refunded, the entire application fee is refunded as well. Otherwise, a proportional amount of the application fee is refunded.

    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