Question regarding headless storefront and checkout

Hello we are using a headless implementation of Shopify using Next.js , when a customer tries to check out from our headless store they are redirected to a completely different domain which looks like its part of shopify template store to finalize the payment. Is there a way to keep checkout native and on the domain thats connected to the headless storefront?

TLDR;

Customer visits ourheadlessstore.com

Custom adds item to cart
When customer presses Checkout button customer redirected to blahblahblah-3.myshopify/checkouts/

Any clues on how to keep checkout native on the headless storefront? What am I missing?

Yes, it is possible to keep the checkout process native and on the same domain as your headless Shopify store. This can be achieved through the use of Shopify’s Checkout API.

The Checkout API allows you to build custom checkout experiences for your customers. It provides access to the same checkout data and functions as the default Shopify checkout, but with the added flexibility of allowing you to fully customize the checkout process within your own website.

You are wrong. It is NOT possible unless you create a Sales Channel which is not practical. This is Shopify’s biggest pitfall and reason we don’t recommend it.

Yeah, unfortunately, this is not correct. When it comes to your domain, if you point it to your headless application (which we all will), the checkout will be set to default my-store.shopify.com. This means all links (for instance, the logo on the checkout page) will go back to the default templated store and not your headless application. I have went around this by forwarding EVERYTHING with my-store.shopify to my headless, but unfortunately, the biggest hurdle is having to deal with a checkout that loses continuity from the main app. It works for us but it looks tacky, and feels tacky.

Even a sales channel can not use a native checkout, I have researched and talked with Shopify employees about this, as a sales channel YOU ARE FORCED to use cart permalinks, even though the documentation says that there is a way to use native checkout this is not possible and the documentation is wrong because it is not updated. That’s why there is no single app (apart of Shop) that has a native checkout for Shopify stores. It is not possible to solve this problem even if you become a marketplace (Faire/Amazon/Ebay) because Shopify does not allow you to use their website or store to redirect the checkout to other website. It seems that this is a strategic move from Shopify.

Definitely incorrect.

We spent a great deal of time building out a custom checkout via the Checkout API only to be informed (after many painful discussions with support) that the documentation is outdated and this is no longer possible

“Regardless of whether you’re using the online store or Hydrogen, customers are always directed back to a Shopify-hosted checkout. Traditionally, a checkout URL might look something like {shop}.myshopify.com/123456/checkouts….”

https://shopify.dev/docs/storefronts/headless/hydrogen/migrate#subdomain-for-checkout

This is old but the same issue still occurs as we’ve been dealing with it recently. So I’m chiming in on our ‘solution’.

Honestly, we’ve been really disappointed with how “headless” Shopify actually is when it comes to checkout — it’s headless everywhere except the one place it matters most for continuity. There’s no supported way to keep checkout on your own application’s domain, and the Checkout API route others mentioned above is dead.

That said, after a lot of back and forth we’ve landed on a workaround that gets us ~90% of the way there in terms of branding and flow continuity. Sharing in case it helps anyone:

1. Subdomain for checkout branding

Add a subdomain like checkout.yourapp.com as a domain in Shopify, and set it as the primary domain. This means all checkout pages sit on checkout.yourapp.com/... instead of your-store.myshopify.com/``.... Your actual app stays on yourapp.com as normal — so to the customer it all reads as one brand.

2. Store the return location before handoff

On the checkout trigger button in your app (just before redirecting the user to Shopify checkout), write the URL they should return to into localStorage — based on wherever they are in your app at that moment. This is what lets you drop them back into the correct flow later.

3. Let them check out on Shopify as normal

They complete checkout on the checkout.yourapp.com subdomain.

4. Hijack the post-checkout return

On the order confirmation page, we changed the button copy from “Continue shopping” to just “Continue”. That button naturally points at your Shopify online storefront — which nobody should ever see in a headless setup — so we turned the entire theme into a redirect. In theme.liquid:

liquid

<script>
  window.location.replace('https://yourapp.com/redirect');
</script>

Any hit on the templated store instantly bounces to your app. (This also fixes the problem mentioned above where the checkout logo links back to the templated store as this just hits the redirect too.)

5. Redirect page restores their position

/redirect in your app is just a page with a quick loader. On mount, it reads the stored URL out of localStorage and pushes the user straight there — so they land back exactly where they were in the app, with the flow intact.