Shipping and Delivery Overview

Overview of the concepts related to shipping and delivery of Orders in your Composable Commerce Project.

Shipping versus Delivery

We differentiate conceptually between the shipping addresses of the Cart and the delivery addresses of the Order.

  • The shipping addresses captured during checkout represent the request of the customer as to where the individual items should be shipped.
  • The delivery information captured for the Order represent how the Order is actually fulfilled.

Therefore, the delivery information is not automatically set on the Order based on which shipping addresses are set on the Cart. To map a shipping address to delivery information, use the Add Delivery update action.

Shipping addresses

If you are using the default ShippingMode Single, you must set a shippingAddress for the Cart before it can be converted into an Order.

The address stored in the shippingAddress field of the Cart determines the following:

  • The Shipping Methods that are available and their shipping rates
  • The Tax Rate applied to each (Custom) Line Item and the shipping rate

For more information on how Composable Commerce calculates tax using the shippingAddress field, see Cart tax rate selection.

Ship to a single address

To ship all (Custom) Line Items of the Cart to the same address using the same fulfillment method, use a single Shipping Method.

To ship all (Custom) Line Items of the Cart to the same address, using more than one fulfillment method, use multiple Shipping Methods.

Ship to multiple addresses

To ship individual items to different addresses while using a single Shipping Method, set the Cart's ShippingMode to Single on CartDraft. Once set, the ShippingMode field can not be changed.

The shippingAddress field of the Cart is used for taxation purposes and must be set in the CartDraft or with the Set Shipping Address update action.

Any address that is bound to a Line Item or sub-quantity of a Line Item must be added to the itemShippingAddresses field, which contains the complete set of addresses available for use by the Cart.

If a Line Item, or quantity of a Line Item is associated with an address listed in itemShippingAddresses, this address can not be deleted. To delete the address, you must first update the Line Item shipping details and remove the reference.

Each address that you provide must have a key that is unique to the Cart. The key is required when assigning the respective shipping address to a Line Item in the ItemShippingTarget (used with the Set LineItem ShippingDetails update action).

Shipping sub-quantities to different addresses

You can also ship sub-quantities of a Line Item to different addresses.

For example, if you have a Cart that contains 100 paper bags that must be shipped to three point-of-sale locations, you can specify the sub-quantities of the LineItem quantity for each address.

Shipping addressSub-quantity
address_110
address_240
address_350
Example Line Item with sub-quantities delivered to multiple shipping addressesjson
{
"id": "e38a6110-fc74-4095-bde5-9898375e6904",
"productId": "ed7f5333-6f5d-4d07-a44f-2a24885bae0c",
"name": {
"en": "Branded paper bag"
},
"variant": {
"id": 1,
"sku": "sku_4002"
},
"price": {
"value": {
"currencyCode": "USD",
"centAmount": 4200
},
"id": "278af989-688a-4b60-a26f-bee2a2e40920"
},
"quantity": 100,
"priceMode": "Platform",
"totalPrice": {
"currencyCode": "USD",
"centAmount": 630000
},
"lineItemMode": "Standard",
"shippingDetails": {
"targets": [
{
"addressKey": "address_1",
"quantity": 10
},
{
"addressKey": "address_2",
"quantity": 40
},
{
"addressKey": "address_3",
"quantity": 50
}
],
"valid": true
}
}

When you set the Line Item shipping address, there is no enforcement that the sum of the shipping address quantities equals the LineItem quantity. This allows the shipping addresses to be gathered and added to the Cart in a piecemeal way. However, to ensure data integrity, a boolean field called valid exists to determine whether the sum of the shipping address quantities equal the LineItem quantity.

A Cart is still considered valid even if valid is false. However, during Order creation, all valid flags must be true, otherwise the Order creation will be rejected.

To learn more, see our tutorial about multiple shipping addresses.

Shipping Methods

Shipping Methods model the fulfillment option that delivers your goods to the customer. For example, this could include shipping services like standard postal service, express delivery, or other options such as in-store collection.

You can define a default Shipping Method for a Project by setting the isDefault boolean inside an individual Shipping Method. During the checkout process, you can check whether an available Shipping Method has isDefault set to true, and if so, pre-select the option for the Customer.

You can set the shipping rates and the geographical area(s) covered by a Shipping Method using Zones.

Single Shipping Method

To ship all of the items in the Cart using a single Shipping Method, and therefore also the same tax rate selection criteria, set the Cart's ShippingMode to Single on CartDraft. Once set, the ShippingMode field can not be changed.

