Shopify Discount Function not working properly if i use other discounts in the Cart

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

  }

}

Hi @gunasekaranA

Shopify Functions calculate discounts in a sequence based on their Discount Class. Your function currently reads the original line costs because it doesn’t account for reductions made by other discounts before it runs.

To fix this, update your Run.graphql to fetch the totalAmount for each line, which includes line-level discounts. In your function logic, ensure you are using an Order Discount class, as these are calculated after Product discounts. If you need to account for other order-level discounts, you should calculate the rounding based on the cart.cost.totalAmount instead of summing the lines manually.

Hope this helps

Thanks for the explanation. I’ve already tried the suggested approaches, including using lines.cost.totalAmount, cart.cost.totalAmount, and changing the discount class to Order. However, I’m still not able to get the product value after other discounts are applied.

@gunasekaranA In Shopify Functions, discounts do not run sequentially. Your function cannot see the final discounted price after other discounts are applied. Even though line.cost.totalAmount looks like it should be “final”, it’s still calculated before discount resolution is complete.

Key points:

Shopify evaluates all discounts in parallel, not in order

A Function cannot depend on the result of another discount

There is no hook for “after all discounts are applied”

So your round-off function will always calculate from the pre-discount amounts.

What can you do instead?

Only one of these approaches works:

Make the round-off discount the only order-level discount (don’t stack it with others)

Move the rounding logic outside discounts (e.g. pricing, variants, or checkout UX)

Accept rounding on original subtotal, not discounted subtotal (Shopify limitation)

At the moment, Shopify does not support post-discount calculations inside Functions.

If Shopify changes the discount execution model, this may become possible but today, this is the hard limit.

Thanks for the clear explanation, Erick.

@gunasekaranA I’m happy if this helped :blush:. If this helped out you can mark solution. Thanks