Short answer
Coming back to your return URL doesn’t mean onboarding is complete. Retrieve the account and read its requirements: as long as requirements.currently_due isn’t empty, it can be restricted. Send the seller back through a new Account Link when anything is due, create a fresh link from your refresh URL when one expires, and listen to account.updated so new requirements don’t surprise you.
Why the account is still restricted, and the fix
01
Your app treats the return URL as “done”
“It doesn’t mean that all information has been collected, or that there are no outstanding requirements on the account.” Stripe, Stripe-hosted onboarding
Stripe sends the seller to your return URL when they finish or click Save for later, and passes no status with it. If your app marks the seller as ready at that point, it can be wrong. Retrieve the account and check charges_enabled, payouts_enabled and the requirements hash, or cache the state from account.updated events.
02
The Account Link expired or was already used
“Many clients automatically visit links, which causes an Account Link to expire.” Stripe, Stripe-hosted onboarding
Each Account Link works once and only for a few minutes. Opening it twice, pressing back, or pasting it into a messaging app that previews links sends the seller to your refresh URL. Your refresh URL should create a new Account Link with the same parameters and redirect to it. In live mode both URLs must be HTTPS. Stripe’s sample asks for eventually_due fields, which is up-front onboarding; for incremental onboarding, set collection_options[fields] to currently_due.
curl https://api.stripe.com/v1/account_links \ -u "sk_test_...:" \ -d "account={{CONNECTED_ACCOUNT_ID}}" \ --data-urlencode "refresh_url=https://example.com/refresh" \ --data-urlencode "return_url=https://example.com/return" \ -d type=account_onboarding \ -d "collection_options[fields]=eventually_due"03
New requirements appeared after onboarding
“Send a connected account back through onboarding when it has any currently_due or eventually_due requirements.” Stripe, Stripe-hosted onboarding
Requirements can change over time, for example when an account reaches a threshold: an eventually_due item that becomes required shows up in currently_due too. Anything in currently_due has a deadline (requirements.current_deadline). Stripe typically disables payouts if it isn’t provided in time, and fields still missing at the deadline move to past_due. You don’t need to work out which fields are missing: send the seller back through onboarding and it asks for what’s needed.
04
Verification failed
“If verification or validation is unsuccessful, requirements can reappear in currently_due, alternative_fields_due, or eventually_due with error information.” Stripe, Handle verification with the API
A typo can stop Stripe verifying the owner’s identity, and the requirement comes back with an error attached. While Stripe is still reviewing, the item sits in requirements.pending_verification, so wait for the account.updated event before sending the seller back. Read requirements.errors for the reason, and send the seller back through onboarding to fix it, where Stripe may ask for an identity document.
Checked against the vendor’s docs on : Stripe docs: Stripe-hosted onboarding; Stripe docs: Handle verification with the API.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way.See scope and start
Related: Stripe works in test mode, not live · Stripe webhook 200 but database not updated · Stripe subscription stuck incomplete · Stripe paid, account not upgraded