When using ShippingMode Single, tax is calculated and applied to the contents of the Cart based on the address in the shippingAddress field.

Multiple Shipping Methods

To ship individual items of an Order using different Shipping Methods, use ShippingMode Multiple on CartDraft. For example, a customer wants to collect some items in person and have the rest sent by express delivery.

To add and assign Shipping Methods, do the following:

  1. Specify any shipping addresses to be used by the Line Items in your Cart. For new Carts, you can specify addresses in the itemShippingAddresses field on CartDraft. For existing Carts, you can use the Add ItemShippingAddress update action, which adds the addresses to the itemShippingAddresses field. The itemShippingAddresses field is the complete set of addresses available for use by the Cart.

  2. Use the Add Shipping Method or Add Custom Shipping Method (for externally managed Shipping Methods) update action to add Shipping Methods to a Cart. In the update action, you need to specify a shippingAddress for the Shipping Method. We recommend that you provide a key for the shippingAddress that matches the key of the corresponding address listed in itemShippingAddresses. The shippingAddress is used later to calculate tax for any associated (Custom) Line Item(s), or sub-quantities of a (Custom) Line Item.

Both internal and external (outside Composable Commerce) Shipping Methods can coexist in a single Cart.
  1. Assign a Shipping Method to each Line Item using the Set LineItemShippingDetails update action.

You can also ship items (or sub-quantities of an item) to different addresses located in other states, countries, or regions using multiple Shipping Methods, however, the following applies:

  • The LineItem's or CustomLineItem's perMethodTaxRate field contains the individual Tax Rates applied within a single Line Item together with the Shipping Methods assigned to it. This field is equivalent to the taxRate field when using the default ShippingMode Single.
  • The LineItem's or CustomLineItem's taxedPricePortions field contains individual taxed prices of each Shipping Method. This is automatically calculated when perMethodTaxRate is set.

To learn more, see our multiple Shipping Methods tutorial and our Shipping Methods self-learning module.

Predicates

Predicates allow you define rule-based logic to determine which Shipping Methods are eligible for a Cart during checkout. To do this, add your predicate text to the predicate field directly on each Shipping Method.

For example:

  • Shipping Method "Express" should only be offered for Carts with Line Items that are eligible for express shipping.
  • Shipping Method "Overnight" should not be offered to a certain segment of the customers.
  • Shipping Method "Ground" is the only method available for Carts with bulky items weighing more than 10 kg.
Predicate examplesjson
// matches a cart when at least one Line Item has the custom field attribute "eligible_for_express_shipping" set to TRUE
lineItemExists(attributes.eligible_for_express_shipping = true)
// matches a cart for all customer group except one
customerGroup.id != "f6a19a23-14e3-40d0-aee2-3e612fcb1bc7"
// matches a cart when at least one Line Item has the custom field attribute "bulky" set to TRUE and when at least one Line Item has the custom field attribute "weightInKilograms" set to a value greater than 10
lineItemExists(attributes.bulky = true) and lineItemExists(attributes.weightInKilograms > 10)

Shipping predicates take into account the entire scope of the Cart, regardless of associations to Line Items. For example, a Shipping Method with a predicate totalPrice > "100.00 USD" will be applicable even if only $10 worth of goods is associated with it, so long as total Cart price satisfies the predicate. Similarly, this also applies to the Shipping Method's freeAbove price.

The predicate language contains a list of logical operators and functions that can be used to express the conditions of a Shipping Method rule.

The evaluation of each predicate occurs during checkout, when you call Get ShippingMethods for a Cart. This method retrieves only the Shipping Methods which are valid, based on the rules of the predicate, for a particular Cart.

If you use the Set ShippingMethod update action with a Shipping Method that does not match the conditions of the Cart, the call will be perceived as an invalid operation and be rejected.

If the Cart is updated and its conditions no longer match the criteria of the selected Shipping Methods, the parameter shippingMethodState found under the Cart's ShippingInfo changes from MatchesCart to DoesNotMatchCart. If you attempt to create an Order from a Cart that has ShippingMethodState with DoesNotMatchCart, the Order creation will be rejected.

Shipping Rates

A shipping rate is the price that you charge customers for a Shipping Method. Shipping rates are defined in the Shipping Method's Zones.

Fixed shipping rates

A fixed shipping rate is a rate assigned to a Shipping Method that never changes, even if the content or the conditions of a Cart is modified.

Tiered shipping rates

The alternative to fixed shipping rates is tiered shipping rates. This allows you to set shipping rates that increase or decrease, based on the tiers that you define. For example, you might want the shipping rate to decrease based on the Cart value, meaning the more money the customer is spending, the cheaper the shipping becomes.

