Earlier, we were using custom (legacy) apps for each client. Each merchant created their own custom app in their store, granted the required scopes, generated an access token, and shared it with us.
This worked well because:
Each store had its own app
Scopes were store-specific
Only a few special clients needed additional scopes like read_orders, and adding that scope did not affect other stores
Now, we have migrated to a public Shopify app with OAuth.
In the new flow:
We define scopes in the app configuration / app version
During installation, merchants see the Shopify-hosted permission page
All merchants installing the app must approve the same set of scopes
The problem:
Some merchants want us to read their orders (read_orders), but most merchants do not want or need this permission.
If I add read_orders to the app scopes:
Every merchant installing the app will be asked to approve read_orders, even if they don’t need it
If I don’t add it:
I can’t access orders for the few merchants who explicitly want to allow it
My question:
What is the recommended way to handle this use case in a public Shopify app?
Is it possible to request additional scopes only for specific merchants?
Can we perform a secondary OAuth / reauthorization flow for selected merchants?
Or is creating a separate app the only recommended approach?
Any guidance or best practices from the Shopify team would be greatly appreciated.
Hi @Shopping_IQ! This is a perfect use case for Optional Access Scopes which lets you declare scopes that are available to your app but not requested by default during installation.
To set this up, you’ll need to move read_orders from the scopes list to optional_scopes in your shopify.app.toml.
[access_scopes]
scopes = "write_products,read_products" # Standard scopes for everyone
optional_scopes = "read_orders" # Scopes for specific merchants
Once that’s pushed with shopify app deploy, you can request the scope dynamically for just the merchants who need it. If you’re using App Bridge, you can use shopify.scopes.request to trigger a modal:
shopify.scopes.request(['read_orders']);
Alternatively, you can redirect the merchant to the install URL with the optional_scopes query parameter: https://admin.shopify.com/store/{shop}/oauth/install?client_id={client_id}&optional_scopes=read_orders.
This way, regular users just accept the base permissions, and only the ones opting into that feature get prompted for the extra access.
The {STORE_NAME} in the URL format should just be the store name (feed-iq-store), not the full myshopify domain. The system was seeing feed-iq-store.myshopify.com.myshopify.com and failing to resolve it.
Once you fix that, make sure read_orders is declared in your optional_scopes in your TOML and deployed with shopify app deploy - otherwise you’ll hit a different error.
Also you can use the App Bridge to request additional scopes:
This is really handy, because you can craft your merchant UX to only request for additionally scopes at the time they enabled a specific setting or open a specific page.
There’s also real time querying for current scopes, as well as the ability to revoke scopes directly from the AppBridge.
Thanks @Donal-Shopify Now its working you have not only solved my problem but also saved my time. That edge case was head ache for me but now i finally find the solution that you have provided.