Stripe Connect lets platforms make API calls on behalf of connected accounts. This guide covers both direct API access and the OAuth onboarding flow.
Making Calls on Behalf of Connected Accounts
Pass stripe_account to set the Stripe-Account header, either on the
client or per-request:
On the Client
All calls made with this client will target the connected account:
client = Stripe.client("sk_test_platform",
stripe_account: "acct_connected_123"
)
{:ok, charge} = Stripe.Services.ChargeService.retrieve(client, "ch_123")
{:ok, customer} = Stripe.Services.CustomerService.list(client, %{"limit" => 10})Per-Request
Override for a single call without changing the client:
client = Stripe.client("sk_test_platform")
{:ok, charge} = Stripe.Services.ChargeService.retrieve(client, "ch_123",
stripe_account: "acct_connected_123"
)OAuth Flow
Use Stripe.OAuth to onboard connected accounts via the OAuth authorization
flow. This requires a client_id from your
Connect settings.
1. Build the Authorization URL
Redirect the user to Stripe's authorization page:
client = Stripe.client("sk_test_...", client_id: "ca_...")
{:ok, url} = Stripe.OAuth.authorize_url(client, %{
scope: "read_write",
redirect_uri: "https://example.com/callback"
})
# Redirect the user to `url`2. Exchange the Authorization Code
After the user authorizes, Stripe redirects back with a code parameter.
Exchange it for access tokens:
{:ok, resp} = Stripe.OAuth.token(client, %{
grant_type: "authorization_code",
code: "ac_..."
})
# resp contains:
# - stripe_user_id: the connected account ID
# - access_token: for making API calls
# - refresh_token: for refreshing the access token3. Deauthorize
Revoke access to a connected account:
{:ok, resp} = Stripe.OAuth.deauthorize(client, %{
client_id: "ca_...",
stripe_user_id: "acct_..."
})Multi-Tenant Patterns
For platforms serving many connected accounts, create clients dynamically:
defmodule MyApp.Stripe do
def client_for_account(account_id) do
Stripe.client(platform_key(),
stripe_account: account_id
)
end
defp platform_key do
Application.fetch_env!(:my_app, :stripe_secret_key)
end
end
# Usage
client = MyApp.Stripe.client_for_account("acct_123")
{:ok, charges} = Stripe.Services.ChargeService.list(client, %{"limit" => 5})Since clients are plain structs with no global state, this is safe for concurrent use across processes.