You can enable tiered shipping rates by setting the optional parameter ShippingRateInputType in Project Settings.

The ShippingRateInputType parameter requires one of three ShippingRatePriceTiers:

  • CartValueType: the shipping rate maps to the sum of all Line Item totals and Custom Line Item totals (after discounts have been applied).
  • CartClassificationType: the shipping rate maps to an abstract Cart categorization expressed through a string (for example, Light, Medium, Heavy).
  • CartScoreType: the shipping rate maps to an abstract Cart categorization expressed through an integer (for example, a cart score or weight range).

When you create a Cart, you can set the parameter shippingRateInput on CartDraft which is used as look-up value to determine the shipping rate according to the defined tiers. If no value is set, or there is no tier for the value, the default shipping rate is used. An exception to this is when the ShippingRateInputType is set to CartValueType. In this case, the shipping rate is determined by the sum of all Line Item totals and Custom Line Item totals (via the totalPrice field) after discounts have been applied.

Defining shipping tiers

After you set the ShippingRateInputType parameter, specify the tiers and the shipping rate they should map to. To do this, define the array called tiers within the ShippingRate object.

The following examples illustrate tiered shipping rates for each input type.

CartValueType

In this example, the shipping rate gradually decreases until it becomes free of charge when the Cart value exceeds $100.

Shipping Rate TierShipping Rate
Default$4
> $50$3
> $75$2
> $100$0

CartClassificationType

In this example, if you don't provide a classification for a given Cart during checkout, the shipping rate defaults to $10. If you classify the Cart as Medium, the shipping rate is $25.

Shipping Rate TierShipping Rate
Default$10
Medium$25
Heavy$50

CartScoreType

In this example, the score represents the total weight of the Cart expressed in grams. A Cart with a combined weight of 50 grams or less, will have a shipping rate of $1.75. As the weight increases, the shipping rate increases.

Shipping Rate TierShipping Rate
Default$1.75
> 50$2.50
> 100$4.75
> 500$7.25
> 1000$10.50

In the following example, we'll use CartScoreType again, but we'll express the shipping rate as a linear PriceFunction. When a score is 35 or less, the shipping rate increases in set intervals. For scores higher than 35, the shipping rate is calculated based on the defined function. For example, a cart score of 40 results in a shipping rate of $10.

Shipping Rate TierShipping Rate
Default$2
> 5$3
> 15$6
> 25$8
> 35x - 30

Free shipping

To offer free shipping, use one of the following methods:

Free above: This option creates the discount at the Shipping Method level. This means that each Shipping Method can have a unique threshold amount. This is useful when you have multiple Shipping Methods with different cost structures. For example, if you have a Shipping Method for Express shipping, you can define a higher threshold amount since the costs are higher.

The Free above option is only available with fixed shipping rates.

To enable this option, set a freeAbove value on ShippingRateDraft. Alternately, you can set this value inside individual Shipping Methods using the Merchant Center.

Cart discounts: This option applies the same free shipping threshold amount across all Shipping Methods by default. However, it is possible to restrict a Cart Discount to only certain Shipping Methods using Cart Predicates. To use this method, set the target property of the CartDiscountDraft to CartDiscountShippingCostTarget.

We strongly recommend that you choose only one of these methods and not use both at the same time.

Shipping rate calculation

The shipping rate is calculated when at least one of the following occurs:

Tax calculation

The TaxMode of the Cart determines how Composable Commerce applies tax.

Platform tax mode

When only one Shipping Method is used on the Cart, the address specified in the Cart's shippingAddress field is used for determining the eligible Shipping Methods and their shipping rates, as well as the tax rates that are applied to (Custom) Line Items and shipping rate.

When a Cart contains multiple Shipping Methods, its taxedShippingPrice field represents the sum of taxed prices across all Shipping Methods.

Individual Shipping Method prices are contained within their respective ShippingInfo objects under shipping.

External tax mode

TaxModes External and ExternalAmount require the tax rate/amount to be manually set on each (Custom) Line Item and Shipping Method.

This requirement also applies to Carts with ShippingMode Multiple, with the added constraint that the rates/amounts must be present for each Shipping Method associated with a given (Custom) Line Item. Update actions SetLineItemTaxRate, SetLineItemTaxAmount, SetCustomLineItemTaxRate, and SetCustomLineItemTaxAmount contain a shippingKey parameter that you can use to define which method/address combination the rate is referring.