I’ve created a round-off discount using the Shopify Functions API. It works correctly when no other discounts are applied.
For example:
-
Product price 99.99 → round-off discount 0.99
-
Product price 49.49 → round-off discount 0.49
This works as expected when the cart has only this discount.
However, when any other discount (product discount, automatic discount, or discount code) is applied to the cart, my function still calculates the round-off discount based on the original product price, not the discounted price.
So even after another discount is applied, the function continues to read the original decimal value instead of the updated discounted amount.
Has anyone faced this issue before?
How can I make the Shopify Function calculate the round-off discount after all other discounts have been applied?
Check my code:
import {
DiscountClass,
OrderDiscountSelectionStrategy,
} from '../generated/api';
/**
* @typedef {import("../generated/api").CartInput} RunInput
* @typedef {import("../generated/api").CartLinesDiscountsGenerateRunResult} CartLinesDiscountsGenerateRunResult
*/
/**
* @param {RunInput} input
* @returns {CartLinesDiscountsGenerateRunResult}
*/
export function cartLinesDiscountsGenerateRun(input) {
if (!input.cart.lines.length) {
return { operations: [] };
}
const hasOrderDiscountClass = input.discount.discountClasses.includes(
DiscountClass.Order,
);
const operations = [];
if (hasOrderDiscountClass) {
console.error('=== Starting Round Down Calculation ===');
let effectiveSubtotal = 0;
// Loop through lines using the NEW field
for (const line of input.cart.lines) {
const linePrice = parseFloat(line.cost.totalAmount.amount);
effectiveSubtotal += linePrice;
}
console.error(`Correct Discounted Cart Total: ${effectiveSubtotal}`);
// Calculate rounding based on this sum
const decimalPart = parseFloat((effectiveSubtotal % 1).toFixed(2));
// const decimalPart = parseFloat((cartTotal % 1).toFixed(2));
console.error(`Decimal part to discount: ${decimalPart}`);
// Only apply if there are cents to remove
if (decimalPart > 0) {
console.error(`Applying round down discount of $${decimalPart.toFixed(2)}`);
operations.push({
orderDiscountsAdd: {
candidates: [
{
message: `Round down discount -$${decimalPart.toFixed(2)}`,
targets: [
{
orderSubtotal: {
excludedCartLineIds: [],
},
},
],
value: {
fixedAmount: {
amount: decimalPart.toFixed(2),
},
},
},
],
selectionStrategy: OrderDiscountSelectionStrategy.Maximum,
},
});
} else {
console.error('No decimal part to discount');
}
}
console.error('=== End Round Down Calculation ===');
return { operations };
}
Run.graphql
query CartInput {
cart {
cost {
subtotalAmount {
amount
}
totalAmount {
amount
}
}
lines {
cost {
subtotalAmount {
amount
}
totalAmount {
amount
}
}
}
}
discount {
discountClasses
}
}