Customer information in external app

jtane
Shopify Partner
9 0 1

I am working on a project where I plan to use Shopify only for Products / Orders / Customers / Checkout management - my client already has a wonderful site that simply needs some shop augmentation. I've hacked up a prototype that is working pretty well - here is how it works so far:

* I use the Shopify API on my server to pull in products added via the Shopify admin.
* I use an iframe on my external site to add products to the user's cart (POST /cart/add) which works a charm.
* I update the user's cart infos client side by ajaxing the Shopify jsonp endpoint GET /cart.json which also works nicely.

The only thing I'm missing that I'd really like to add is some meta information about the current Shopify customer. Basically I'd like to know - do they have an account at my store? If so, are they logged in? And if they are logged in, maybe some non-invasive meta info about them - for example: `customer.first_name`.

Does anyone know if this is possible? I have investigated using the API server side, client side, and even an application proxy, but I can't seem to find a way to make this happen.

Any help much appreciated, thanks!

Replies 14 (14)
Adam_Harrison2
Explorer
127 0 22

Well, if you want to know this stuff, you can do it pretty easily. Do the following. On the shopify side of things, create an easily parsable page, with the following as its contents: {{ customer | json }}.

 

If you can find customer json data, you know the customer is logged in. The data contains first name, last name, etc.. This should solve your problem.

jtane
Shopify Partner
9 0 1

How can I get the contents of this 'easily parsable' page cross domain? Can you explain in more detail?

Adam_Harrison2
Explorer
127 0 22

Hi jtane,

 

Ah right, it's cross domain. Sorry, for some reason that slipped my mind. You may however be able to get around this by using an app proxy; I believe it's possible to set the Access-Control-Allow-Origin header, in your response, and have Shopify forward that to the client, but I'm not 100% positive. This would let you make cross-domain requests on modern browsers.

 

Adam

jtane
Shopify Partner
9 0 1

Oh, I see - that's an interesting idea, will give it a shot and post back - thanks!

jtane
Shopify Partner
9 0 1

Gah, so annoying! Shopify will forward headers for you ONLY if you don't set content-type to liquid...

Adam_Harrison2
Explorer
127 0 22

Ah. Typical. Hmm. I don't really see any other way you can do it. If you can find some way to get their email, you could bounce information requests to your server, which could simply do an API lookup...

 

Also, good to know about the liquid thing; I'll write that into my model. Hmm. This is an interesting problem... I'll let you know if I think of anything.

jtane
Shopify Partner
9 0 1

Right - looking up the user server side seems like a reasonable (if less than scalable) solution, however the only clue I'm able to get my hands on is the 'token' property that comes back with the response from GET /cart.json.

If there were some way to get at customers' carts server side I could figure it out that way, but there doesn't appear to be any way of accessing un-checked-out carts (server side).

Ideally, the customer id would just come back with GET /cart.json, that way I could safely look them up server side without sacrificing any security.

Adam_Harrison2
Explorer
127 0 22

Hmm, Jtane; what about having a javascript snippet in your iframe that pings your server with the customer information + cart token? That way, your server would be able to spit the data back out. If you're looking to keep things secure, you could even implement some sort of oauth scheme/use https with a shared secret in a customer metafield.

jtane
Shopify Partner
9 0 1

I thought of that, however things start to get more complicated than I'd like - now my otherwise simple external site needs to support HTTPS, CORS, and have its own sessions so I can pair that customer id back up with the right client, right?

Adam_Harrison2
Explorer
127 0 22

Well, not CORS 'cause you can ping your server through the app proxy itself, which, to the client, looks like the same domain. If you use OAuth, you don't need HTTPS. But sessions, yeah; you'd have to support that, unfortunately. Sucks, but I don't really see any alternative for something like that... although...

I uh, suppose one way to show meta information, is you could actually just use an iframe to display the user information each and every time, and simply style the inner contents to look identical to your external site. It'd be a bit weird, but it would circumvent these problems.

jtane
Shopify Partner
9 0 1

Oh, right good point about the proxy - I suppose adding access-control-allow-origin isn't too hard either 🙂 As far as security goes, if all I'm passing around is the customer id, I don't think there's anything inherently insecure about that - so that really just leaves the problem of matching up the data with the right client.

It's true that just doing the customer display in the iframe is probably the easiest... bummer tho cos custom fonts, integrated layout etc. etc.

Thanks a ton for all your help, really nice to have someone to bounce these questions off! Cheers.

Adam_Harrison2
Explorer
127 0 22

No problem! It's an interesting problem to think about, and I've been in a lot of similar situations, so I sympathize :). Good luck with the integration!

 

Adam

Adam_Harrison2
Explorer
127 0 22

Ah, jtane. I just remembered; you can add in cart attributes to a person's cart via POST requests using the cart api. These attributes are just strings, so you can encode arbitrary information in them; including customer data. So if you can retrieve the customer's cart via ajax, this would be the solution you're looking for. Sorry I didn't think of it earlier :\.

jtane
Shopify Partner
9 0 1

Brilliant! Definitely a ridiculous number of hoops to jump through, but that does in fact do the trick - thanks again Adam.

In case others have this problem, the (admittedly super hack) solution I ended up with works like this: 

SHOPIFY SITE
* create a custom page: '/pages/stash_customer_meta' for example
* on this page make some (synchronous - this is important!) xhr's to first get your hands on a valid variant id
* then to add one unit along with whatever meta info you need tucked into cart.attributes (my POST to /cart/add.js body looked like this, note the liquid code: { "id": 123456, "attributes[customer_id]": {{ customer.id }} }
* immediately after you get a response, use POST /cart/change.js to remove quantity: 1 of that same variant from the cart so as not to leave unwanted items lying around

EXTERNAL SITE
* add an iframe to your page with src="/pages/stash_customer_meta"
* listen for the iframe's load event with javascript (this is why your xhr's on the Shopify page have to be sync)
* when the event fires, hit the JSONP endpoint GET /cart.js and find your infos inside the attributes object

Although this works, it's pretty fragile and basically sucks a lot. If any Shopify API gods are watching these forums, _please_ implement the features below:

* CORS support for the ajax API. JSONP is an insecure hack that doesn't support POST
* add an ajax API endpoint: GET /customer.json

If these existed, all of this craziness would be unnecessary, and significantly increase Shopify's ability to integrate with external sites.