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.addressesarray. - 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
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();
}
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
shippingarray, and you can specifyitemShippingAddressesfor 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
ExternalorExternalAmounttax mode, your application must provide the correct tax rates and amounts, including those for shipping.When a Cart'staxModeis set toExternal, 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'staxModetoExternalAmountto 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
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();
}
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
matchingCartendpoint. - 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.