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 Standard account connects to your platform using OAuth, going through these steps:
- Starting on a page at your site, the user clicks a link that takes them to Stripe, passing along your platform’s
client_id
. - On Stripe’s website, the user is prompted to connect their Stripe account or create and connect a new account.
- The user is then redirected back to your site, passing along either an authorization code or an error if the user chooses not to connect.
- Your site then makes a request to our OAuth token endpoint to fetch the user’s account ID, storing it on your site.
After completing Step 4, API requests can be made on behalf of the connected account using their 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:
https://connect.stripe.com/oauth/authorize?response_type=code&client_id=ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7&scope=read_write
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:
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!
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
https://stripe.com/connect/default/oauth/test?scope=read_write&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:
https://stripe.com/connect/default/oauth/test?error=access_denied&error_description=The%20user%20denied%20your%20request
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 https://connect.stripe.com/oauth/token \
-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
https://connect.stripe.com/oauth/deauthorize
:
curl https://connect.stripe.com/oauth/deauthorize \
-u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
-d client_id=ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7 \
-d stripe_user_id=acct_qlaZ93jG9qL2yN
# Using stripe-ruby
acct = Stripe::Account.retrieve("acct_thPg3XtdtKSWSY")
acct.deauthorize('ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7')
# Using rest-client: http://www.rubydoc.info/github/rest-client/rest-client
RestClient.post(
'https://connect.stripe.com/oauth/deauthorize',
{
client_id: 'ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7',
stripe_user_id: 'acct_Ijm473zpuMHOsi',
},
{Authorization: 'Bearer sk_test_4eC39HqLyjWDarjtT1zdp7dc'}
)
# Using requests: http://docs.python-requests.org/en/master/
requests.post(
'https://connect.stripe.com/oauth/deauthorize',
data={
'client_id': 'ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7',
'stripe_user_id': 'acct_52eTqb9zk2yDal',
},
headers={'Authorization': 'Bearer sk_test_4eC39HqLyjWDarjtT1zdp7dc'}
)
// Using curl: https://secure.php.net/manual/en/book.curl.php
$api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc';
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://connect.stripe.com/oauth/deauthorize',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer $api_key"],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'client_id' => 'ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7',
'stripe_user_id' => 'acct_HEBlDRqcxqvq8D',
])
]);
curl_exec($curl);
// Using Apache HttpComponents: https://hc.apache.org/
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("https://connect.stripe.com/oauth/deauthorize");
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_6TAUUNVc1dhDYG"));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
CloseableHttpResponse response = httpclient.execute(httpPost);
// Using request: https://github.com/request/request
var request = require('request');
request.post({
url: 'https://connect.stripe.com/oauth/deauthorize',
formData: {
client_id: 'ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7',
stripe_user_id: 'acct_KuWSgC6RkG7Arn',
},
headers: {'Authorization': 'Bearer sk_test_4eC39HqLyjWDarjtT1zdp7dc'},
});
// Using "net/http": https://golang.org/pkg/net/http/
client := &http.Client{}
req, err := http.NewRequest("POST",
"https://connect.stripe.com/oauth/deauthorize",
strings.NewReader(url.Values{
"client_id": {"ca_32D88BD1qLklliziD7gYQvctJIhWBSQ7"},
"stripe_user_id": {"acct_3NpX7FzLAH5rAo"}
}.Encode()),
)
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.