After AppSubscription confirmation, redirect back to app triggers re-auth asking for shop (session lost)

Hi everyone — looking for help with an embedded app redirect issue during billing.

  • Stack: Remix + @shopify/shopify-app-remix, Prisma session storage, App Bridge, Polaris
  • Auth: authenticate.admin(request) with embedded app (App Store distribution)
  • Billing: appSubscriptionCreate with confirmation URL, then return to /app/billing

Problem

When the merchant approves the subscription in Shopify’s confirmation screen, the redirect back to my app lands on /app/billing, but I immediately get bounced to the auth flow asking for the shop domain (as if the session is gone).

Example redirect URL after confirmation:

/app/billing?embedded=1&hmac=...&host=YWRtaW4uc2hvcGlmeS5jb20vc3RvcmUvMDBxeG5lLWV0&id_token=...&locale=en&session=...&shop=00qxne-et.myshopify.com&timestamp=...

What I’m doing now

  • Creating the subscription:
    • returnUrl is built as:
      • const host = new URL(request.url).searchParams.get('host')
      • const appBase = process.env.SHOPIFY_APP_URL || currentOrigin
      • const returnUrl = ${appBase}/app/billing${host ? ?host=${host}&embedded=1 : ''}
  • Server returns confirmationUrl JSON (no server-side redirect).
  • Client does:
useEffect(() => {
  if (actionData?.success && actionData.confirmationUrl) {
    window.open(actionData.confirmationUrl, '_top');
  }
}, [actionData]);
  • On return, the URL includes host, embedded=1, shop, session, but authenticate.admin(request) still triggers login asking for shop.

Relevant config

  • shopifyApp({ appUrl: process.env.SHOPIFY_APP_URL, authPathPrefix: '/auth', sessionStorage: new PrismaSessionStorage(prisma), distribution: AppStore, future: { unstable_newEmbeddedAuthStrategy: true } })
  • SHOPIFY_APP_URL is set to the public HTTPS domain.
  • Sessions persist fine elsewhere; only this billing return path exhibits the issue.

What I’ve tried

  • Server-side redirect vs. client window.open('_top')
  • Ensuring returnUrl matches SHOPIFY_APP_URL host + https
  • Preserving host + embedded=1 on returnUrl
  • Verifying the route is loaded within the embedded context (has host, embedded=1)
  • Confirmed session tables are writable and used for other routes

Hey! I’m moving this over in to the authentication and access board as this may be better suited here.

Fixed it! Just returned to a different url.