BigCommerce

Introduction

HubBox can be implemented on a BigCommerce site via the HubBox Tag script - this is a piece of JavaScript that is added to the checkout via BigCommerce's Script Manager functionality.

For more information on Tag and customization features, please refer to the Tag documentation.

Adding the Tag script to your BigCommerce site

To add the script in BigComemrce you will need to go to the Script Manager by clicking on ‘Storefront’ in the left-hand menu and then ‘Script Manager’. If you have multiple channels, you may first need to go to 'Channel Manager' and then 'Scripts'. Once in the Script Manager, follow the below steps:

  1. Click 'Create a Script'
  2. Give your Script a name, like “HubBox Tag”. Settings should be set as per the below table
  3. Paste the script provided by HubBox into the script box and save
Settings
Location on page Footer
Select pages where script will be added Checkout
Script category Essential
Script type Script

bigcommerce-add-script-1 bigcommerce-add-script-2 bigcommerce-add-script-3 bigcommerce-add-script-4

Testing & deploying

The HubBox Integrations team, they will provide you with your Tag script. You will need to add this to your checkout and test.

If you do not have a test site, you can add the script to your live site with the below added to the config of the Tag script.

mode: "test",

When mode is set to "test" you will need to add the below string to the end of the checkout URL in order to view the Tag. This stops live customers from seeing the integration whilst you are testing.

?hubboxPayloadTest=true

The URL will look like this, for example: https://hubbox-store.com/checkout?hubboxPayloadTest=true

Once testing is completed you can then set mode to "live" and customers will be able to see the pickup option.

Features

Hiding pickup option for ineligible baskets

Retailers with diverse product catalogs may be required to exclude certain products from the pickup service. In this instance, you will need to hide the pickup option for baskets that contain ineligible items. For example, if the customer has an item in their basket that is too large for a pickup location, you will need to ensure that they cannot see the pickup option at checkout. To implement this behavior we can use the bailoutOnCondition callback which will "bailout" the Tag script based on certain criteria.

Below are some BigCommerce examples of using the bailoutOnCondition callback to hide the pickup UI. Please note the callbacks sit within the config of the Tag script.

Hide pickup for out of stock items

