Shopify / js-buy-sdk

The JS Buy SDK is a lightweight library that allows you to build ecommerce into any website. It is based on Shopify's API and provides the ability to retrieve products and collections from your shop, add products to a cart, and checkout.
https://shopify.github.io/js-buy-sdk
MIT License
989 stars 261 forks source link

Cart is not cleared on completion of a checkout #98

Closed richgilbank closed 7 years ago

richgilbank commented 8 years ago

Currently, the cart doesn't clear itself when the user checks out, as it does with the Buy Button. This could be solved by using a server-backed cart.

peteshilling commented 8 years ago

Solving this would be huge. The only solution I've come up with is to redirect users to a thank you page after checkout that clears the cart from local storage.

lepsalex commented 8 years ago

+1 ... I'm going to do the same redirect trick but it's not ideal.

minasmart commented 8 years ago

We have a way to manage this, but still not sure on the best approach to implement in the API.

I should have news in the next couple weeks.

minasmart commented 8 years ago

@peterbrunton @lepsalex We've built an example detailing the best way to watch the checkout. The most pertinent part is here: https://github.com/Shopify/js-buy-sdk/pull/142/files#diff-ce801cc7cadd385c53c5ab7f3b477719R48

peterbrunton commented 8 years ago

Tagged the wrong Peter @minasmart

minasmart commented 8 years ago

Sorry. @peterbrunton. @peteshilling see above!

peteshilling commented 8 years ago

Thanks! This looks like a good option, although keeping users in the same window during checkout would be ideal.

minasmart commented 8 years ago

@peteshilling that's why I didn't build it into the SDK. We have a cart and checkout API coming soon, and I didn't want to build out a new behaviour which will soon be deprecated. This is temporary compromise.

peteshilling commented 8 years ago

Great, thanks! I'll use this method for now.

On Thu, Jun 16, 2016 at 8:25 AM, Mina Smart notifications@github.com wrote:

@peteshilling https://github.com/peteshilling that's why I didn't build it into the SDK. We have a cart and checkout API coming soon, and I didn't want to build out a new behaviour which will soon be deprecated. This is temporary compromise.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Shopify/js-buy-sdk/issues/98#issuecomment-226520268, or mute the thread https://github.com/notifications/unsubscribe/AC4x4MLeXU9LMLSSHYYxUO6K7B3inhZFks5qMWr8gaJpZM4IRUyb .

lepsalex commented 8 years ago

Thanks! This is a great option to have. I think we will stick with our redirect countdown and thank you page reset since for this particular application of the API we're required to stay within the same window.

Good to hear about the upcoming API, I looked at all your current webhooks to see if anything could send back something we could use but nothing was 100%.

drewbaker commented 8 years ago

We tried putting the checkout link into an iFrame, so that we could get postMessages out of it to know when someone has checked out successfully. But it appears you have some sort of CSP protections against the checkout in an iFrame.

Seems like it should be easy for you guys to add a hasCheckedOut: true parameter to the CartModel right? Then we could just test the model on a setInterval() at the very least.

yomexzo commented 8 years ago

+1 for building it into the SDK. Probably even have an event you can subscribe to.

Anyways, can you confirm you checked this out? If it still doesn't work, can you give some context into your environment/setup i.e browser etc?

peteshilling commented 8 years ago

If anyone's interested, I ended up simply redirecting the user to a custom thank you page that clears the cart from local storage. Works well enough. To set it up just add a simple redirect to the 'Additional Scripts' box on the Settings > Checkout page.

<script>
window.location = <custom thank you page>
</script>

Then on the thank you page:

localStorage.removeItem('shopifyCart');

drewbaker commented 8 years ago

@peteshilling thanks for this. But then how does the customer get to see the order completed page? I guess your thank you page is just replicating the Shopify page right?

peteshilling commented 8 years ago

@drewbaker we couldn't think a way to securely show the order details on the custom thank you page (how do you verify the user is the one who purchased?), so we simply show a generic message for all users. Not ideal (the biggest trade-off of this solution), but we found it acceptable since they get emailed an order summary after checkout.

minasmart commented 8 years ago

We don't actually have an API to support something like hasCheckoutOut: true. Right now the cart is stored in local storage, and we have no way of indicating what checkout object it's tied to, or if the checkout has been completed. We are currently developing an API to support this, but it'll be a bit of time before we're able to switch over. Sorry for not being of more help.

paulgrieselhuber commented 7 years ago

@minasmart has there been any update on the hasCheckedOut parameter? Would be great to have this in place going in to holiday sales.

minasmart commented 7 years ago

This feature relies on a checkout API that isn't yet built. It's in progress, and we'll be trying it out on some internal apps soon. Release, however, won't be until the new year. Sorry about that!

paulgrieselhuber commented 7 years ago

Too bad. Can tell you this is a huge pain point for external integrations. We get a hefty handful of complaints about this per week.

If you know yet, does new year mean end of January or end of August?

minasmart commented 7 years ago

We're aiming for around april. There may be a beta of js buy available a couple months before that though.

I definitely feel your pain and understand that you're getting a lot of complaints, and I wish I had a better answer. Unfortunately, anything to do with taking payments and managing totals for customers can't be undertaken lightly with the number of merchants in our system.

