Solved

Storefront API - App must have a channel record

CoreyW
Tourist
6 0 5

I am trying to connect my public app to the storefront API by creating an access token.

I have authorized the app with all of the unauthorized scopes (https://shopify.dev/docs/storefront-api/access-scopes)

Here is the full scope list of the unauthenticated list returned after from /admin/oauth/access_token

unauthenticated_read_product_listings, unauthenticated_read_product_tags, unauthenticated_write_checkouts, unauthenticated_write_customers, unauthenticated_read_customer_tags, unauthenticated_read_content

When I try to create the token, I am still getting this error:

App must have a channel record to create a storefront access token.

Does this mean that ALL storefront API's need to be created with a token? Or am I doing something wrong.

Any help would be greatly appreciated!

Accepted Solution (1)
BStubbs
Shopify Partner
136 16 62

This is an accepted solution.

Hi @CoreyW ,

To answer your question, yes, but also no. 🤦🏻‍♂️

From the Storefront API docs:

To authenticate with the Storefront API as either a private or public app, you need to obtain a storefront access token with the unauthenticated access scopes.

...

When building a private app, you can obtain a storefront access token by creating a private app.

...

To authenticate to the Storefront API as a public app you need to turn your app into a sales channel.

https://shopify.dev/docs/storefront-api/getting-started 

So if you were using a private app, you would not need to turn your app into a sales channel, however since you are making a Public App, you don't have a choice, it must be a sales channel.

Unauthenticated scopes doesnt mean that the app is unauthenticated, it means the client is unauthenticated, that is to say, they are not known to the shop. But your app needs to be authorized to interact with the shop on the behalf of the authorized user. 

If you want the sales processed to be part of the online shop, maybe it would be better to build with Liquid and the Shopify Admin API instead? If it is going to be within the Online Store? That sounds more like what you are describing wiht the other apps.

Was this helpful? Press like!
Did it fix the problem? Mark it as the solution for others!
Buy me a beer? Well, sure!

View solution in original post

Replies 12 (12)

BStubbs
Shopify Partner
136 16 62

Looks like the error might be relating to the need to create the sales channel for your app. Have you done that?

Was this helpful? Press like!
Did it fix the problem? Mark it as the solution for others!
Buy me a beer? Well, sure!
CoreyW
Tourist
6 0 5

Sorry, I was writing that late last night -- I meant to write: "Does that mean ALL storefront API's need to be used with a sales channel"?

My understanding from the documentation is that if they were using the unauthorized scope, they didn't need to specifically be a sales channel, unless you were intending to process a payment.

I am not looking to complete a checkout or process any payments, I am simply looking to build a checkout and get a link to send them to the last (purchase) page of the checkout with products. I would like the sales to ultimately be attributed to the: "Online Store" sales channel.

I have seen some 3rd party apps send you to the last checkout page with your information and shipping method chosen, without having to be a sales channel listed on a store.

DGP
Excursionist
12 0 6

Getting this answered would be really useful!

BStubbs
Shopify Partner
136 16 62

This is an accepted solution.

Hi @CoreyW ,

To answer your question, yes, but also no. 🤦🏻‍♂️

From the Storefront API docs:

To authenticate with the Storefront API as either a private or public app, you need to obtain a storefront access token with the unauthenticated access scopes.

...

When building a private app, you can obtain a storefront access token by creating a private app.

...

To authenticate to the Storefront API as a public app you need to turn your app into a sales channel.

https://shopify.dev/docs/storefront-api/getting-started 

So if you were using a private app, you would not need to turn your app into a sales channel, however since you are making a Public App, you don't have a choice, it must be a sales channel.

Unauthenticated scopes doesnt mean that the app is unauthenticated, it means the client is unauthenticated, that is to say, they are not known to the shop. But your app needs to be authorized to interact with the shop on the behalf of the authorized user. 

If you want the sales processed to be part of the online shop, maybe it would be better to build with Liquid and the Shopify Admin API instead? If it is going to be within the Online Store? That sounds more like what you are describing wiht the other apps.

Was this helpful? Press like!
Did it fix the problem? Mark it as the solution for others!
Buy me a beer? Well, sure!
CoreyW
Tourist
6 0 5

@BStubbs this makes much more sense; thank you for explaining it.

What I am trying to achieve is to load a cart and take them to the last page so all the customer needs to do is click "purchase". Basically like a post-purchase upsell.

I am familiar with the URL to load a cart:

/cart/variant_id:qty?customer[]

but haven't found out how to preset the shipping method (free) and take them to the last step. Is this possible to do?

Reading up on it, I was under the impression you needed a storefront API to generate that type of order link. 

This is the app I was testing out that was able to achieve what I am looking for: https://apps.shopify.com/aftersell

I'll do some more digging and see if I can reverse engineer what they are doing. This is a "public app" which I really only intend to use on my own website(s), but a part of me wants it to just "install and work" should I want to use it on other sites in the future.

If you have any recommendations on that, it would be a huge help! 🙂 

BStubbs
Shopify Partner
136 16 62

Hey @CoreyW 

That was the next thing I was going to suggest to you. I've used that method of adding things to a cart before. Its handy, but don't forget it creates a new cart instance, so anything else that is in an unsold cart at that point will be removed.

That being said, if this is a post-purchase thing, then it probably won't be an issue.

For a pretty quick answer, you could just turn off shipping for the product? That would send the customer back to the checkout and they dont enter any shipping information. You'd have to get the shipping address from the previously completed order, but that won't be too difficult.

BStubbs_0-1599800358519.png

 

Was this helpful? Press like!
Did it fix the problem? Mark it as the solution for others!
Buy me a beer? Well, sure!
CoreyW
Tourist
6 0 5

@BStubbs This makes sense; would shutting off the physical shipping have any effect on normal checkouts?

I am still curious about how the aftersell app does it. They still use the existing data AFAIK as I did not have to change any product settings unless they are (potentially) creating products on the fly or some other wizardry (my Shopify development experience is somewhat limited). I am fully hooked into the Admin API with full permissions, but it seems like I'll have to do some more digging obviously and see what I come up with.

I wasn't really happy with how you had to manually pick the offers that would be shown after checkout and am trying to build something using cookies to track user data and figure out which products interest a customer the most but that they didn't end purchasing. My goal was to serve those specific products after the checkout with a discount applied to them.

I'll do some more digging and report back if I find any solutions -- I have found a bunch of similar threads that didn't come up with any answers, so maybe this will help others along the way too!

Of course, if you have any other ideas to try out let me know too! 🙂

Thanks for your help!

BStubbs
Shopify Partner
136 16 62

Hey @CoreyW 

Marking a product as non-physical would only impact on that product, nothing else in the shop.

Understanding what you are trying to do here helps, and I can make a few suggestions.

First, the Storefront API probably isn't the right place for you. For the issues we've already discussed, but also I think you've missed the use for Storefront. Its not about how your Online Store looks, its about replicating that experience somewhere else. Think about a McDonalds, the Online Shop might be the counter inside the shop, and you could use Storefront API to build a drivethru. Sorry if that is super lame explaination, but the point is they are both backending to the same core structure, none of the product offerings are different, just the way the customer interacts with it.

Second, for the product marked as non-physical, it would only impact that Product instance. You could have two of the same products in the shop, one with shipping enabled and the other without. The one without shipping enabled would be held in a seperate collection so it wouldnt normally show up. This isnt ideal, because you would need to have each shop configure their collections in different ways. This sometimes isnt as easy as it sounds.

Finally, I think you are probably in the right area with the Admin API. It might not be that complicated, but you will need access to the product at least, and be able to create an order. The other thing I think you need to look at is Liquid and Javascript. Liquid and a bit of Javascript is a pretty powerful tool, you'd just want to see that a popup appears after a checkout completes, and that it takes the customer data with it, then sends the customer to a new checkout with all the shipping data etc already completed. They would have to do the payment again, because that can't be stored, but no biggy.

Interesting idea!

Was this helpful? Press like!
Did it fix the problem? Mark it as the solution for others!
Buy me a beer? Well, sure!
CoreyW
Tourist
6 0 5

@BStubbs @DGP 

I had a few minutes tonight to do some more digging & have figured out how the other applications achieve this.

Essentially what they do is leverage the draft orders to pre-populate the fields and create a checkout link -- as there is no final transaction, this works within the Admin API.

Using graphql, you can add the shipping address & rate, customer email, line items & discount.

After generating the draft link, you can receive the checkout URL -- if all information was entered correctly, it takes you to the last checkout page with all information ready to go!

Here is the link to the graphql page: 

https://shopify.dev/docs/admin-api/graphql/reference/mutation/draftordercreate

Thanks for helping me in the right direction 🙏🏻

BStubbs
Shopify Partner
136 16 62

Nice work!

Was this helpful? Press like!
Did it fix the problem? Mark it as the solution for others!
Buy me a beer? Well, sure!
CoreyW
Tourist
6 0 5

Just checking if you have any other recommendations or info!

shashank-a
Shopify Partner
5 0 1

FYI. This is no longer the case https://shopify.dev/changelog/storefront-api-is-now-available-to-non-channel-apps.

 

This means that public apps can also use the Storefront APIs.

 

Apps no longer need to be a channel in order to access the Storefront APIs.