← library
Self-serve, legacy path
Payments platform / Connect account-linking OAuth·agent-generated · deepseek-v4.1-flash·checked 2026-10-28
difficulty
2/5

Stripe's OAuth is Connect account-linking for Standard accounts, not a "Sign in with Stripe": there is no discovery document (both well-knowns 404 or return the SPA's HTML), so you hardcode https://connect.stripe.com/oauth/authorize, and your only scopes are read_write for everyone or read_only for Extensions only.

First working connection
~1–2 hours
Production / approved
~1–3 days (platform verification), plus each seller's own KYC
Composio managed OAuth
Available: ship today
Composio lists a managed OAuth app for this toolkit — you can ship on it while your own app is set up or reviewed.
who does itagent 4you 4provider 0
evidencetested 7sourced 23inferred 7
◆ agent run12 pages read19/22 quotes verified verbatim50s$0.020deepseek-v4.1-flash

01Pick your path

Connect OAuth (Standard accounts)
when You are an extension or existing platform that needs to attach to sellers' existing Standard Stripe accounts.
→ Authorization code in hand; read_write (or read_only for Extensions) on that seller's account. Hardcoded endpoints, no discovery.
Connect Onboarding via Account Links
when You are building a new platform/marketplace in 2025+ — this is what Stripe recommends.
→ A new connected account you control, with scoped capabilities; Stripe-hosted KYC. No OAuth token, no shared seller login.
API keys on your own account
when Your agent only needs to operate your own Stripe account.
→ Restricted live key (rk_live_) or sandbox sk_test_; fastest route, but it acts as you, not as your users.
Embedded components / Account Sessions
when You need dashboard access for sellers inside your product rather than API access from your server.
→ Seller sees a Stripe-dashboard slice inside your UI, without OAuth.

02Time & effort

Hands-on work
1.2 h – 3.8 h
Waiting on others
1 day – 3 days
You're actually working
5% of elapsed time
Phases
5
start↑ first working connection, then production pathproduction
  1. DEVRegister platform + create the Connect app20–45 minutessourced[S10][S11][S2]Register the platform, verify business details, complete platform profile, then read client_id from application settings. Needs your legal identity — not delegable.
  2. DEVAdd redirect URIs, build authorize + callback30–90 minutessourced[S2]Agent can write the URL builder, state handling and callback code; you must paste the URIs into application settings.
  3. DEVSandbox round-trip with a Standard test account20–60 minutessourced[S2][S5]You must click through the Stripe consent screen yourself; the agent can only assert on the returned code.
  4. PRODLive-mode activation (platform profile + business verification)wait 1–3 daysinferredEstimate. Sources list the steps but give no turnaround time.
  5. PRODEach seller connects and passes their own KYC5–30 minutessourced[S6][S2]Per connected account. SSN last-4, DOB, address, business URL etc. are collected in the seller's own account — the agent cannot supply these.
agent can do it you waiting on providerbar widths ∝ √time, so short tasks stay visible

03Steps

0/8 done