Please know, however, that you've been heard, and what we're working on is going to be pretty good when it finally gets released 😄 .

paulgrieselhuber commented 7 years ago

Cool, would love to join the beta. Glad to hear your team is working so hard on it.

strikerforce commented 7 years ago

I've come up with a slightly different approach to clearing the cart after a purchase based on @peteshilling approach.

Instead of adding

<script> window.location = <custom thank you page> </script>

to the Additional scripts section of the Settings > Checkout page, I added

<iframe style="display:none;" src="https://yourdomain.com/clearCart.html"></iframe>

Note: clearCart.html should contain a simple script to load the users cart and clear it from localStorage.

This approach gives the added benefit of keeping the user on the same window and original checkout page while clearing the carts content.

Obviously, this approach will only work if the iframe is able to load completely before the user closes the page.

alfsaav commented 7 years ago

@strikerforce Thank for the idea. I will test it soon. That's a very ingenious solution.

alfsaav commented 7 years ago

@strikerforce Finally I managed to test your solution, but it seems that shopify doesn't allow iframes to be loaded dynamically. This is the error I get:

Refused to display 'https://xxxxxxxxx.com/store/clear/' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.

Did you run into this issue as well?

Thanks,

minasmart commented 7 years ago

X-frame-origin is set by the server providing the iframe. That's not a Shopify thing. Hope that helps :)

strikerforce commented 7 years ago

@alfsaav Awesome to see you trying this approach out. Try changing X-Frame-Options from SAMEORIGIN to ALLOWALL (bad for security, not recommended, quick fix to see if works) or ALLOW-FROM https://checkout.shopify.com/ (not well supported, have fallback) on your web server.

For configuring X-Frame-Options, here is a good reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options#Examples

If you choose ALLOW-FROM (or ALLOWALL for that matter), then for your fallback (really should be main security overall), you may want to look at frame-ancestors within CSP(Content Security Policy).

Here is a good reference for CSP: https://content-security-policy.com/

However, if all of the above is not possible, JSONP is your friend.

agos commented 7 years ago

I have tried the example, but I saw no messages being posted by the iframe. This is easily solvable by adding a custom script to the order page, but shouldn't it be at least documented? Is there something I'm missing?

paulgrieselhuber commented 7 years ago

@minasmart, is @strikerforce's idea being taken as the solution here, or is a fix still in the works for ~April from Shopify?

JonMcL commented 7 years ago

I came up with an iframe solution as well, but it appears that the Shopify Thank You page has a security policy to limit child src's to the same domain. So I don't think an iframe can be put into the page (assuming browser complies). My only solution so far is a redirect by to the main site to clear the cart or to have the cart automatically expire after a period of time.

agos commented 7 years ago

@JonMcL if you are referring to the X-Frame-Options header, that says nothing about included iframe, only that the page itself cannot be in an iframe. An iframe can be indeed put into the order complete page, provided that the X-Frame-Options value of the URL you are trying to load allows it

JonMcL commented 7 years ago

@agos There is actually a child-src CSP directive in the page. When I tried adding an iframe to the page (to empty the cart from my own domain), Chrome reported: Refused to frame 'http://example.com/' because it violates the following Content Security Policy directive: "child-src 'self' https://* blob: data:".

However, I gave up too quickly and I am just now noticing that an iframe with an https src should actually work. I was doing tests with a non-secure iframe. I solved my cart issue with a redirect to my site, and then a redirect back to the checkout page (with a query parameter added to avoid repeats). I might try an iframe again once I have the site up and running on a secure domain.

paulgrieselhuber commented 7 years ago

@minasmart back in November you mentioned April-ish might be a possibility on a fix here. We are still getting lots up upset and confused customers here. Any fix, even a beta in sight?

minasmart commented 7 years ago

This is resolved in the v1.0alpha.

The readme and branch are available here, and the node module can be installed with npm install shopify-buy@alpha.

The alpha part of this build isn't so much build quality, as it is interface stability. The API that drives this is stable, so the alpha should continue to work for quite some time. Full release of this build will happen once we've done more vetting that we've built the interface correctly, and not missed anything, but I'd definitely recommend hopping on board.

There's also a migration guide available to help you migrate your existing work.

This new version of the SDK is built on our Storefront API which can also be accessed directly without an SDK if that's your preference.

paulgrieselhuber commented 7 years ago

Excellent, will test this out next week. Thanks for the work on this!

paulgrieselhuber commented 7 years ago

Hi Mina,

I've done some digging here, but I can't find a flavor of the v1.0alpha that can be deployed standalone as a client side integration. All of the flavors I see are meant to be baked into a Node, React, etc. implementation.

For instance, how we use the JS Buy SDK currently is:

The end result is that we can a nearly full-featured Shopify experience on our large Wordpress website.

Could you please point me to the correct v1.0alpha version of the resource which contains the library needed to leverage the new methods you linked to in the migration docs?

paulgrieselhuber commented 7 years ago

Ah ha, I didn't grock that you've moved away from delivering a version of the SDK that allow standalone Githubissues.

  • Githubissues is a development platform for aggregating issues.