Creating Separate Charges and Transfers

    With Connect, you can make charges on your platform account on behalf of connected accounts, perform transfers separately, and even retain funds in the process. If you need help after reading this, check out our answers to common questions or chat live with other developers in #stripe on freenode.

    Connect supports three approaches for processing charges on behalf of a connected account. For Managed Accounts, the simplest route is to create the charge on your platform’s account and use the destination parameter to indicate the connected account that receives the funds.

    For platforms that desire more flexibility in how funds move, a more manual option is to create the charge on your platform account and separately transfer funds to the connected account. Using this approach, the platform is responsible for the cost of the Stripe fees, refunds, and chargebacks by default.

    Because of the additional programming and operations required, this approach is best left to business models with any of these qualities:

    • Have a one-to-many correlation between charges and transfers (i.e., a single charge may be paid out to multiple connected accounts)
    • Do not know which connected account should receive the funds at the time the charge is made
    • Need to perform a transfer before the actual charge is made (e.g., to pay a service provider before charging the customer)

    For example, charges made to a delivery service need to be split between the business—the source of the items being delivered—and the delivery person. The platform processes the charge, as it’s providing the overarching service. As another example, a cleaning service may process the charge immediately but not know which connected account to pay—who is actually doing the work—until later.

    Because this manual approach creates no direct link between the charge and the subsequent transfer, you should assign a transfer group to both when making the requests. This can be any unique value, such as a sale ID.

    # Create a Charge:
    curl https://api.stripe.com/v1/charges \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -d amount=1000 \
       -d currency=usd \
       -d source=tok_48vDjmhsovEqCbCXc8guHEaW \
       -d transfer_group=ORDER42
    # Create a Transfer to the connected account (later):
    curl https://api.stripe.com/v1/transfers \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -d amount=877 \
       -d currency=usd \
       -d destination="{CONNECTED_STRIPE_ACCOUNT_ID}" \
       -d transfer_group=ORDER42
    
    # 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_BQokikJOvBiI2HlWgH4olfQ2"
    
    # Token is created using Stripe.js or Checkout!
    # Get the payment token submitted by the form:
    token = params[:stripeToken]
    
    # Create a Charge:
    charge = Stripe::Charge.create({
      :amount => 1000,
      :currency => "usd",
      :source => token,
      :transfer_group => "ORDER42",
    })
    
    # Create a Transfer to the connected account (later):
    transfer = Stripe::Transfer.create({
      :amount => 877,
      :currency => "usd",
      :destination => "{CONNECTED_STRIPE_ACCOUNT_ID}",
      :transfer_group => "ORDER42",
    })
    
    # 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_BQokikJOvBiI2HlWgH4olfQ2"
    
    # Token is created using Stripe.js or Checkout!
    # Get the payment token submitted by the form:
    token = request.POST['stripeToken']
    
    # Create a Charge:
    charge = stripe.Charge.create(
      amount=1000,
      currency="usd",
      source=token,
      transfer_group="ORDER42",
    )
    
    # Create a Transfer to the connected account (later):
    transfer = stripe.Transfer.create(
      amount=877,
      currency="usd",
      destination="{CONNECTED_STRIPE_ACCOUNT_ID}",
      transfer_group="ORDER42",
    )
    
    // 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_BQokikJOvBiI2HlWgH4olfQ2");
    
    // Token is created using Stripe.js or Checkout!
    // Get the payment token submitted by the form:
    $token = $_POST['stripeToken'];
    
    // Create a Charge:
    $charge = \Stripe\Charge::create(array(
      "amount" => 1000,
      "currency" => "usd",
      "source" => $token,
      "transfer_group" => "ORDER42",
    ));
    
    // Create a Transfer to the connected account (later):
    $transfer = \Stripe\Transfer::create(array(
      "amount" => 877,
      "currency" => "usd",
      "destination" => "{CONNECTED_STRIPE_ACCOUNT_ID}",
      "transfer_group" => "ORDER42",
    ));
    
    // 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_BQokikJOvBiI2HlWgH4olfQ2";
    
    // Token is created using Stripe.js or Checkout!
    // Get the payment token submitted by the form:
    String token = request.getParameter("stripeToken");
    
    // Create a Charge:
    Map<String, Object> chargeParams = new HashMap<String, Object>();
    chargeParams.put("amount", 1000);
    chargeParams.put("currency", "usd");
    chargeParams.put("source", token);
    chargeParams.put("transfer_group", "ORDER42");
    Charge charge = Charge.create(chargeParams);
    
    // Create a Transfer to the connected account (later):
    Map<String, Object> transferParams = new HashMap<String, Object>();
    transferParams.put("amount", 877);
    transferParams.put("currency", "usd");
    transferParams.put("destination", "{CONNECTED_STRIPE_ACCOUNT_ID}");
    transferParams.put("transfer_group", "ORDER42");
    Transfer transfer = Transfer.create(transferParams);
    
    // 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
    var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    // Token is created using Stripe.js or Checkout!
    // Get the payment token submitted by the form:
    var token = request.body.stripeToken; // Using Express
    
    // Create a Charge:
    stripe.charges.create({
      amount: 1000,
      currency: "usd",
      source: token,
      transfer_group: "ORDER42",
    }).then(function(charge) {
      // asynchronously called
    });
    
    // Create a Transfer to the connected account (later):
    stripe.transfers.create({
      amount: 877,
      currency: "usd",
      destination: "{CONNECTED_STRIPE_ACCOUNT_ID}",
      transfer_group: "ORDER42",
    }).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_BQokikJOvBiI2HlWgH4olfQ2"
    
    // Token is created using Stripe.js or Checkout!
    // Get the payment token submitted by the form:
    token := r.FormValue("stripeToken")
    
    // Create a Charge:
    chargeParams := &stripe.ChargeParams{
      Amount: 1000,
      Currency: "usd",
      TransferGroup: "ORDER42",
    }
    params.SetSource(token)
    charge, err := charge.New(chargeParams)
    
    // Create a Transfer to the connected account (later):
    transferParams := &stripe.TransferParams{
      Amount: 877,
      Currency: "usd",
      Dest: "{CONNECTED_STRIPE_ACCOUNT_ID}",
      TransferGroup: "ORDER42",
    }
    transfer, err := transfer.New(transferParams)
    

    When using this approach, your platform:

    • Does not have to transfer the same amount as the original charge
    • Can only transfer up to the platform’s available account balance
    • Cannot be using automatic transfers

    This approach provides the most flexibility but requires the platform to implement additional logic, such as the use of transfer_group and timing when transfers can be created based upon the available balance.

    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 first code example.

    With the above code:

    1. The charge amount less the Stripe fees is added to the platform’s account pending balance
    2. When the platform’s available balance is sufficient (at least $8.77), the transfer can succeed, reducing the platform’s available balance by that amount and increasing the connected account’s available balance by that same amount
    3. The platform retains an additional $0.64 ($10.00 - $8.77 - $0.59).

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

    Grouping transactions

    Some platforms have more complex business models, lacking a one-to-one relationship between charges and transfers. For example, a ride sharing platform may pay bonuses to its drivers (not tied to an individual charge) or a delivery platform needs to pay both the business and the delivery person.

    The charge-and-separately-transfer approach does not require a one-to-one relationship between charges and transfers. The transfer_group parameter allows you to define complex relationships, including:

    • Linking any number of charges and transfers
    • Creating the charges and transfers in any order

    The only restriction is the transfer_group must represent a single business action and the value unique to a single grouping of charges and transfers.

    # Create a Charge:
    curl https://api.stripe.com/v1/charges \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -d amount=5000 \
       -d currency=usd \
       -d source=tok_sL6gQT3Kxp731fyNqLeRGnJq \
       -d transfer_group="{ORDER10}"
    # Create a Transfer to a connected account (later):
    curl https://api.stripe.com/v1/transfers \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -d amount=3743 \
       -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_BQokikJOvBiI2HlWgH4olfQ2: \
       -d amount=916 \
       -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_BQokikJOvBiI2HlWgH4olfQ2"
    
    # Token is created using Stripe.js or Checkout!
    # Get the payment token submitted by the form:
    token = params[:stripeToken]
    
    # Create a Charge:
    charge = Stripe::Charge.create({
      :amount => 5000,
      :currency => "usd",
      :source => token,
      :transfer_group => "{ORDER10}",
    })
    
    # Create a Transfer to a connected account (later):
    transfer = Stripe::Transfer.create({
      :amount => 3743,
      :currency => "usd",
      :destination => "{CONNECTED_STRIPE_ACCOUNT_ID}",
      :transfer_group => "{ORDER10}",
    })
    
    # Create a second Transfer to another connected account (later):
    transfer = Stripe::Transfer.create({
      :amount => 916,
      :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_BQokikJOvBiI2HlWgH4olfQ2"
    
    # Token is created using Stripe.js or Checkout!
    # Get the payment token submitted by the form:
    token = request.POST['stripeToken']
    
    # Create a Charge:
    charge = stripe.Charge.create(
      amount=5000,
      currency="usd",
      source=token,
      transfer_group="{ORDER10}",
    )
    
    # Create a Transfer to a connected account (later):
    transfer = stripe.Transfer.create(
      amount=3743,
      currency="usd",
      destination="{CONNECTED_STRIPE_ACCOUNT_ID}",
      transfer_group="{ORDER10}",
    )
    
    # Create a second Transfer to another connected account (later):
    transfer = stripe.Transfer.create(
      amount=916,
      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_BQokikJOvBiI2HlWgH4olfQ2");
    
    // Token is created using Stripe.js or Checkout!
    // Get the payment token submitted by the form:
    $token = $_POST['stripeToken'];
    
    // Create a Charge:
    $charge = \Stripe\Charge::create(array(
      "amount" => 5000,
      "currency" => "usd",
      "source" => $token,
      "transfer_group" => "{ORDER10}",
    ));
    
    // Create a Transfer to a connected account (later):
    $transfer = \Stripe\Transfer::create(array(
      "amount" => 3743,
      "currency" => "usd",
      "destination" => "{CONNECTED_STRIPE_ACCOUNT_ID}",
      "transfer_group" => "{ORDER10}",
    ));
    
    // Create a second Transfer to another connected account (later):
    $transfer = \Stripe\Transfer::create(array(
      "amount" => 916,
      "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_BQokikJOvBiI2HlWgH4olfQ2";
    
    // Token is created using Stripe.js or Checkout!
    // Get the payment token submitted by the form:
    String token = request.getParameter("stripeToken");
    
    // Create a Charge:
    Map<String, Object> chargeParams = new HashMap<String, Object>();
    chargeParams.put("amount", 5000);
    chargeParams.put("currency", "usd");
    chargeParams.put("source", token);
    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", 3743);
    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", 916);
    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
    var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    // Token is created using Stripe.js or Checkout!
    // Get the payment token submitted by the form:
    var token = request.body.stripeToken; // Using Express
    
    // Create a Charge:
    stripe.charges.create({
      amount: 5000,
      currency: "usd",
      source: token,
      transfer_group: "{ORDER10}",
    }).then(function(charge) {
      // asynchronously called
    });
    
    // Create a Transfer to the connected account (later):
    stripe.transfers.create({
      amount: 3743,
      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: 916,
      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_BQokikJOvBiI2HlWgH4olfQ2"
    
    // Token is created using Stripe.js or Checkout!
    // Get the payment token submitted by the form:
    token := r.FormValue("stripeToken")
    
    // Create a Charge:
    chargeParams := &stripe.ChargeParams{
      Amount: 5000,
      Currency: "usd",
      TransferGroup: "{ORDER10}",
    }
    params.SetSource(token)
    charge, err := charge.New(chargeParams)
    
    // Create a Transfer to the connected account (later):
    transferParams := &stripe.TransferParams{
      Amount: 3743,
      Currency: "usd",
      Dest: "{CONNECTED_STRIPE_ACCOUNT_ID}",
      TransferGroup: "{ORDER10}",
    }
    transfer, err := transfer.New(transferParams)
    
    // Create a second Transfer to another connected account (later):
    secondTransferParams := &stripe.TransferParams{
      Amount: 916,
      Currency: "usd",
      Dest: "{OTHER_CONNECTED_STRIPE_ACCOUNT_ID}",
      TransferGroup: "{ORDER10}",
    }
    secondTransfer, err := transfer.New(secondTransferParams)
    

    You can also query by transfer groups using the transfer_group filter when listing transfers or charges.

    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_BQokikJOvBiI2HlWgH4olfQ2: \
       -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_BQokikJOvBiI2HlWgH4olfQ2"
    
    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_BQokikJOvBiI2HlWgH4olfQ2"
    
    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_BQokikJOvBiI2HlWgH4olfQ2");
    
    $transfer = \Stripe\Transfer::create(array(
      "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_BQokikJOvBiI2HlWgH4olfQ2";
    
    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
    var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    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_BQokikJOvBiI2HlWgH4olfQ2"
    
    params := &stripe.TransferParams{
      Amount: 1000,
      Currency: "usd",
      SourceTx: "{CHARGE_ID}",
      Dest: "{CONNECTED_STRIPE_ACCOUNT_ID}",
    }
    transfer, err := transfer.New(params)
    

    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

    Issuing refunds

    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 your the platform by reducing subsequent transfer amounts or by reversing transfers.

    curl https://api.stripe.com/v1/refunds \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -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_BQokikJOvBiI2HlWgH4olfQ2"
    
    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_BQokikJOvBiI2HlWgH4olfQ2"
    
    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_BQokikJOvBiI2HlWgH4olfQ2");
    
    $refund = \Stripe\Refund::create(array(
      "refund" => "{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_BQokikJOvBiI2HlWgH4olfQ2";
    
    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
    var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    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_BQokikJOvBiI2HlWgH4olfQ2"
    
    params := &stripe.RefundParams{
      Charge: "{CHARGE_ID}",
    }
    
    refund, err := refund.New(params)
    

    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_BQokikJOvBiI2HlWgH4olfQ2"
    
    transfer = Stripe::Transfer.retrieve("{TRANSFER_ID}")
    transfer.reversals.create({
      :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_BQokikJOvBiI2HlWgH4olfQ2"
    
    transfer = stripe.Transfer.retrieve("{TRANSFER_ID}")
    transfer.reversals.create()
    
    // 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_BQokikJOvBiI2HlWgH4olfQ2");
    
    $transfer = \Stripe\Transfer::retrieve("{TRANSFER_ID}");
    $transfer->reversals->create(
      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_BQokikJOvBiI2HlWgH4olfQ2";
    
    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
    var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    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_BQokikJOvBiI2HlWgH4olfQ2"
    
    params := &stripe.ReversalParams{
      Amount: 500,
      Transfer: "{TRANSFER_ID}",
    }
    reversal, err := reversal.New(params)
    

    Transfer reversals add the 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 platform reserves enabled.

    Using on_behalf_of

    If you’re creating a charge on behalf of a particular connected account but you want to separate the charge and the transfer, you can use the on_behalf_of attribute when creating the charge. Setting on_behalf_of sets the merchant of record for the charge and funds will be settled using that account. This is especially important for international platforms who have connected accounts in different countries. Setting on_behalf_of:

    • Causes charges to settle in the country of the specified account, thereby minimizing declines.
    • Uses the connected account’s currency to settle, often avoiding currency conversions.
    • Uses the fee structure for the account’s country.
    • If the account is in a different country than the platform, the connected account’s address and phone number shows up on the customer’s credit card statement (as opposed to your own).
    curl https://api.stripe.com/v1/charges \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -d amount=1000 \
       -d currency=usd \
       -d source=tok_5M3c99BSN8rqvKls4VuHpdsH \
       -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_BQokikJOvBiI2HlWgH4olfQ2"
    
    # Token is created using Stripe.js or Checkout!
    # Get the payment token submitted by the form:
    token = params[:stripeToken]
    
    # Create a Charge:
    charge = Stripe::Charge.create({
      :amount => 1000,
      :currency => "usd",
      :source => token,
      :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_BQokikJOvBiI2HlWgH4olfQ2"
    
    # Token is created using Stripe.js or Checkout!
    # Get the payment token submitted by the form:
    token = request.POST['stripeToken']
    
    # Create a Charge:
    charge = stripe.Charge.create(
      amount=1000,
      currency="usd",
      source=token,
      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_BQokikJOvBiI2HlWgH4olfQ2");
    
    // Token is created using Stripe.js or Checkout!
    // Get the payment token submitted by the form:
    $token = $_POST['stripeToken'];
    
    // Create a Charge:
    $charge = \Stripe\Charge::create(array(
      "amount" => 1000,
      "currency" => "usd",
      "source" => $token,
      "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_BQokikJOvBiI2HlWgH4olfQ2";
    
    // Token is created using Stripe.js or Checkout!
    // Get the payment token submitted by the form:
    String token = request.getParameter("stripeToken");
    
    // Create a Charge:
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("amount", 1000);
    params.put("currency", "usd");
    params.put("source", token);
    params.put("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
    var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    // Token is created using Stripe.js or Checkout!
    // Get the payment token submitted by the form:
    var token = request.body.stripeToken; // Using Express
    
    // Create a Charge:
    stripe.charges.create({
      amount: 1000,
      currency: "usd",
      source: token,
      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_BQokikJOvBiI2HlWgH4olfQ2"
    
    // Token is created using Stripe.js or Checkout!
    // Get the payment token submitted by the form:
    token := r.FormValue("stripeToken")
    
    // Create a Charge:
    params := &stripe.ChargeParams{
      Amount: 1000,
      Currency: "usd",
      OnBehalfOf: "{CONNECTED_STRIPE_ACCOUNT_ID}",
    }
    params.SetSource(token)
    
    charge, err := charge.New(params)
    

    Further reading

    Discover what other Connect functionality is available.