callbacks: {
  bailoutOnCondition: () =>
    new Promise((resolve) => {
      const getCart = (url) =>
        fetch(url, { method: "GET" })
          .then((response) => response.json())
          .catch((error) => console.error(error));
      const fetchProductData = (productIds, variantIds) =>
        fetch("/graphql", {
          method: "POST",
          credentials: "same-origin",
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer {{ settings.storefront_api.token }}`
          },
          body: JSON.stringify({
            query: `
                    query ProductInventory {
                      site {
                        products (entityIds: ${JSON.stringify(productIds)}) {
                          edges {
                            node {
                              entityId
                              name
                              variants (entityIds: ${JSON.stringify(variantIds)}) {
                                edges {
                                  node {
                                    entityId
                                    sku
                                    inventory {
                                      aggregated {
                                        availableToSell
                                        warningLevel
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  `
          })
        })
          .then((res) => res.json())
          .catch((error) => console.error(error));
      getCart("/api/storefront/carts?include=lineItems.physicalItems.options")
        .then((data) => {
          const productMap = {};
          data.forEach((d) =>
            d.lineItems.physicalItems.forEach((item) => {
              const productId = item.productId;
              if (!Array.isArray(productMap[productId])) {
                productMap[productId] = [];
              }
              productMap[productId].push(item.variantId);
            })
          );
          return productMap;
        })
        .then((productMap) => {
          const keys = Object.keys(productMap).map((key) => Number(key));
          return fetchProductData(
            keys,
            keys.flatMap((key) => productMap[key])
          );
        })
        .then((data) =>
          data.data.site.products.edges.flatMap((productEdge) => productEdge.node.variants.edges.flatMap((variantEdge) => variantEdge.node.inventory))
        )
        .then((inventories) => inventories.every((i) => i.aggregated?.availableToSell > 0) === true)
        .then((areAllItemsInStock) => resolve(!areAllItemsInStock))
        .catch(() => resolve(false));
    });
}

Hide pickup for particular SKUs

callbacks: {
    bailoutOnCondition: () => new Promise(resolve => {
        fetch('/api/storefront/cart', {
            credentials: 'include'
        }).then((response) => {
            return response.json();
        }).then((cartArray) => {
            const nonAcceptableSkuList = ['ABC123','XYZ987',];
            const cartSkuList = cartArray.shift()?.lineItems?.physicalItems.map(item => item?.sku);
            const nonAcceptableSkuExists = cartSkuList.some(cartSku => nonAcceptableSkuList.includes(cartSku));
            resolve(nonAcceptableSkuExists);
        }).catch(() => resolve(false));
    }),
}

Hide pickup based on shipping group

callbacks: {
  bailoutOnCondition: () =>
    new Promise(async (resolve) => {
      const getCart = (url) =>
        fetch(url, { method: "GET" })
          .then((response) => response.json())
          .catch((error) => console.error(error));

      const cartData = await getCart("/api/storefront/carts?include=lineItems.physicalItems.options");
      // noinspection JSUnresolvedReference
      const productIds = cartData.flatMap((d) => d.lineItems.physicalItems.map((item) => item.productId));
      const apiEndpointUrl = "https://api.bigcommerce.hub-box.com/v1/tag/product/metafield";
      const storeHash = "hkpifbogfq";
      const results = await Promise.all(
        productIds.map((productId) =>
          fetch(`${apiEndpointUrl}?storeHash=${storeHash}&productId=${productId}`)
            .then((response) => response.json())
            .then((dataContainer) => dataContainer["data"])
        )
      );

      const doesMediumExist = results
        .flat(2)
        .filter((item) => item.key === "shipping-groups")
        .map((item) => JSON.parse(item.value))
        .some((shippingGroups) => shippingGroups.some((shippingGroup) => shippingGroup.toLowerCase() === "large"));
      resolve(doesMediumExist);
    });
}

Shipping rate filtering

If you use multiple carriers or wish to offer pickup at a different price or service level, you will need to show and hide particular shipping rates depending on whether the customer has chosen home delivery or pickup.

In order to manage and filter the rates that are displayed to a customer when pickup is selected, you can use the shippingRates configuration and using xpath set the rates you wish to show/hide. The HubBox Integrations team can help you configure this for your site.

Below is an example of the shippingRates configuration hiding the "Standard Home Delivery rate" if a pickup location is chosen and hiding the "Stanard Pickup" rate if home delivery is being used by the customer. The shippingRates configuration sits within the selectors which sits inside the config.

shippingRates: {
  wrapper: "#checkout-shipping-options",
    hiddenShippingRates: {
    network: [
      "xpath://*[contains(@class, 'form-checklist-header')][div/label/div/div/span[contains(text(),'Standard Delivery')]]",
    ],
  },
  hiddenPickupRates: {
    network: [
      "xpath://*[contains(@class, 'form-checklist-header')][div/label/div/div/span[contains(text(),'Pickup Delivery')]]",
    ],
  },
}
shippingMethods: {
    excludeOnLocalPickup: [{
        networks: ["ups", "dpd"],
        selectors: [
            "xpath://*[contains(@class, 'form-checklist-header')][div/label/div/div/span[contains(text(),'Standard Delivery')]]"
        ],
        "mode": "first"
    }, {
        selectors: [
            "xpath://any"
        ],
        "mode": "all"
    }],
    excludeOnHomeDelivery: [{
        selectors: [
            "xpath://*[contains(@class, 'form-checklist-header')][div/label/div/div/span[contains(text(),'Pickup Delivery')]]",
            ".two",
            ".three"
        ]
    }]
}

Other features

HubBox can also offer additional features upon request:

These features require HubBox customization so please contact the HubBox Integrations team if you would like to find out more at clientsupport@hub-box.com.

The end result

Once the Tag has been setup and the script has been added to your checkout, your customers will see the pickup option presented in the checkout. If the customer clicks the pickup option, they will be able to search for, view and select an available pickup location.

Once the customer has selected a location, they will complete checkout as normal. The shipping address will be the customer's chosen pickup location address.

bigcommerce-example-checkout

If you have any issues during set up, please contact clientsupport@hub-box.com.