Shipping information

Learn how to set a shipping address and fetch available Shipping Methods using the Composable Commerce API.

Copy for LLM
View as Markdown

After completing this page, you should be able to:

  • Set a shipping address on a Cart

  • Fetch available Shipping Methods for a Cart

  • Handle multiple shipping addresses for complex scenarios

  • Integrate external address validation services

The Shipping stage determines how and when an Order will be delivered. Setting the shipping information is a critical step that directly impacts Cart totals, available delivery options, and checkout feasibility.

Setting shipping details on a Cart triggers an automatic recalculation of:

  • Shipping costs: Based on the selected Shipping Method and destination
  • Taxes: Calculated according to the shipping address and your Project's tax configuration
  • Available delivery options: Determined by the shipping address and Zone configurations

In Composable Commerce, shipping details are stored on the Cart entity. The platform automatically recalculates shipping costs and applicable taxes whenever:

  • The shipping address changes.
  • The Shipping Method changes.
  • A shipping-related discount or promotion is applied.

Collecting the shipping address

The first step is to collect the customer's shipping address.

If a Cart contains only virtual or digital products, you can skip the shipping address collection step entirely.

Guest checkout

For guest users, you must provide a form to capture their shipping address. This address should be set on the Cart to enable tax calculation and retrieve the applicable Shipping Methods.

Registered users

For registered users, you can pre-populate the information from their saved addresses. You can improve the user experience by:

  • Reading existing addresses from the customer.addresses array.
  • Allowing the user to select a default shipping address or add a new one.
  • Limiting the number of stored addresses—for example, a maximum of 10—to maintain a clean user interface.

Address validation

This is optional—to reduce delivery errors and improve data quality, integrate a third-party address validation service like Loqate, Google Places API, or UPS Address Validation. To avoid unnecessary API calls to Composable Commerce, you can perform validation on the client-side or in your BFF before updating the Cart.

Set the shipping address on the Cart

Setting the shippingAddress on a Cart is a key action that triggers tax recalculation and determines the eligible Shipping Methods. You can update the address using the setShippingAddress Cart update action.
async function setShippingAddress(
  storeKey: string,
  cartId: string,
  version: number,
  address
) {
  return apiRoot
    .inStoreKeyWithStoreKeyValue({ storeKey })
    .carts()
    .withId({ ID: cartId })
    .post({
      body: {
        version,
        actions: [{ action: "setShippingAddress", address }],
      },
    })
    .execute();
}
If you use a Store per delivery country, you can set a delivery country on newly created Carts. This allows the Cart to calculate shipping costs and taxes, and display totals before the customer enters the checkout sequence and sets their delivery address—for example, on the cart overview page.

Special shipping scenarios

Your implementation should account for more complex shipping requirements.

  • Multiple shipments: Composable Commerce supports shipping items in a single Cart to multiple addresses. For this, shipping-related data is managed in the Cart's shipping array, and you can specify itemShippingAddresses for individual Line Items. You can also set different shipping methods for each Line Item. For a detailed understanding, refer to the Multiple Shipping Addresses and Methods tutorial.

    Since this adds complexity to your data model, test the scenarios carefully.

  • Click and collect: The shipping address can be a physical store or collection point, which can affect tax calculations.
  • Split billing and shipping addresses: The billing address might not match the delivery address.
  • External tax providers: When using an External or ExternalAmount tax mode, your application must provide the correct tax rates and amounts, including those for shipping.
    When a Cart's taxMode is set to External, Composable Commerce might still perform intermediate calculations. In jurisdictions with complex tax laws, such as the USA, this can lead to minor rounding discrepancies between the tax amounts calculated by commercetools and an integrated third-party tax provider.
    To ensure tax consistency, treat your third-party tax provider as the single source of truth. Set the Cart's taxMode to ExternalAmount to apply the exact tax totals from your tax provider directly to the Cart. This approach bypasses internal calculations and avoids rounding conflicts. It also ensures that when an Order is created and imported into a third-party system, no discrepancies occur.

    Ensure your third-party tax solution and pricing data are configured correctly.

Fetch available Shipping Methods

Shipping Methods are determined by the shipping address, Cart contents (such as weight and dimensions), and your Project's Zone configurations. A Zone is a geographic area where specific Shipping Methods and tax rates apply.

Use the matching Shipping Methods for a Cart endpoint to retrieve only the methods that are valid for the current Cart. If the Shipping Method does not match the Cart's conditions, the API will reject the update.

async function getShippingMethodsForCart(cartId: string) {
  return apiRoot
    .shippingMethods()
    .matchingCart()
    .get({ queryArgs: { cartId } })
    .execute();
}

Set the Shipping Method

After the customer selects a shipping option, use the setShippingMethod Cart update action to set a Shipping Method for the Cart. If the Shipping Method does not match the Cart's conditions, the API rejects the request.
async function setShippingMethod(
  storeKey: string,
  cartId: string,
  version: number,
  shippingMethodId: string
) {
  return apiRoot
    .inStoreKeyWithStoreKeyValue({ storeKey })
    .carts()
    .withId({ ID: cartId })
    .post({
      body: {
        version,
        actions: [
          {
            action: "setShippingMethod",
            shippingMethod: { id: shippingMethodId, typeId: "shipping-method" },
          },
        ],
      },
    })
    .execute();
}
After the update, the Cart includes the recalculated shipping rate, discounts, and taxes. Ensure your frontend displays the updated totals from fields like shippingInfo.price and taxedPrice.totalGross to avoid showing a mismatched order summary.

Key takeaways

  • Set the shipping address as the first step in the Shipping stage, since it determines tax calculation and Shipping Method eligibility.
  • Fetch only the Shipping Methods applicable to the current Cart using the matchingCart endpoint.
  • Retrieve the updated Cart after changing the shipping address or Shipping Method to display the latest totals.
  • Design your architecture to handle special scenarios, including multiple shipments and external tax providers.
  • Use an external address validation service to improve data accuracy and reduce delivery failures.

Next, we will learn about billing information and payment method selection, where you'll collect billing addresses and prepare the cart for payment.

Test your knowledge