New to working with Shopify functions. I’ve read a ton of the documentation and followed the tutorial to create a discount experience for 10% off for a volume order.
I want to customize this now. Ideally, I want to eventually have a function for a tiered discount where a gift card of a certain value will be automatically added to the cart when the user enters a certain discount code. The gift card amount will be determined by the cart subtotal.
To work up to that, I’m currently just trying to have the cart subtotal discounted 10% when it is over $50. I’ve read the documentation for discounts and cart API and objects, but the code doesn’t work. This is what I have (photos attached for easier reading):
// @TS -check
import { DiscountApplicationStrategy } from “../generated/api”;
@returns {FunctionResult}
*/
(input) => {
// Calculate the total pre-tax cost of items in the cart
let totalPreTaxCost = 0;
for (const line of input.cart.lines) {
const lineSubtotal = line.cost.subtotalAmount.amount;
totalPreTaxCost += lineSubtotal;
}
// Check if the total pre-tax cost is greater than $50
if (totalPreTaxCost > 50) {
// Add the free product to the cart
// Replace this with the code to add the free product to the cart
// …
// Apply a 10% discount to all items in the cart
const targets = input.cart.lines.map(line => {
const variant = /** @type {ProductVariant} / (line.merchandise);
return /* @type {Target} */ ({
productVariant: {
id: variant.id
}
});
});
if (!targets.length) {
console.error(“No cart lines qualify for volume discount.”);
return EMPTY_DISCOUNT;
}
Your code logic seems almost correct except that you closed your if (totalPreTaxCost > 50) condition too early. This is causing your function to always return EMPTY_DISCOUNT, regardless of the subtotal amount.
Here’s a corrected version of your code:
// @TS-check
import { DiscountApplicationStrategy } from "../generated/api";
/**
* @typedef {import("../generated/api").InputQuery} InputQuery
* @typedef {import("../generated/api").FunctionResult} FunctionResult
* @typedef {import("../generated/api").Target} Target
* @typedef {import("../generated/api").ProductVariant} ProductVariant
*/
/**
* @type {FunctionResult}
*/
const EMPTY_DISCOUNT = {
discountApplicationStrategy: DiscountApplicationStrategy.First,
discounts: [],
};
// The @Shopify/shopify_function package will use the default export as your function entrypoint
export default /**
* @param {InputQuery} input
* @returns {FunctionResult}
*/
(input) => {
// Calculate the total pre-tax cost of items in the cart
let totalPreTaxCost = 0;
for (const line of input.cart.lines) {
const lineSubtotal = line.cost.subtotalAmount.amount;
totalPreTaxCost += lineSubtotal;
}
// Check if the total pre-tax cost is greater than $50
if (totalPreTaxCost > 50) {
// Apply a 10% discount to all items in the cart
const targets = input.cart.lines.map(line => {
const variant = /** @type {ProductVariant} */ (line.merchandise);
return /** @type {Target} */ ({
productVariant: {
id: variant.id
}
});
});
if (!targets.length) {
console.error("No cart lines qualify for volume discount.");
return EMPTY_DISCOUNT;
}
return {
discounts: [
{
targets,
value: {
percentage: {
value: "10.0"
}
}
}
],
discountApplicationStrategy: DiscountApplicationStrategy.First
};
}
// If the total pre-tax cost is not greater than $50, return an empty discount
return EMPTY_DISCOUNT;
};
Remember to replace the "10.0" string with a numerical value 10.0 as the discount percentage should be a number, not string.
for (const line of input.cart.lines) { const lineSubtotal = line.cost.subtotalAmount.amount; totalPreTaxCost += lineSubtotal; }
Ended up needing to change this line. Instead of getting the cost attribute of each line, just got the cost attribute of the cart directly.
Thoughts on this updated code? API-KEY is being replaced with the appropriate API key. The subtotal is calculate correctly now, I tested the ALL_PRODUCTS query in graphQL and it correctly retrieves gift cards, the tiered discount was working when it was a percentage off.
I’m thinking the issue is with the CartTransform mutation? Can this be combined with a discount like I’m trying to do to add the gift card to the cart?
I have a similar need to add free gift based on cart total price. But I need to check the total price where discount code is applied. For example if the original total cart price was $120 and customer applied 20% discount code, it will be $96.
And I’d like to offer a free gift which is provided by handle in shop’s global metafield and cart total price threshold.
Assume, there is a free gift setting by total cart price >= $100, then gift should be added only when discount code is not applied. If discount code (20% discount) has been applied, this gift should not be added. How can we check this price where discount code is applied in Shopify Function?
Also, how can we access global metafields of Shop?