Magento 2

Magento 2 Flat Rate Free Shipping Bug: Why Your Customers Are Still Paying

Technical diagram showing Magento 2 shipping carrier logic for free shipping flags
Technical diagram showing Magento 2 shipping carrier logic for free shipping flags

Magento 2 Flat Rate Free Shipping Bug: Why Your Customers Are Still Paying

As e-commerce migration experts at Shopping Mover, we are constantly monitoring the pulse of the Magento community, especially critical bugs that can impact merchant operations and customer satisfaction. A recent GitHub issue (Issue #41431) has brought to light a significant bug in Magento 2's Flat Rate shipping method concerning free shipping cart rules. This insight delves into the problem, its technical roots, and provides an immediate workaround for affected Magento Open Source and Adobe Commerce users.

Accurate shipping calculations are fundamental to any successful online store. When a customer expects free shipping and is charged, it erodes trust, increases cart abandonment, and can lead to costly manual refunds. This particular bug, reported on Magento 2.4.9 and reproducible on 2.4-develop, highlights a critical discrepancy in how Magento handles free shipping rules with the Flat Rate carrier.

The Magento 2 Flat Rate Free Shipping Conundrum

Merchants frequently configure cart rules to offer free shipping based on specific conditions, such as a minimum order subtotal or specific product inclusions. A common setup involves a cart rule with the "Free Shipping" option set to "For shipment with matching items". The expectation is straightforward: if the cart meets the rule's conditions, the Flat Rate shipping cost should be zeroed out.

However, users have discovered that when the Flat Rate shipping method is enabled, it continues to charge the full shipping price, even when a qualifying free shipping rule is active. Consider this scenario:

  • Magento Version: 2.4.9 Open Source (or Adobe Commerce)
  • Shipping Method: Flat Rate enabled, e.g., $5.00 per item.
  • Cart Rule: "Spend $50 or more - shipping is free!" with "Free Shipping" set to "For shipment with matching items".
  • Customer Action: Adds 2 x Joust Duffle Bags to the cart, subtotal $68.00.
  • Expected Result: Shipping $0.00.
  • Actual Result: Shipping $10.00.

This issue is not limited to the storefront checkout but also manifests when using Magento's REST API for shipping information:

POST /rest/V1/guest-carts/{cartId}/shipping-information
{"addressInformation": {..., "shipping_carrier_code": "flatrate", "shipping_method_code": "flatrate"}}

In this case, the API response would still show the Flat Rate charge, despite the rule being applied (indicated by applied_rule_ids on the quote and free_shipping = 1 on the shipping address).

Unpacking the Technical Discrepancy

The core of this issue lies in how different Magento shipping carriers interpret free shipping flags. When a cart rule with "For shipment with matching items" is applied, Magento's Calculator::applyFreeShippingRule() correctly sets the free_shipping flag on the shipping address ($address->setFreeShipping(true)). This indicates that the entire shipment should be free.

The problem arises within the Flatrate carrier's logic. Specifically, its getFreeBoxesCount() method, which determines how many items should be charged, only checks the free_shipping flag at the item level ($item->getFreeShipping()). It completely overlooks the free_shipping flag set on the address itself.

This behavior contrasts sharply with other built-in shipping carriers:

  • The Tablerate carrier correctly checks $item->getFreeShipping() || $item->getAddress()->getFreeShipping(), meaning it honors both item-level and address-level free shipping flags.
  • The Freeshipping carrier also checks $request->getFreeShipping(), which is derived from the address's free shipping status.

Historical context reveals that this address-level check was removed from both Flat Rate and Tablerate carriers in a commit (cdefefa948, related to MAGETWO-63844) back in 2017. While Tablerate later had this crucial check reinstated, Flat Rate did not, leading to the current bug. This isn't the first time this issue has surfaced; similar problems were reported in #35967 and #37945, both of which were unfortunately closed without a fix.

Impact on Merchants and Customer Experience

This bug, classified with a severity of S2 (Affects non-critical data or functionality and forces users to employ a workaround), has significant implications for merchants:

  • Customer Dissatisfaction: Customers expecting free shipping will be confused and frustrated when charged, leading to negative reviews and reduced loyalty.
  • Increased Support Load: Merchants will face a surge in customer service inquiries and requests for refunds.
  • Operational Inefficiency: Manual refunds are time-consuming and prone to errors, impacting accounting and reconciliation processes.
  • Lost Sales: Cart abandonment rates can spike if customers encounter unexpected shipping charges at checkout.
  • Brand Reputation Damage: Inaccurate pricing undermines trust in the store and the brand.

For businesses undergoing a Magento migration, such subtle yet critical bugs highlight the importance of thorough pre-migration audits and post-migration testing. Ensuring that all shipping logic, especially complex cart rules, functions identically and correctly on the new platform is paramount to a successful transition.

Immediate Workaround: Adjusting Your Cart Rule

While a permanent fix is awaited from the Magento core team, there's an immediate workaround available:

Change your cart rule's "Free Shipping" setting from "For shipment with matching items" to "For matching items only".

When this setting is used, the rule explicitly sets the free_shipping flag on the individual items in the cart that match the rule's conditions. Since Flat Rate's getFreeBoxesCount() method *does* check item-level free shipping flags, this workaround effectively zeros out the shipping cost for qualifying items.

Considerations for the Workaround: While effective, this workaround might not be ideal for all scenarios. "For matching items only" applies free shipping on a per-item basis, which might behave differently if your rule intends to grant free shipping for the *entire shipment* based on a total cart value, regardless of whether all items qualify individually. Always test thoroughly after implementing this change.

The Path Forward: Awaiting a Core Fix

The ideal long-term solution requires a fix within the Magento core. The Flat Rate carrier's collectRates() method, or specifically its getFreeBoxesCount(), needs to be updated to honor the address-level free_shipping flag, similar to how Tablerate and Freeshipping carriers operate. This would involve checking $request->getFreeShipping() or $item->getAddress()->getFreeShipping().

The Magento community plays a vital role in pushing such fixes forward. Developers can contribute by submitting pull requests that address this discrepancy, ensuring robust and consistent shipping logic across all core carriers.

Shopping Mover's Expertise in Action

At Shopping Mover, our role as e-commerce migration experts extends beyond simply moving data. We conduct comprehensive audits of your existing Magento setup, identifying potential pitfalls like this Flat Rate bug, and ensuring that your new platform (whether it's an upgraded Magento 2 instance or a different e-commerce solution) handles all business logic, including complex shipping rules, flawlessly. Our rigorous testing protocols are designed to catch such discrepancies before they impact your live store and your customers.

Conclusion

The Magento 2 Flat Rate free shipping bug is a prime example of how seemingly minor technical discrepancies can lead to significant operational challenges and customer dissatisfaction. While the "For matching items only" workaround provides immediate relief, a permanent core fix is essential for the long-term health and reliability of Magento's shipping functionality. Stay informed, test your shipping configurations diligently, and consider partnering with migration experts like Shopping Mover to safeguard your e-commerce operations against such critical issues.

Share:

Start with the tools

Explore migration tools

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

Explore migration tools