Using Connect with Standard Accounts

    Integrating with Standard accounts is the fastest and easiest way to get started using Connect, since you'll be offloading the majority of the user experience and user communication to Stripe.

    A Standard Stripe account is a conventional Stripe account controlled directly by the account holder (i.e., your platform’s user). A user with a Standard account has a relationship with Stripe, is able to log in to the Dashboard, can process charges on their own, and can disconnect their account from your platform.

    You can prompt your users to create Stripe accounts, or allow anyone with an existing Stripe account to connect to your platform.

    The OAuth connection flow

    A user connects to your platform using the following OAuth connection flow:

    1. Starting on a page at your site, the user clicks a link that takes them to Stripe, passing along your platform’s client_id.
    2. On Stripe’s website, the user provides the necessary information for connecting to your platform.
    3. The user is then redirected back to your site along with an authorization code.
    4. Your site then makes a request to Stripe’s OAuth token endpoint to complete the connection and fetch the user’s account ID.

    When these steps are done, API requests can be made on behalf of the user with their account ID or authorization credentials.

    Step 1: Create the OAuth link

    To get started with your integration, you need two pieces of information from your platform settings:

    • Your client_id, a unique identifier for your platform, generated by Stripe
    • Your redirect_uri, a page on your website to which the user is redirected after connecting their account (or failing to, should that be the case), set by you

    Stripe also provides a development client_id to make testing easier.

    With these two pieces of information in hand, you’re ready to create the OAuth link. We recommend showing a Connect button that sends users to our authorize_url endpoint:

    The Stripe endpoint should receive at least these three parameters:

    • response_type, with a value of code
    • Your client_id
    • scope, with a value of read_write

    The scope parameter dictates what your platform can do on behalf of the connected account, with read_only being the default.

    To prevent CSRF attacks, add the state parameter, passing along a unique token as the value. We’ll include the state you gave us when we redirect the user back to your site.

    Here’s how the above URL can be presented to your user to begin the connection:

    Connect with Stripe

    Step 2: User creates or connects their account

    After the user clicks the link on your site, they'll be taken to Stripe's website where they'll be prompted to allow or deny the connection to your platform.

    Unlike most OAuth implementations (like Facebook Connect or Sign In with Twitter), we've seamlessly added the process of creating a Stripe account right into our authorization flow. You don't have to worry about whether or not your users already have accounts!

    The user is logged in and can connect directly.

    The user needs to create an account.

    Step 3: User is redirected back to your site

    After the user connects their existing or newly created account to your platform, they are redirected back to your site, to the URL established as your platform’s redirect_uri.

    For successful connections, we’ll pass along in the URL:

    • The scope granted
    • The state value, if provided
    • An authorization code{AUTHORIZATION_CODE}

    If the authorization was denied by the user, they'll still be redirected back to your site, but the URL includes an error instead of the authorization code:

    Step 4: Fetch the user's credentials from Stripe

    Assuming no error occurred, the last step is to use the provided code to make a POST request to our access_token_url endpoint to fetch the user’s Stripe credentials:

    curl \
      -d client_secret=sk_test_4eC39HqLyjWDarjtT1zdp7dc \
      -d code="{AUTHORIZATION_CODE}" \
      -d grant_type=authorization_code

    Note that you’ll make the request with your live or test secret API key, depending on whether you want to get a live or test access token back.

    Stripe returns a response containing the authentication credentials for the user:

      "token_type": "bearer",
      "stripe_publishable_key": "{PUBLISHABLE_KEY}",
      "scope": "read_write",
      "livemode": false,
      "stripe_user_id": "{ACCOUNT_ID}",
      "refresh_token": "{REFRESH_TOKEN}",
      "access_token": "{ACCESS_TOKEN}"

    If there was a problem, we instead return an error:

      "error": "invalid_grant",
      "error_description": "Authorization code does not exist: {AUTHORIZATION_CODE}"

    You’re done! The user is now connected to your platform. Store the stripe_user_id in your database; this is the Stripe account ID for the new account. You’ll use this value to authenticate as the connected account by passing it into requests in the Stripe-Account header. (It’s also possible to authenticate with the secret key returned here, but it’s more secure to store and use only the account ID instead.)

    In your application, you might want to consider using a dedicated OAuth client library to simplify these steps. To find an OAuth library for your language or framework, you can refer to the list of client libraries on the OAuth website.

    The refresh_token can be used to generate test access tokens for a production client_id or to roll your access token. You should hold on to this value, too, as you’re only able to get it after this initial POST request.

    Revoked and revoking access

    An account.application.deauthorized event occurs when a user disconnects your platform from their account. By watching for this event via webhooks, you can perform any necessary cleanup on your servers.

    To disconnect a Standard account from your platform, POST your client_id and the connected account’s ID to

    curl \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -d client_id=ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7 \
      -d stripe_user_id=acct_EKaKDUvlwX5M7r
    # Using stripe-ruby
    acct = Stripe::Account.retrieve('acct_eKG1nCCRtKrtcR')
    # Using rest-client:
        client_id: 'ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7',
        stripe_user_id: 'acct_x1VrsZ5whG1PDX',
      {Authorization: 'Bearer sk_test_4eC39HqLyjWDarjtT1zdp7dc'}
    # Using requests:
        'client_id': 'ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7',
        'stripe_user_id': 'acct_p2aQmV54QIUhkp',
      headers={'Authorization': 'Bearer sk_test_4eC39HqLyjWDarjtT1zdp7dc'}
    // Using curl:
    $api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc';
    $curl = curl_init();
    curl_setopt_array($curl, [
      CURLOPT_URL => '',
      CURLOPT_HTTPHEADER => ["Authorization: Bearer $api_key"],
      CURLOPT_POST => true,
      CURLOPT_POSTFIELDS => http_build_query([
        'client_id' => 'ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7',
        'stripe_user_id' => 'acct_t8nPcLtd2RoApu',
    // Using Apache HttpComponents:
    CloseableHttpClient httpclient = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("");
    httpPost.setHeader("Authorization", "Bearer sk_test_4eC39HqLyjWDarjtT1zdp7dc");
    List <NameValuePair> nvps = new ArrayList <NameValuePair>();
    nvps.add(new BasicNameValuePair("client_id", "ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7"));
    nvps.add(new BasicNameValuePair("stripe_user_id", "acct_sNcAvgtofzfU63"));
    httpPost.setEntity(new UrlEncodedFormEntity(nvps));
    CloseableHttpResponse response = httpclient.execute(httpPost);
    // Using request:
    var request = require('request');{
      url: '',
      formData: {
        client_id: 'ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7',
        stripe_user_id: 'acct_pHRrxWUCzoKWsd',
      headers: {'Authorization': 'Bearer sk_test_4eC39HqLyjWDarjtT1zdp7dc'},
    // Using "net/http":
    client := &http.Client{}
    req, err := http.NewRequest("POST",
            "client_id": {"ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7"},
            "stripe_user_id": {"acct_1JrWUnCZVjatf5"}
    req.Header.Add("Authorization", "Bearer sk_test_4eC39HqLyjWDarjtT1zdp7dc")
    resp, err := client.Do(req)

    Next steps

    Now you can use the API on your user's behalf to accept payments, set up recurring billing, fetch account data, and more:

    Join the Stripe Partner Program to get best practices across a range of topics like how to optimize your Stripe integrations, effectively go to market, and answer frequently asked questions about Stripe and payments.

    Was this page helpful?

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


    We're always happy to help with code or other questions you might have. Search our documentation, contact support, or connect with our sales team. You can also chat live with other developers in #stripe on freenode.

    On this page