Applying different discount based on customer and multiple variant tags - Shopify function

Topic summary

A developer is migrating a Shopify script to a Shopify Function that applies tiered discounts (50%, 30%, 20%) to customers tagged as “Employee” based on product tags (“OFF50”, “OFF30”, “OFF20”). The main challenge is checking multiple product tags within a single function using DiscountApplicationStrategy.ALL.

Technical Issue:

  • Need to query multiple product tags and apply corresponding percentage discounts per cart line item
  • Uncertainty about proper implementation with the Shopify Functions API

Solution Provided:
A complete code example was shared showing:

  • GraphQL query using hasTags(tags: ["OFF20", "OFF30", "OFF50"]) to check multiple tags simultaneously
  • JavaScript logic that:
    • Verifies customer has “Employee” tag
    • Iterates through cart lines checking product tags
    • Maps tags to discount percentages using an object ({OFF50: 50, OFF30: 30, OFF20: 20})
    • Applies one discount per product with appropriate targeting

A related community thread was also referenced for additional context on accessing multiple discount nodes and metafield values.

Status: Solution appears complete with working code provided.

Summarized with AI on November 5. AI used: claude-sonnet-4-5-20250929.

I’ve script that provide discount to the customer that has tagged with “Employee” tag and based on product tag specific tag like “OFF50”, “OFF30” and “OFF20” . Like if customer has Employee tag then it check if products on cart has “OFF50”, “OFF30” and “OFF20” tag and provide the 50%, 30% and 20% off based on product tag . Now we want to migrate it to Shopify function.

I am not sure how to check multiple product tag using one function using DiscountApplicationStrategy.ALL . anyone have idea how can I do that?

Here is code:

query RunInput {
  cart {
    buyerIdentity {
      customer {
        hasTags(tags: ["Employee"]) {
          tag
          hasTag
        }
      }
    }
    lines {
      id
      merchandise {
        ...on ProductVariant {
          id
          product {
            hasAnyTag(tags: ["OFF20","OFF30","OFF50"])
          }
        }
        __typename
      }
    }
  }
}

run.js:

// -check
import { DiscountApplicationStrategy } from "../generated/api";

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

/**
 *  {FunctionRunResult}
 */
const EMPTY_DISCOUNT = {
  discountApplicationStrategy: DiscountApplicationStrategy.All,
  discounts: [],
};

/**
 * @param {RunInput} input
 * @returns {FunctionRunResult}
 */
export function run(input) {

  // Check if the customer has the "employee" tag
  const customerTags = input.cart.buyerIdentity?.customer?.hasTags || [];
  console.error("customer value = " + customerTags);

// how to check product tags here
  
 

  return EMPTY_DISCOUNT;
};

Thanks !

Follow this thread, It is relevant and I recently posted an answer that should solve your issues.

https://community.shopify.com/c/shopify-functions/how-can-i-access-multiple-discountnodes-metafields-value/m-p/2784033#M2427

run.graphql:

query RunInput {
	cart {
		buyerIdentity {
			customer {
				hasTags(tags: ["Employee"]) {
					tag
					hasTag
				}
			}
		}
		lines {
			id
			merchandise {
				... on ProductVariant {
					id
					product {
						hasTags(tags: ["OFF20", "OFF30", "OFF50"]) {
							hasTag
							tag
						}
					}
				}
				__typename
			}
		}
	}
}

run.js:

export function run(input) {
	
	const requiredTags = {
		OFF50: 50,
		OFF30: 30,
		OFF20: 20,
	};
	const discounts = [];

	const customerTags = input.cart.buyerIdentity.customer.hasTags.map(
		(tag) => tag.tag,
	);
	const isEmployee = customerTags.includes('Employee');

	if (isEmployee) {
		input.cart.lines.forEach((line) => {
			const productTags = line.merchandise.product.hasTags.map(
				(tag) => tag.tag,
			);

			for (const [tag, discountValue] of Object.entries(requiredTags)) {
				if (productTags.includes(tag)) {
					discounts.push({
						message: `Employee discount of ${discountValue}% applied.`,
						targets: [
							{
								type: 'CartLineTarget',
								id: line.id,
							},
						],
						value: {
							type: 'percentage',
							percentage: discountValue,
						},
					});
					break; // Apply only one discount per product
				}
			}
		});
	}

	if (discounts.length > 0) {
		return {
			discountApplicationStrategy: DiscountApplicationStrategy.ALL,
			discounts: discounts,
		};
	}

	return EMPTY_DISCOUNT;
}

This way, you can check for multiple tags effectively. Make sure to adjust the discount application logic as needed based on your specific requirements!