Preventing Checkout Until Giftship Bundles are Loaded

In Giftship, bundled products can be set to add to the cart when a user navigates to the cart page. Unfortunately, if a user clicks the checkout button before Giftship’s bundle function fires, this could result in an empty bundle being added to their cart.

To prevent this from happening, we’ve devised a solution that ensures the checkout button remains disabled until Giftship bundles have fully loaded.

Please note: This is an advanced tutorial, and should be completed by a qualified web developer familiar with HTML and Liquid. If you are not working with a developer, and would like us to handle this for you, we can do so for a flat fee of $200 USD. Payment can be made by navigating to the following url: https://shop.gist-apps.com
Considerations:

Please note that the following code should only be implemented if your store frequently encounters orders missing unbundled products. This solution is experimental and requires customization to fit your theme and environment. Always publish and test code on a development theme before deploying it to your live site.

1. Duplicate Your Live Theme and Edit the Development Theme

2. Disable the Checkout Button in Your Theme

To disable the checkout button, add the “disabled” attribute to your theme’s checkout button:

<button type="submit" id="checkout" name="checkout" form="cart" disabled>

3. Add the Following Script

Add the following script to the bottom of theme.liquid or your theme’s existing assets.
This solution is experimental and requires customization to fit your theme and environment.

{% if template.name == 'cart' %}

<script>

    (function() {

      var GSCART = {

        init: function() {

          this.events();
          
        },
        
        state: {
          bundlesLoaded: false
        },

        events: function() {

          document.addEventListener('giftship.loaded', GSCART.beginBundleCheck);
          document.addEventListener('giftship.bundle-updated', GSCART.handleBundleUpdated);                          
        },

        handleBundleUpdated: function() {

          GSCART.state.bundlesLoaded = true;
          
        },

        awaitBundleLoaded: function(attempts = 0) {

          if (GSCART.state.bundlesLoaded === true) {
            GSCART.enableCheckout();
            return;
          }

          if (attempts < 20) {
             console.log("Bundles not updated yet", attempts);
             setTimeout(function() {
               attempts = attempts + 1;
               GSCART.awaitBundleLoaded(attempts);
             }, 500);
          } else {
             console.warn("Bundle cart exists, but bundles never loaded");
          }
          
        },

        hasBundleItem: function(cart) {

          var hasBundleItem = false;

          cart.items.forEach(function(item) {

            var propertyKeys = Object.keys(item.properties);

            propertyKeys.forEach(function(key) {

              if (key.includes("_gs_bundle")) {
                hasBundleItem = true;
              }
              
            });
            
          });

          return hasBundleItem;
          
        },
        
        beginBundleCheck: function() {

          fetch('/cart.js')
          .then(function(res) {
            return res.json();
          })
          .then(function(cart) {
            console.log(cart);
            var hasBundleItem = GSCART.hasBundleItem(cart);

            console.log('Cart has bundle', hasBundleItem);
            
            if (hasBundleItem === true) {
              GSCART.awaitBundleLoaded();
            } else {
              GSCART.enableCheckout();
            }
            
          })
          .catch(function(err) {
            console.log(err);
          })
          ;
          
        },

        enableCheckout: function() {
          
          var currentPage = window.GSSDK.page.get();
          var checkoutBtn = document.getElementById('checkout');

          if (!checkoutBtn) {
            return;
          }

          checkoutBtn.removeAttribute('disabled');

          console.log('Checkout button is now enabled');
          
        }
        
      };

      GSCART.init();
        
      
    })();
    
</script>

{% endif %}

Now, With This Implementation, It’s Important to Test:

  1. Ensure that the checkout button becomes enabled once the page loads.
  2. Check if refreshing the page and quickly clicking checkout prevents the checkout process.
  3. Verify that clicking checkout properly bundles products.
  4. Ensure there are no console errors present before or after clicking checkout.

Can't find the answer in our documentation?
Contact Support