Magento 2 GraphQL Glitch: Unpacking Default Customer Address Save Issues

As e-commerce continues its shift towards headless architectures, Magento 2's GraphQL API becomes an increasingly vital component for seamless data exchange and customer experience. However, even the most robust systems can harbor subtle bugs that impact core functionality. A recent GitHub issue (magento/magento2#41597) brought to light a significant glitch in how Magento 2's GraphQL handles customer addresses, specifically when setting billing addresses to be the same as shipping.

The Core Problem: Missing Default Address Flags in GraphQL Orders

The issue describes a scenario where, despite placing an order via GraphQL with a new address and explicitly using same_as_shipping: true for the billing address, the newly saved customer address was not marked as the default shipping or default billing address. Furthermore, the order's billing address was not correctly linked to the saved customer address, leading to data inconsistencies.

This behavior deviates significantly from the expected outcome seen in the storefront checkout or when using REST APIs, where the address would be saved as the customer's default shipping and billing address, and both order addresses would be correctly linked to the customer's address book entry.

Reproducing the GraphQL Address Bug

The issue author provided clear, step-by-step instructions using GraphQL mutations, which are invaluable for developers trying to understand or replicate the problem. The process involves:

  1. Generating a customer token.
  2. Retrieving the customer's cart ID.
  3. Adding a product to the cart.
  4. Setting a new shipping address (save_in_address_book defaults to true).
  5. Crucially, setting the billing address using same_as_shipping: true:
    mutation {
      setBillingAddressOnCart(input: {cart_id: "", billing_address: {same_as_shipping: true}}) {
        cart { id }
      }
    }
  6. Setting shipping and payment methods, then placing the order.
  7. Finally, querying the customer's addresses to observe the incorrect default_shipping and default_billing flags.
    { customer { addresses { id default_shipping default_billing } } }

Unpacking the Root Cause: A Deep Dive for Developers

The detailed root cause analysis provided in the issue is a testament to the community's dedication to understanding Magento's internal workings. It points to two key areas:

  • QuoteManagement::_prepareCustomerQuote(): This method was found to skip both the shipping and billing addresses in this specific GraphQL flow. The shipping address was skipped because it had same_as_billing = 1, and the billing address lacked save_in_address_book because QuoteAddressFactory::createBasedOnShippingAddress() failed to copy this flag.
  • Magento\QuoteGraphQl\Plugin\CustomerManagementPlugin::beforePopulateCustomerInfo(): While this plugin was designed to save addresses to the address book (similar to REST's PaymentInformationManagement::processShippingAddress()), it critically failed to set the default shipping/billing flags (via saveAddressesAsDefault()) and did not link the customer address ID to the billing quote address. This plugin was introduced in a previous commit (6904e9f79a) to address a related issue, but inadvertently missed these crucial steps for default address handling.

Impact on Headless Magento Implementations and Migrations

For merchants leveraging Magento 2 in a headless setup, or those undergoing a Magento migration, this bug could lead to significant data integrity issues and a degraded customer experience. Customers would find their newly used addresses not automatically set as default, requiring manual updates. This not only adds friction but can also complicate subsequent orders and address management.

The Resolution: Aligning GraphQL with Storefront Behavior

Fortunately, the issue includes a release note indicating a resolution: "Placing an order through GraphQL with same_as_shipping now saves the address as the customer's default shipping and billing address when the customer has none yet, the same as the storefront checkout." This confirms that the bug has been addressed, ensuring that GraphQL's address management aligns with the expected behavior of the Magento storefront and REST API.

This fix is crucial for maintaining consistency across all Magento touchpoints and reinforces the importance of thorough testing, especially in complex areas like GraphQL and address management. Developers and merchants using or planning headless Magento 2 implementations should ensure they are on a version that includes this fix to avoid potential customer data discrepancies.

Start with the tools

Explore migration tools

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

Explore migration tools