Get a working connection

  1. Pick the right integration: Connect OAuth vs Onboarding vs API keysagentsourced ❝[S5][S3][S12]

    OAuth here connects a seller's existing Standard Stripe account to your platform. If you're building a new platform, Stripe points you at Connect Onboarding (Account Links) instead, and its API keys doc describes key-based auth (sk_test_, rk_live_) for your own account.

    “If you’re an extension or an application that needs access to an existing account so you can provide services to your users, you can still use OAuth.” — [S5] verified verbatim
  2. Register the platform in the Dashboardyousourced ❝[S10][S11]

    Register the platform, verify business details, complete the platform profile and brand settings. This is the only part with no agent substitute — it needs your legal identity.

    “Verify and add business details in Dashboard.” — [S10] verified verbatim
  3. Register redirect URIs and copy client_idyousourced ❝[S2]

    client_id lives in application settings; redirect_uri values are a comma-separated list there. Add one per environment (localhost for test, HTTPS for live) before writing any code, because authorization fails on mismatch.

    “If provided, this must exactly match one of the comma-separated redirect_uri values in your application settings.” — [S2] verified verbatim
  4. Build the authorize redirectagentsourced ❝[S2]

    response_type=code is the only option. Set scope explicitly (read_write unless you're an Extension) and always include state for CSRF. stripe_user[...] prefill params only help users creating a new account; they're ignored for existing users.

    “Prefilling has no effect if your user already has a Stripe account.” — [S2] verified verbatim
    ◆ prepared by agent · Authorize URL builder
    https://connect.stripe.com/oauth/authorize
      ?response_type=code
      &client_id=ca_XXXXXXXXXXXXXXXXXXXXXXXX
      &scope=read_write
      &redirect_uri=https%3A%2F%2Fapp.example.com%2Fstripe%2Fcallback
      &state=<random-csrf-nonce>
      # optional prefill (silently ignored if invalid):
      &stripe_user[email]=seller%40example.com
      &stripe_user[country]=US
      &stripe_user[business_type]=llc
  5. Handle the callback and exchange the codeagentinferred[S2]

    Verify state matches, then exchange the returned code for an account token using your client secret server-side. The token-exchange endpoint isn't in the pages fetched here — confirm its URL and parameters in Stripe's Connect OAuth docs before coding.

  6. Confirm Platform vs Extension before promising read_onlyyousourced ❝[S12]

    Check Connect Settings → Availability. Platform registrations can't use read_only or attach to platform-controlled Standard accounts; only Stripe can flip the selection.

    “However, if you previously selected Platform for your Connect application and you now need Extension functionality, you must contact us to modify your integration selection.” — [S12] verified verbatim
    ◆ prepared by agent · Integration-selection change request
    Subject: Connect integration selection change — Platform → Extension
    
    Hi Stripe team,
    
    Our Connect platform (account: acct_..., client_id: ca_...) is registered with integration selection "Platform" under Connect Settings → Availability. We need Extension behaviour: (a) read_only scope, and (b) the ability to attach to Standard accounts that may already be connected to another Platform or Extension, since our product provides services to sellers who already have Stripe accounts.
    
    No change to our funds flow: we do not process payments on these accounts.
    
    Could you change our integration selection to Extension? Happy to provide any details you need.
    
    Thanks,
    <name, company, platform account id>

Make it production-ready

  1. Go live: HTTPS URIs, live client, minimal scopeyousourced ❝[S2]

    Swap in the live client_id, confirm every redirect URI is HTTPS and exact, and only request read_write if you truly need write access to the seller's account.

    “To protect yourself from certain forms of man-in-the-middle attacks, the live mode redirect_uri must use a secure HTTPS connection.” — [S2] verified verbatim
  2. Bake in the data-sharing disclosureagentinferred[S2]

    read_write gives you access to that seller's charges, customers, invoices and payout data. Draft a one-paragraph explanation of what you touch and why for your onboarding screen, and never log tokens or the authorization code.

04Requirements, scopes & nuances

You'll need

  • ▸A Stripe account with a registered platform: business details verified and platform profile completed in the Dashboard before going live. sourced ❝[S10][S11]
  • ▸OAuth client_id (starts with ca_) from your application settings, plus each redirect URI pre-registered — multiple URIs are allowed. sourced ❝[S2]
  • ▸Live-mode redirect URIs must be HTTPS and match the configured value exactly; HTTP is test-only. sourced ❝[S2]
  • ▸The connected account must be one that can access the full Stripe Dashboard — this OAuth reference applies only to those configurations. inferred[S2]
  • ▸If you create accounts rather than attach them, expect to collect MCC, business URL, statement descriptor, TOS acceptance, external account, and for individuals: name, DOB, address, email, phone, SSN last-4. inferred[S6]

Gotchas

  • !There are exactly two scopes: read_write (full read/write on the connected account) and read_only (Extensions only). No granular per-resource scopes, no openid/email/profile. sourced ❝[S2][S12]
  • !Stripe documents OAuth as a legacy path: the Standard-accounts page says to use Connect Onboarding for new integrations and reserves OAuth for extensions/apps that need to attach to existing accounts. sourced ❝[S5]
  • !Data is shared by default: whatever you create on a Standard account is visible in that seller's Dashboard, and if they connect other platforms, those platforms see it too. sourced ❝[S2]
  • !Your integration selection (Platform vs Extension) lives in Connect Settings under Availability, and Platform→Extension changes require contacting Stripe. sourced ❝[S12]
  • !Prefill parameters (stripe_user[...]) are silently ignored when invalid — a typo'd country or DOB field won't error, it just won't prefill. sourced ❝[S2]
Scope / permissionTierNoteEvidence
read_writerestrictedFull read/write on the connected account. Can't attach to accounts controlled by another platform (post-June 2021).sourced ❝[S2][S12]
read_onlygatedDefault if scope is omitted, but 'can only be specified for extensions' — a Platform-registered integration will be rejected.sourced ❝[S2][S12]
openid / profile / emailgatedNot offered. This is Connect account-linking, not a login identity provider; no such scopes appear in the OAuth reference.inferred[S2]

05If you get blocked

✕read_only scope is refused because you registered as a Platform integrationsourced ❝[S12][S2]

→ Select the Extension integration type at registration, or contact Stripe to change it — Extension is the only path to read_only (and the only path that can attach to an account another platform controls).

✕read_write OAuth can't attach to a Standard account already controlled by another platform (post-June 2021)sourced ❝[S12][S2]

→ Let the onboarding flow create a separate Standard account for that seller; it auto-connects to your platform.

✕Your client library expects OIDC discovery and fails because no JSON metadata existsinferred[S2]

→ Hardcode https://connect.stripe.com/oauth/authorize (and the /oauth/v2/authorize path seen in the probe) instead of building a discovery-driven flow.

✕redirect_uri mismatch error at authorize timesourced ❝[S2]

→ Register every redirect URI in application settings first; add a redirect_uri param that exactly matches one of them (HTTPS in live mode).

06Evidence: what was tested, sourced, and still uncertain

$ probes: live GETs with a dummy client_id, no credentials
✓ Discovery document (/.well-known/openid-configuration) → 404
https://stripe.com/.well-known/openid-configuration
not published
∴ Stripe publishes no OIDC discovery for its main domain. Don't build a discovery-first client against stripe.com.
✓ Discovery document (/.well-known/oauth-authorization-server) → 404
https://stripe.com/.well-known/oauth-authorization-server
not published
∴ Same: 404. No RFC 8414 metadata on the marketing domain.
✓ Discovery document (/.well-known/openid-configuration) → 200
https://dashboard.stripe.com/.well-known/openid-configuration
non-JSON (text/html;charset=utf-8)
∴ 200 with text/html is the dashboard SPA catch-all, not metadata. Parsing this as JSON will crash your client — the endpoints must be hardcoded.
✓ Discovery document (/.well-known/oauth-authorization-server) → 200
https://dashboard.stripe.com/.well-known/oauth-authorization-server
non-JSON (text/html;charset=utf-8)
∴ Same SPA fallback — 200 is a false positive; there is no OIDC issuer here.
✓ Discovery document (/.well-known/openid-configuration) → 200
https://connect.stripe.com/.well-known/openid-configuration
non-JSON (text/html;charset=utf-8)
∴ The Connect host also returns HTML for /.well-known/*, so no discovery even on the host that actually serves the authorize endpoint.
✓ Discovery document (/.well-known/oauth-authorization-server) → 200
https://connect.stripe.com/.well-known/oauth-authorization-server
non-JSON (text/html;charset=utf-8)
∴ Confirms discovery is absent on the real OAuth host; read the docs, not the metadata.
✓ Authorize endpoint with a fake client_id → 302
https://connect.stripe.com/oauth/authorize?client_id=probe_invalid_client&response_type=code&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
redirect → https://connect.stripe.com/oauth/v2/authorize?client_id=probe_invalid_client&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback&response_type=code
∴ The authorize endpoint is live and redirects to the v2 path even with a bogus client_id — you'll get the invalid-client error at that second hop, so log the final URL when debugging.

Still uncertain

  • ? Token-exchange endpoint, token lifetime, refresh behaviour and revocation are not covered by the fetched sources — verify in Stripe's Connect OAuth docs before implementing.
  • ? No source states a review or approval turnaround for Connect platform registration; the 1–3 day production window is my estimate.
  • ? Whether brand-new platforms can still create a Connect OAuth application (as opposed to Extensions only) is not stated explicitly; the docs only say OAuth is what extensions and existing apps use.
  • ? Exact Dashboard URLs were not in the fetched pages — navigation is given as Settings → Connect → Availability, not a link.
  • ? Pricing, per-account Connect fees and marketplace vs SaaS fee responsibility are described qualitatively in S8 but no numbers were fetched.
  • ? Generated automatically; no app was registered and no review was submitted.