Heads Up, Zero-Decimal Currency Stores! A Deep Dive into Shopify's `cart.js` Discount Quirks (and a Potential Fix!)

Hey fellow store owners and developers! As someone who spends a lot of time digging into the nitty-gritty of Shopify migrations and community discussions, I often come across fascinating threads that highlight the subtle complexities of running an online store. Recently, a discussion popped up that's super relevant for anyone dealing with international sales, especially if you're using what Shopify calls 'zero-decimal currencies' like the Chilean Peso (CLP) or Vietnamese Dong (VND).

It all started with a sharp observation from a community member, duongnt.avadagroup. They pointed out what looked like a significant inconsistency in Shopify's Ajax Cart API (specifically the /cart.js endpoint) when handling discounts for these zero-decimal currencies. And trust me, when your cart's numbers aren't adding up, that's a red flag you want to investigate immediately!

The Curious Case of `line_level_total_discount`

So, what was the big deal? duongnt.avadagroup explained that for stores using currencies like CLP, VND, and even JPY or KRW (which are also zero-decimal), nearly all money-related fields in the /cart.js response – think price, total_discount, and individual discount allocations like line_level_discount_allocations[].amount – were behaving as expected. They were all using the standard 'cents-like' integer units, meaning a value of 100000 for CLP would represent 1,000 CLP.

However, there was one outlier: the line_level_total_discount field. For some reason, this specific field was being returned at a different scale, effectively 100 times smaller than all the other discount fields. Imagine trying to calculate your cart totals when one key discount figure is off by two decimal places! That's a developer's nightmare and a potential headache for accurate display on your storefront.

To illustrate, here's a simplified example from duongnt.avadagroup's post, showing what they saw in a CLP store's /cart.js output:

{
  "currency": "CLP",
  "items": [
    {
      "price": 1099000,
      "original_price": 1099000,
      "discounted_price": 989100,

      "total_discount": 219800,
      "discounts": [
        {
          "amount": 219800,
          "title": "AOVAI_7EJ2U0P9"
        }
      ],

      "line_level_discount_allocations": [
        {
          "amount": 219800,
          "discount_application": {
            "title": "AOVAI_7EJ2U0P9",
            "total_allocated_amount": 219800
          }
        }
      ],

      "line_level_total_discount": 2198
    }
  ]
}

Notice how total_discount and line_level_discount_allocations[0].amount both show 219800 (representing 2,198 CLP), but line_level_total_discount is 2198? Yep, that's the 100x discrepancy right there. For non-zero-decimal currencies like USD or EUR, all these fields would be perfectly consistent. This made it look like a very specific, zero-decimal currency bug.

Why This Matters for Your Store

If you're using custom scripts to display cart information, calculate totals, or integrate with third-party apps that rely on /cart.js data, this kind of inconsistency can lead to:

  • Incorrect Discount Displays: Your customers might see the wrong discount amount applied to a line item, which can erode trust.
  • Miscalculated Totals: If your custom cart summary uses line_level_total_discount, your final cart total could be off.
  • Developer Headaches: Developers have to write extra conditional logic to handle zero-decimal currencies differently, making code more complex and prone to errors.

duongnt.avadagroup rightly pointed out that Shopify's documentation doesn't mention this scaling difference, which is a strong indicator that it was indeed an unintended bug rather than a feature.

Has Shopify Fixed It? A Community Update!

Now, here's where it gets interesting and highlights the power of the community. In a follow-up post on the same thread, another member, VRverse, chimed in with some good news! They reported:

"i think they fix the issue now here it showing properly with CLP or VND currency with {amount_no_decimals}} ."

This is fantastic news! It suggests that Shopify has likely addressed this bug. VRverse even included a screenshot showing the proper display, which is always reassuring to see:

The mention of {amount_no_decimals}} is key here. It suggests that when displaying prices or discounts, especially for currencies that don't traditionally use decimals (like CLP or VND), Shopify's liquid filters are now correctly handling the output, likely after the underlying API data has been normalized. This is a huge win for consistency and ease of development!

What You Need to Do: Verify Your Store's `cart.js`

Even with a reported fix, it's always a good practice to verify things on your own store, especially if you've done custom development or are operating in zero-decimal currency markets. Here's a quick checklist:

  1. Access Your Store's `cart.js` Output

    Go to your store's URL and simply add /cart.js to the end (e.g., yourstore.myshopify.com/cart.js). This will show you the raw JSON data that your theme and apps use to display cart information.

  2. Add a Product with a Discount to Your Cart

    Ensure you have at least one product in your cart that has a line-item specific discount applied (e.g., through an automatic discount, a draft order discount, or an app). This will populate the relevant discount fields in the /cart.js output.

  3. Inspect the Discount Fields for Consistency

    Look specifically at line_level_total_discount, total_discount, and line_level_discount_allocations[].amount for your zero-decimal currency. Are they now showing consistent values? For example, if total_discount is 219800, then line_level_total_discount should also be 219800, not 2198.

  4. Check Your Theme's Display Logic

    If you have custom code that was trying to work around this bug (e.g., multiplying line_level_total_discount by 100), you'll want to remove that workaround. Ideally, you should be using Shopify's built-in money filters (like {{ amount | money_without_currency }} or {{ amount | money_without_decimals }}) in your Liquid templates to ensure proper formatting for all currencies. These filters are designed to handle the various currency formats correctly.

  5. Test with Different Zero-Decimal Currencies

    If you operate in multiple zero-decimal currency markets (CLP, VND, JPY, KRW), it's worth testing each one to ensure the fix is applied universally.

It's great to see Shopify's team addressing these kinds of inconsistencies, and it's a testament to the community that such detailed issues are brought to light. This ensures that everyone building on Shopify can do so with confidence, knowing the underlying data is reliable. Always remember to keep an eye on your store's specific API responses, especially after platform updates or if you're working with less common currency configurations. Staying proactive can save you a lot of headaches down the line!

Share:

Start with the tools

Explore migration tools

See options, compare methods, and pick the path that fits your store.

Explore migration tools