skip to Main Content

I am trying to add a shopify function to our store and its functionality should be to give free shipping to customers that have at least one of these two tags: "swell_vip_learned lounger", "swell_vip_pj professional".

I have created a custom app and added an extension of type "shipping-discount". The app is installed successfully and discount is also showing applied. but when I open the checkout as a customer that has those tags, it donot apply free shipping. I am providing code for my run.graphql and run.js both as only these are two main files in extension. Kindly help me what could be wrong here ?

run.grpahql

query RunInput {

 cart {
  deliveryGroups{
    id
  }
  buyerIdentity {
    customer {
      hasTags(tags: ["swell_vip_learned lounger", "swell_vip_pj professional"]) {
        hasTag
        tag
      }
    }
  }
   cost {
      subtotalAmount {
        amount
      }

    }
 }
}

run.js

/**
 * @typedef {import("../generated/api").RunInput} RunInput
 * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult
 */

/**
 * @type {FunctionRunResult}
 */
const EMPTY_DISCOUNT = {
  discounts: [],
};

/**
 * @param {RunInput} input
 * @returns {FunctionRunResult}
 */
export function run(input) {
  console.log("Free Shipping Validation Function");
  // fetch("https://haroon-ins-dev.free.beeceptor.com/", {method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify(input) } )

  const headers = new Headers();
headers.append('Authorization', 'Bearer SOME-VALUE');

fetch('https://haroon-ins-dev.free.beeceptor.com', {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(input)
  })
  .then(response => response.text())
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error(error);
  });

  const SWELL_TIER_2 = "swell_vip_learned lounger";
  const SWELL_TIER_3 = "swell_vip_pj professional";

  let customer = input.cart.buyerIdentity.customer;
  const deliveryGroupId = input.cart.deliveryGroups.id;

  if (
    // customer has tags
    customer && (
      customer?.hasTags.find((t) => t.tag === SWELL_TIER_2)?.hasTag === true ||
      customer?.hasTags.find((t) => t.tag === SWELL_TIER_3)?.hasTag === true
    )
  ) {
    // return free shipping
    const ShippingDiscount = {
      discounts: [
        {
          message: "Free VIP Shipping",
          targets: {
            deliveryGroup: {
              id: deliveryGroupId,
            },
          },
          value: {
            percentage: 100,
          },
        },
      ],
    };
    return ShippingDiscount;
  } else {
    // otherwise return empty discount (no free shipping)
    return EMPTY_DISCOUNT;
  }
}

I tried adding a console.log to show what form of data I am getting inside input but it donot show in the console of frontend.
Tried doing a post request to Beeceptor but request is not reaching there as well.

2

Answers


  1. Chosen as BEST ANSWER

    I fixed the issue with the help provided by Simarjeet Singh and some additional fixes. Here are the fixes I applied that might help anyone seeking answer to same question.

    1. there was problem how I was returning the discount percentage. percentage should be object instead of number and there should be value inside it.
    2. There was problem in the if condition. here is the correct code that's working for me.

    /**
     * @typedef {import("../generated/api").RunInput} RunInput
     * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult
     */
    
    /**
     * @type {FunctionRunResult}
     */
    const EMPTY_DISCOUNT = {
      discounts: [],
    };
    
    /**
     * @param {RunInput} input
     * @returns {FunctionRunResult}
     */
    export function run(input) {
      console.log("Free Shipping Validation Function: Input", input); // Log input data for debugging
    
      const SWELL_TIER_2_LOWER = "swell_vip_learned lounger".toLowerCase();
      const SWELL_TIER_3_LOWER = "swell_vip_pj professional".toLowerCase();
    
      let customer = input.cart.buyerIdentity.customer;
      const deliveryGroupId = input.cart.deliveryGroups[0].id;
    
      if (
        customer &&
        customer.hasTags.some(
          (t) =>
            (t.tag.toLowerCase() === SWELL_TIER_2_LOWER && t.hasTag === true) ||
            (t.tag.toLowerCase() === SWELL_TIER_3_LOWER && t.hasTag === true)
        )
      ) {
        // return free shipping
        const ShippingDiscount = {
          discounts: [
            {
              message: "Free VIP Shipping",
              targets: {
                deliveryGroup: {
                  id: deliveryGroupId,
                },
              },
              value: {
                percentage: {
                  value: 100,
                },
              },
            },
          ],
        };
        return ShippingDiscount;
      } else {
        // otherwise return empty discount (no free shipping)
        return EMPTY_DISCOUNT;
      }
    }


  2. The code you provided seems to be on the right track, but there are a couple of issues that might be preventing free shipping from applying correctly. Let’s break it down:

    1. Logging Issues:

    • Frontend console: Shopify Functions run on the backend and don’t directly interact with the frontend. So, console logs within the function won’t appear in your browser’s developer console.
    • Beeceptor request: Double-check the Beeceptor URL. It might be a typo or require a specific path after the base URL.

    2. Free Shipping Logic:

    The logic to check for tags and apply the discount looks good. However, consider these points:

    • Case Sensitivity: Make sure the tag comparison in customer?.hasTags.find considers case sensitivity. Shopify tags might be case-sensitive. You can use toLowerCase() to ensure a match regardless of case.
    • OR condition: Your current logic uses an OR condition to check for either tag. This works, but if you ever want to require both tags for free shipping, you can change the logic to check if both hasTag properties are true within the find function.

    3. Debugging Tips:

    • Use the Shopify developer tools (https://www.youtube.com/watch?v=bWWmxULp8oM) to inspect your function execution. You can see the input data received by the function and any errors logged.
    • Temporarily remove the Beeceptor call and focus on logging customer.hasTags within the function to verify it retrieves the customer tags correctly.

    Here’s an improved version of run.js incorporating the suggestions:

    /**
     * @typedef {import("../generated/api").RunInput} RunInput
     * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult
     */
    
    /**
     * @type {FunctionRunResult}
     */
    const EMPTY_DISCOUNT = {
      discounts: [],
    };
    
    /**
     * @param {RunInput} input
     * @returns {FunctionRunResult}
     */
    export function run(input) {
      console.log("Free Shipping Validation Function: Input", input); // Log input data for debugging
    
      const SWELL_TIER_2_LOWER = "swell_vip_learned lounger".toLowerCase();
      const SWELL_TIER_3_LOWER = "swell_vip_pj professional".toLowerCase();
    
      let customer = input.cart.buyerIdentity.customer;
      const deliveryGroupId = input.cart.deliveryGroups.id;
    
      if (
        customer &&
        customer.hasTags.some((t) =>
          t.tag.toLowerCase() === SWELL_TIER_2_LOWER ||
          t.tag.toLowerCase() === SWELL_TIER_3_LOWER
        )
      ) {
        // return free shipping
        const ShippingDiscount = {
          discounts: [
            {
              message: "Free VIP Shipping",
              targets: {
                deliveryGroup: {
                  id: deliveryGroupId,
                },
              },
              value: {
                percentage: 100,
              },
            },
          ],
        };
        return ShippingDiscount;
      } else {
        // otherwise return empty discount (no free shipping)
        return EMPTY_DISCOUNT;
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search