# Shipping information 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 commercetools, 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 commercetools, 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. ```ts 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](/api/projects/stores.md) 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**: commercetools supports shipping items in a single Cart to multiple addresses. For this, store the available item-level addresses in `itemShippingAddresses`, and reference them from the Line Item `shippingDetails`. If the Cart uses `Multiple` shipping mode, shipping-related data is also managed in the Cart’s `shipping` array, and you can assign different Shipping Methods to different Line Items. For conceptual details, see [Shipping and Delivery Overview](/api/shipping-delivery-overview.md). For a working API example, see [Multiple Shipping Addresses and Methods](/tutorials/multiple-shipping-addresses-methods.md). 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](/api/carts-orders-overview.md#tax-modes), your application must provide the correct tax rates and amounts, including those for shipping. When using an `External` [tax mode](/api/carts-orders-overview.md#tax-modes), minor rounding discrepancies can occur between the commercetools Cart calculations and your third-party tax provider. To ensure consistency, use the `ExternalAmount` tax mode to apply exact tax totals from your provider directly to the Cart. For more information, see [Integrate tax](/tutorials/tax-integration.md). ## 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. ```ts 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. ```ts 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. ```mermaid sequenceDiagram participant C as Client participant B as BFF participant CT as commercetools C->>B: POST /checkout/shipping-address B->>CT: Update Cart (setShippingAddress) CT-->>B: Updated Cart (new version, taxes recalculated) B->>CT: GET Shipping Methods (matchingCart) CT-->>B: Applicable Shipping Methods B-->>C: Updated Cart + Shipping Methods ``` ### 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](/api/projects/shippingMethods.md#for-a-cart-in-store). - Retrieve the updated Cart after changing the shipping address or Shipping Method to display the latest totals. - Design your architecture to handle [special scenarios](/learning-implement-checkout/custom-checkout/shipping.md#special-shipping-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. ## Related pages - [Area overview page with navigation](/learning-implement-checkout.md) - [Previous page: Cart preparation and review](/learning-implement-checkout/custom-checkout/cart-preparation-and-review.md) - [Next page: Billing information](/learning-implement-checkout/custom-checkout/billing.md) - [Search documentation and API specs](/search.md)