Oauth Flow Test - Works With URL in Browser, Does Not Work When Clicking Install

Shopify Partner
6 0 2

For a pubic app, I'm having difficulties in my test environment initiating oauth, but only when I choose to click install in one of my test stores.


If I insert the full url into the browser, the oauth works fine, and I can sign up my test store no issues.


Here's an example of the url I put into my browser:




So now I have uninstalled the app on my test store, and I want to see what happens when I try to reinstall below (this is a screenshot from the uninstalled apps on a test store):


it throws a 400 error.

{"error":"Error during token exchange: 400 Client Error: Bad Request for url: https://myshop.myshopify.com/admin/oauth/access_token"}

this is the url that is produced in the browser:

in my logs I did notice that I am not producing a 'code' in my query params through this method, but I really don't know what to do differently to produce it.


My current app settings:

APP URL: https://ngrok-url.ngrok-free.app/api_connections/shopify/auth/callback-initial

Allowed redirect URL: https://d912-2606-8e80-4805-e800-5593-8453-56a2-1b8a.ngrok-free.app/api_connections/shopify/auth/cal...


I've tried versions switching the APP URL to different endpoints within my program.  Nothing else really makes sense as a url


Normally I'd try in a production environment and let it rip, but I've gotten burned with oauth before, and want to make sure I have everything perfectly set up.


Any help would be much appreciated.

Reply 1 (1)

Shopify Partner
6 0 2

I solved my issue - it had to do with my APP URL declaration.  Must ensure that the app url is not the callback, but the endpoint that actually produces the proper redirect url.


In my case it was ngrok-app/api_connections/shopify/install


for anyone else interested:

async def shopify_install(request: Request, db: Session = Depends(get_db)):
    shop_url = request.query_params.get("shop")
    if not shop_url:
        raise HTTPException(status_code=400, detail="Missing 'shop' parameter")
    shopify_auth_url = get_shopify_auth_url(shop_url, is_shopify_registration=True)
    return RedirectResponse(url=shopify_auth_url, status_code=status.HTTP_303_SEE_OTHER)
def get_shopify_auth_url(shop_url, is_shopify_registration=False, scopes=shopify_scope😞
    if shop_url is None:
        raise ValueError('shop_url is none')
    version = shopify_api_version
    session = shopify.Session(shop_url, version)
    shopify_state = binascii.b2a_hex(os.urandom(15)).decode("utf-8")
    if is_shopify_registration:
        shopify_redirect = f'{base_url}/api_connections/shopify/auth/callback-initial'
        shopify_redirect = f'{base_url}/api_connections/shopify/auth/callback'
    print(f'This is shopify redirect: {shopify_redirect}')
    permission_url = session.create_permission_url(scopes, shopify_redirect, shopify_state)
    return permission_url