Authentication with Connect

    Learn how to authenticate as your users when using Connect, so you can perform any API actions on their behalf.

    There are two ways of authenticating requests when using the Stripe API on behalf of a connected account:

    You should use the Stripe-Account header method when possible: it’s easier and more secure. The second approach is supported for legacy compatibility, but generally shouldn’t be used in new applications. Both approaches require that you store the connected account’s information—ID or API keys–when connecting the account to your platform.

    Authentication via the Stripe-Account header

    The first, preferred, authentication option is to use your—the platform account’s—secret key and pass a Stripe-Account header identifying the connected account for which the request is being made. This curl request performs a refund of a charge on behalf of a connected account:

    curl https://api.stripe.com/v1/charges/{CHARGE_ID}/refunds \
       -u {PLATFORM_SECRET_KEY}: \
       -H "Stripe-Account: {CONNECTED_STRIPE_ACCOUNT_ID}" \
       -d amount=1000
    

    The Stripe-Account header authentication approach is implied in any API request that includes the Stripe account ID in the URL:

    curl https://api.stripe.com/v1/accounts/{CONNECTED_STRIPE_ACCOUNT_ID} \
       -u {PLATFORM_SECRET_KEY}:
    

    All of Stripe’s libraries support this style of authentication on a per-request basis:

    Stripe.api_key = PLATFORM_SECRET_KEY
    Stripe::Customer.create(
      {:email => "person@example.edu"},
      {:stripe_account => CONNECTED_STRIPE_ACCOUNT_ID}
    )
    
    # Fetching an account just needs the ID as a parameter
    Stripe::Account.retrieve(CONNECTED_STRIPE_ACCOUNT_ID)
    
    stripe.api_key = PLATFORM_SECRET_KEY
    stripe.Customer.create(
      email="person@example.edu",
      stripe_account=CONNECTED_STRIPE_ACCOUNT_ID
    )
    
    # Fetching an account just needs the ID as a parameter
    stripe.Account.retrieve(CONNECTED_STRIPE_ACCOUNT_ID)
    
    \Stripe\Stripe::setApiKey(PLATFORM_SECRET_KEY);
    \Stripe\Customer::create(
      array("email" => "person@example.edu"),
      array("stripe_account" => CONNECTED_STRIPE_ACCOUNT_ID)
    );
    
    // Fetching an account just needs the ID as a parameter
    \Stripe\Account::retrieve(CONNECTED_STRIPE_ACCOUNT_ID);
    
    Stripe.apiKey = PLATFORM_SECRET_KEY;
    RequestOptions requestOptions = RequestOptions.builder().setStripeAccount(CONNECTED_STRIPE_ACCOUNT_ID).build();
    
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("email", "person@example.edu");
    
    Customer.create(params, requestOptions);
    
    // Fetching an account just needs the ID as a parameter
    Account.retrieve(CONNECTED_STRIPE_ACCOUNT_ID);
    
    var stripe = require('stripe')(PLATFORM_SECRET_KEY);
    stripe.customers.create(
      {email: "person@example.edu"},
      {stripe_account: CONNECTED_STRIPE_ACCOUNT_ID}
    );
    
    // Fetching an account just needs the ID as a parameter
    stripe.accounts.retrieve(CONNECTED_STRIPE_ACCOUNT_ID);
    
    stripe.Key = PLATFORM_SECRET_KEY
    params := &stripe.CustomerParams{
      Email: "person@example.edu",
    }
    params.SetStripeAccount("{CONNECTED_STRIPE_ACCOUNT_ID}")
    cust, err := customer.New(params)
    
    // Fetching an account just needs the ID as a parameter
    acct, err := account.GetByID("{CONNECTED_STRIPE_ACCOUNT_ID}", nil);
    

    Authentication via API keys

    The second authentication option makes API calls using the connected account’s secret and publishable keys. How a platform receives a connected account’s secret key depends upon the connection method:

    • For Standard and Express accounts, it’s the access_token, provided by the OAuth flow
    • For Custom accounts, it’s in the keys[secret] property returned by the create account API call

    This code performs the same refund request as above using this second authentication method:

    curl https://api.stripe.com/v1/charges/{CHARGE_ID}/refunds \
       -u {CONNECTED_ACCOUNT_SECRET_KEY}: \
       -d amount=1000
    

    If you are using this method, we recommend that you perform authentication with every request, instead of setting the API key globally. All of Stripe’s libraries support this style of authentication on a per-request basis:

    # Not recommended: setting global API key state
    Stripe.api_key = CONNECTED_ACCOUNT_SECRET_KEY
    Stripe::Customer.create(
      :email => "person@example.edu"
    )
    
    # Recommended: sending API key with every request
    Stripe::Customer.create(
      {:email => "person@example.edu"},
      :api_key => CONNECTED_ACCOUNT_SECRET_KEY # account's access token from the Connect flow
    )
    
    # Not recommended: setting global API key state
    stripe.api_key = CONNECTED_ACCOUNT_SECRET_KEY
    stripe.Customer.create(
      email="person@example.edu"
    )
    
    # Recommended: sending API key with every request
    stripe.Customer.create(
      email="person@example.edu",
      api_key=CONNECTED_ACCOUNT_SECRET_KEY # account's access token from the Connect flow
    )
    
    // Not recommended: setting global API key state
    \Stripe\Stripe::setApiKey(CONNECTED_ACCOUNT_SECRET_KEY);
    \Stripe\Customer::create(
      array("email" => "person@example.edu")
    );
    
    // Recommended: sending API key with every request
    \Stripe\Customer::create(
      array("email" => "person@example.edu"),
      array("api_key" => CONNECTED_ACCOUNT_SECRET_KEY) // account's access token from the Connect flow
    );
    
    // Not recommended: setting global API key state
    Stripe.apiKey = CONNECTED_ACCOUNT_SECRET_KEY;
    
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("email", "person@example.edu");
    
    Customer.create(params);
    
    // Recommended: sending API key with every request
    RequestOptions requestOptions = RequestOptions.builder().setApiKey(CONNECTED_ACCOUNT_SECRET_KEY).build();
    
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("email", "person@example.edu");
    
    Customer.create(params, requestOptions);
    
    // Not recommended: setting global API key state
    var stripe = require('stripe')(CONNECTED_ACCOUNT_SECRET_KEY);
    stripe.customers.create({
      email: "person@example.edu"
    });
    
    // Recommended: sending API key with every request
    stripe.customers.create(
      { email: "person@example.edu" },
      { api_key: CONNECTED_ACCOUNT_SECRET_KEY } // account's access token from the Connect flow
    );
    
    // Not recommended: setting global API key state
    stripe := &client.API{}
    stripe.Init("access_token", "CONNECTED_ACCOUNT_SECRET_KEY")
    params := &stripe.CustomerParams{
      Email: "person@example.edu",
    }
    cust, err := customer.New(params)
    
    // Recommended: sending API key with every request
    params := &stripe.CustomerParams{
      Email: "person@example.edu",
      Key: "CONNECTED_ACCOUNT_SECRET_KEY",
    }
    cust, err := customer.New(params)
    

    Next steps

    See what API calls you can perform actions on behalf of your users: