Shopify Installation Guide

Shopify Installation Guide

In this guide, you can read and learn about how to set up Hello Retail with Shopify with API credentials, tracking & conversion scripts, and lastly a blank page for search.


Creating API credentials for Hello Retail:

The API credentials are used by Hello Retail to synchronise your shops products and categories with our own database, to always show updated content in our services. It is also used to get information about your orders, which is used for product relations and services such as our triggered emails.

You have to create a private application for Hello Retail. If needed, you can also read Shopify's own documentation on custom apps here.

Follow the steps below on how to do it:

  1. Log in to your Shopify account.
  2. On the dashboard view, navigate to the left-hand side menu.  Click on Apps -> App and sales channel settings

     
  3. Inside this window, click on the Develop apps button.


     
  4. Click on the Allow custom app development button.


     
  5. Read and accept the warning by clicking on the Allow custom app development button.


     
  6. After accepting this, it will prompt a pop-up to verify this change and the App development overview will look like this as seen below.
  7. Next, click on the Create an app button.

  8. Inside the Create an app view, input an App name associated with Hello Retail. Then choose the App developer appropriate from your company.
    Note It is only possible to assign staff and collaborators with permission to develop apps.
  9. When you have entered the details, then click on the Create button.


     
  10. Next, the overview of the created app will look like this. Click on the Configure Admin API scopes button


     
  11. Inside the search bar for Filter access scopes, search individually for:

    Customers - read_customers
    Orders  - read_orders
    Product listings - read_product_listings
    Products - read_products
    Store content - read_content
    Translations - read_translations


  12. With all these scopes, enable the read ability for all of them.


     
  13. In the Configuration tab, you have the option to see an overview of the access scopes listed with reading access.


     
  14. After the completion, click on the green Install app button to prompt the Admin API access token. Copy this generated token.

  15. Now that the following steps have been completed, please send the API Key and the API Access Token to support@helloretail.com with the following details:

    - API Key
    - Admin API Access Token 
    - Your Shopify store name (xxx.myshopify.com)

     
  16. To find the API, go to the API credentials tab and copy & paste the information.


Inserting the Helloretail.js script

In this section, we will guide you on how to insert the Hello Retail script on you pages.
log into the Admin panel of your Shopify webshop: shopify.com/login.

Note: if you are updating an existing installation, make sure you remove the old parts first:
remove-old-shopify-scripts

  1. On the dashboard view, navigate to the left-hand side menu.  Click on Online Store.


     
  2. From the drop-down menu, click on Themes.


     
  3. Navigate over to the right-hand side to Debut and click on the drop-down button of Actions.


     
  4. From the drop-down menu, click on Edit code.


     
  5. On the left-hand side, a second menu bar will prompt. In this menu, go down to the folder named Layout and click on the file named theme.liquid. Next, an editor window will appear.


     
  6. Inside the editor window scroll down towards the bottom until you locate the end of the </body> tag.
    Copy the following code snippet, and paste it on new line just above the end tag.
<script async src="https://helloretailcdn.com/helloretail.js"></script>
    <script>
    let helloRetailInitParams = {};
    if (Shopify.country) {
        switch (Shopify.country) {
            case "US":
                helloRetailInitParams.websiteUuid = "YOUR_US_WEBSITE_UUID";
                break;
            case "DK":
                helloRetailInitParams.websiteUuid = "YOUR_DK_WEBSITE_UUID";
                break;
        }
        // ignore if the snippet was inserted without updating the websiteUuid.
        if (helloRetailInitParams.websiteUuid && helloRetailInitParams.websiteUuid.startsWith("YOUR_")) {
            delete helloRetailInitParams.websiteUuid;
        }
    }
    window.hrq = window.hrq || [];
    hrq.push(["init", helloRetailInitParams]);
    [hr_preMoney, hr_postMoney] = "{{ 1 | money_with_currency }}".split(/[0-9,.']+/);
    if (Shopify.currency && Shopify.currency.active && Shopify.currency.rate) {
      let date = new Date();
      date.setTime(date.getTime() + (60 * 24 * 365 * 60 * 1000));
      let domain = window.location.host;
      if (domain.indexOf("www.") === 0) {
          domain = domain.substring(4);
      }
      document.cookie = "hello_retail_currency" + "=" + encodeURIComponent(JSON.stringify(Shopify.currency))
        + "; expires=" + date.toGMTString()
        + ";domain=." + domain
        + ";path=/;samesite=lax";
    }
  </script>

Note: The section for setting websiteUuid (if (Shopify.country) {...)  can be removed if you only have one website setup with Hello Retail.
It is also possible to use Shopify.locale instead of Shopify.country if that matches your Hello Retail setup better.

Lastly, scroll up and navigate to the top of the screen and click the Save button.

 


Inserting the Hello Retail tracking pixel:

In this section, we will guide you on how to make your carts and conversions available for Hello Retail. The data is essential in optimising our algorithms, tuning the content and for features like our triggered emails.

Note: if you are updating an existing installation, make sure you remove the old parts first:
remove-old-shopify-scripts

  1. When logged in as Admin: Navigate to the left-hand menu and click on Settings at the bottom of the screen - a popup window with settings will appear.
    Click on the menu for Customer events and then on the button Add custom pixel in the top right corner. 

    A popup will appear and ask for a name, just call it something meaningful like "Hello Retail Pixel" and click the Add Pixel button.
     
  2. Now copy the code snippet from below and insert it into the code field of your new custom pixel. When you have inserted it, you first press the Save button and finally you press the Connect button:

    function trackCart(helloRetailId, helloRetailWebsiteUuid, helloRetailCurrency, event, init) {
        let cartLinesMap = {};
        let cartPayload = {
            'trackingUserId': helloRetailId,
            'websiteUuid': helloRetailWebsiteUuid,
            'total': 0,
            'url': event.context.document.location.origin + '/cart/',
            'productNumbers': [],
        };
        // init.data.cart represents a snapshot of the cart when the event was triggered.
        // So the init.data.cart will be one step behind the new state triggering the event.
        // this means the init.data.cart will be empty on the first "product_added_to_cart" event.
        const existingCart = init.data.cart;
        let currencyCode = null;
        if (existingCart) {
            cartPayload.total = existingCart.cost.totalAmount.amount;
            currencyCode = existingCart.cost.totalAmount.currencyCode;
            existingCart.lines.forEach((existingLine) => {
                // merchandise.id is variant id
                // merchandise.product.id is main id
                cartLinesMap[existingLine.merchandise.id] = existingLine;
            });
        }
        const cartLineUpdate = event.data.cartLine;
        if (cartLineUpdate) {
            currencyCode = cartLineUpdate.cost.totalAmount.currencyCode;
            const lineQtyUpdate = cartLineUpdate.quantity;
            const lineIdUpdate = cartLineUpdate.merchandise.id;
            const isRemoveFromCart = event.name == "product_removed_from_cart" ? true : false;
            if (isRemoveFromCart) {
                if (lineIdUpdate in cartLinesMap) {
                    cartLinesMap[lineIdUpdate].quantity -= lineQtyUpdate;
                    if (cartLinesMap[lineIdUpdate].quantity <= 0) {
                        delete cartLinesMap[lineIdUpdate];
                    }
                }
                cartPayload.total -= cartLineUpdate.cost.totalAmount.amount
            } else {
                if (lineIdUpdate in cartLinesMap) {
                    cartLinesMap[lineIdUpdate].quantity += lineQtyUpdate;
                } else {
                    cartLinesMap[lineIdUpdate] = cartLineUpdate;
                }
                cartPayload.total += cartLineUpdate.cost.totalAmount.amount
            }
        }
        Object.values(cartLinesMap).forEach((currentCartLine) => {
            // merchandise.id is variant id
            // merchandise.product.id is main id
            cartPayload.productNumbers.push(currentCartLine.merchandise.product.id)
            cartPayload.url += (currentCartLine.merchandise.id + ":" + currentCartLine.quantity + ",");
        });
        if (helloRetailCurrency && helloRetailCurrency.code == currencyCode) {
            cartPayload.total = Number(cartPayload.total / helloRetailCurrency.rate).toFixed(2);
        } else if (event.name == "checkout_started") {
            // Our currency doesnt match the current currency presented.
            // Most likely this is due to shopify auto changing the currency based on shipping address.
            // We have likely tracked a cart already at this point, so we can just ignore this event.
            // There is also the chance the customer will go back to the shop,
            // in which case our currency will be updated and we will be able to track correctly next event.
            return;
        }
    
        fetch('https://core.helloretail.com/serve/collect/cart', {
            method: 'POST',
            body: JSON.stringify(cartPayload),
            keepalive: true,
        });
    }
    function trackConversion(helloRetailId, helloRetailWebsiteUuid, helloRetailCurrency, event) {
        const checkoutData = event.data.checkout;
        if (checkoutData) {
            let totalInBaseCurrency = null;
            if (helloRetailCurrency && helloRetailCurrency.code == checkoutData.subtotalPrice.currencyCode) {
                // only set total when we are able to convert to base currency.
                totalInBaseCurrency = Number(checkoutData.subtotalPrice.amount / helloRetailCurrency.rate).toFixed(2);
            }
            let productNumbers = [];
            checkoutData.lineItems.forEach((lineItem) => {
                // lineItem.id is variant id
                // lineItem.variant.product.id is main id
                productNumbers.push(lineItem.variant.product.id)
            });
            const conversionPayload = {
                'trackingUserId': helloRetailId,
                'websiteUuid': helloRetailWebsiteUuid,
                'total': totalInBaseCurrency,
                'orderNumber': checkoutData.order.id,
                'email': checkoutData.email,
                'productNumbers': productNumbers
            }
            fetch('https://core.helloretail.com/serve/collect/conversion', {
                method: 'POST',
                body: JSON.stringify(conversionPayload),
                keepalive: true,
            });
        }
    }
    async function getWebsiteUuid(browser) {
        const helloRetailState = await browser.sessionStorage.getItem('hello_retail_state');
        let helloRetailWebsiteUuid = null;
        if (helloRetailState) {
            const helloRetailStateJSON = JSON.parse(helloRetailState);
            helloRetailWebsiteUuid = helloRetailStateJSON.website.uuid;
        }
        return helloRetailWebsiteUuid;
    }
    async function getHelloRetailId(browser) {
        return await browser.cookie.get('hello_retail_id');
    }
    async function getHelloRetailCurrency(browser) {
        const currency = await browser.cookie.get('hello_retail_currency');
        if (!currency) {
            return null;
        }
        const currencyObj = JSON.parse(decodeURIComponent(currency));
        return {"rate":currencyObj.rate, "code":currencyObj.active};
    }
    analytics.subscribe('product_added_to_cart', async (event) => {
        const helloRetailId = await getHelloRetailId(browser);
        const helloRetailWebsiteUuid = await getWebsiteUuid(browser);
        const helloRetailCurrency = await getHelloRetailCurrency(browser);
        if (helloRetailId && helloRetailWebsiteUuid) {
            trackCart(helloRetailId, helloRetailWebsiteUuid, helloRetailCurrency, event, init);
        }
    });
    analytics.subscribe('product_removed_from_cart', async (event) => {
        const helloRetailId = await getHelloRetailId(browser);
        const helloRetailWebsiteUuid = await getWebsiteUuid(browser);
        const helloRetailCurrency = await getHelloRetailCurrency(browser);
        if (helloRetailId && helloRetailWebsiteUuid) {
            trackCart(helloRetailId, helloRetailWebsiteUuid, helloRetailCurrency, event, init);
        }
    });
    analytics.subscribe('checkout_started', async (event) => {
        // This is used for cart tracking in the case of "direct to checkout".
        // also works as a failsafe in the case a user returns to the shop,
        // has an active cart and goes directly to checkout.
        const helloRetailId = await getHelloRetailId(browser);
        const helloRetailWebsiteUuid = await getWebsiteUuid(browser);
        const helloRetailCurrency = await getHelloRetailCurrency(browser);
        if (helloRetailId && helloRetailWebsiteUuid) {
            trackCart(helloRetailId, helloRetailWebsiteUuid, helloRetailCurrency, event, init);
        }
    });
    analytics.subscribe('checkout_completed', async (event) => {
        // Shopify customer events will only fire if the customer has opted in.
        const helloRetailId = await getHelloRetailId(browser);
        const helloRetailWebsiteUuid = await getWebsiteUuid(browser);
        const helloRetailCurrency = await getHelloRetailCurrency(browser);
        if (helloRetailId && helloRetailWebsiteUuid) {
            trackConversion(helloRetailId, helloRetailWebsiteUuid, helloRetailCurrency, event);
        }
    });

 


The following section is only relevant for setups for a full search.

Step 1: Navigate and click "Online store"

 

Step 2: Click sub-menu "Pages"

 

Step 3: Navigate to the top right corner and click the button "Add pages". A new page editor will appear.

 

Step 4: In the page editor, please write a meaningful title, e.g., "Search results" in Title. Make sure the option "Visible" is chosen under Visibility. Choose "page" under Template.

 

Step 5: Navigate to the bottom right corner and press button "Save"

 

Step 6: You have now created a blank page for Hello Retail to display search results. After you clicked the save button, please navigate to the top of the page and locate and "View Page." This will open a new tab in your browser.

 

Step 7: Find the URL near your browser tab, copy-paste it, and share it with Hello Retail so they can finish your full-page search.


Configure Webshop

After the installation setup of your platform and the onboarding flow, make sure to have your webshop configured. Read this guide here on how to do so:

Configure Webshop

Like Follow
  • 1 yr agoLast active
  • 1Replies
  • 5360Views
  • 2 Following