Cart Service Tutorials
How to create a new cart
To create a new cart, you need to send a request to theHow to add custom attributes to a cart
You can define custom attributes for a cart throughmixins
.Define your custom attributes schema
First, define your custom attributes schema in the form of a JSON schema.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"cartInstructions": {
"type": "object",
"properties": {
"instruction": {
"type": "string"
}
}
}
}
}
Upload your schema to a hosting service and save its URL
Update a cart with custom attributes
To add custom attributes to a cart, you need to send a request to theHow to merge carts
info
To learn more about merging carts, check out Cart merging in the Carts guide.
cartId
path parameter and the anonymous cart's ID in the request body.How to source pricing information from an external price calculation tool
For B2B scenarios, you might want to integrate an external application for price calculation for your products. Usually, the systems, such as ERPs, store all the relevant customer-specific pricing information needed for customer-specific pricing. The external system then can communicate with the Cart Service directly to overwrite the price of the product added to the cart.
info
To achieve the communication between Commerce Engine and the external pricing tool, you have to configure both systems accordingly. The steps required for such a case are described in the External Products, Pricing and Fees documentation. You need to generate a dedicated scope that serves as the authorization token for the API calls.
cartId
path parameter."itemType": "EXTERNAL"
definition which allows the Cart Service to overwrite the pricing from Commerce Engine. The payload must include the price and tax information.warning
When you have enabled external pricing, it's essential to ensure the accuracy of the prices, as CE does not perform price validation in these instances.
How to add a product from an external source to a cart
For some cases, you might want to allow adding products from an external system to cart, and not only from your online store. The products from external product management sources can be added directly to the customer's cart, bypassing the standard product catalog.
info
To achieve the communication between Commerce Engine and the external product management tool, you have to configure both systems accordingly. The steps required for such a case are described in the External Products, Pricing and Fees documentation. You need to generate a dedicated scope that serves as the authorization token for the API calls.
cartId
path parameter. The payload has to include the "itemType" : "EXTERNAL"
parameter, as well as the price and tax information.How to add an external fee
For some cases, you might need to calculate and charge additional fees, for example for packaging, freight, or any additional reasons. The fees calculated externally can be added directly to the customer's cart.
info
To achieve the communication between Commerce Engine and the fee management tool, you have to configure both systems accordingly. The steps required for such a case are described in the External Products, Pricing and Fees documentation. You need to generate a dedicated scope that serves as the authorization token for the API calls.
cartId
path parameter. Custom fee can be configured both for EXTERNAL and INTERNAL products, the payload should include the "itemType" : "EXTERNAL"
or "itemType" : "INTERNAL"
parameter. If the parameter is not provided, then "INTERNAL"
is taken as default.How to apply an external discount on an item level
Adding an external discount to an item in a cart is done with thecart.cart_manage_external_prices
scope. Use the externalDiscounts
attribute when adding an item to the cart or updating an existing one.Pricing calculations
To ensure that both net and gross prices are available, along with clear details on how these values are derived, the Cart Service includes the calculatedPrice field.
At the item level, there's acalculatedPrice
attribute, which contains detailed price calculations for a specific item. Additionally, a calculatedPrice
is also available at the cart level, summarizing the price calculations for all items in the cart.info
See the item level calculation payload example
"calculatedPrice" : {
"price" : {
"netValue" : 100.0,
"grossValue" : 110.0,
"taxValue" : 10.0,
"taxCode" : "STANDARD",
"taxRate" : 10.0
},
"upliftValue" : {
"netValue" : 30.0,
"grossValue" : 33.0,
"taxValue" : 3.0,
"taxCode" : "STANDARD",
"taxRate" : 10.0
},
"discountedPrice" : {
"netValue" : 90.0,
"grossValue" : 99.0,
"taxValue" : 9.0,
"taxCode" : "STANDARD",
"taxRate" : 10.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 10.0,
"discountType" : "PERCENT"
} ]
},
"fees" : [ {
"id" : "6793753e7d4bba47e2a99801",
"type" : "ABSOLUTE",
"origin": "EXTERNAL",
"name" : {
"en" : "Freight Fee"
},
"price" : {
"netValue" : 5.0,
"grossValue" : 5.0,
"taxValue" : 0
},
"discountedPrice" : {
"netValue" : 4.5,
"grossValue" : 4.5,
"taxValue" : 0.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 0.5,
"discountType" : "PERCENT"
} ]
}
} ],
"totalFee" : {
"netValue" : 4.5,
"grossValue" : 4.5,
"taxValue" : 0.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 0.5,
"discountType" : "PERCENT"
} ]
},
"totalDiscount" : {
"calculationType" : "ApplyDiscountBeforeTax",
"value" : 10.5,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 10.5,
"discountType" : "PERCENT"
} ]
},
"finalPrice" : {
"netValue" : 94.5,
"grossValue" : 103.5,
"taxValue" : 9.0
}
}
See the cart level calculation payload example
"calculatedPrice" : {
"price" : {
"netValue" : 100.0,
"grossValue" : 110.0,
"taxValue" : 10.0,
"taxCode" : "STANDARD",
"taxRate" : 10.0
},
"upliftValue" : {
"netValue" : 30.0,
"grossValue" : 33.0,
"taxValue" : 3.0,
"taxCode" : "STANDARD",
"taxRate" : 10.0
},
"discountedPrice" : {
"netValue" : 90.0,
"grossValue" : 99.0,
"taxValue" : 9.0,
"taxCode" : "STANDARD",
"taxRate" : 10.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 10.0,
"discountType" : "PERCENT"
} ]
},
"totalFee" : {
"netValue" : 4.5,
"grossValue" : 4.5,
"taxValue" : 0.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 0.5,
"discountType" : "PERCENT"
} ]
},
"totalDiscount" : {
"calculationType" : "ApplyDiscountBeforeTax",
"value" : 11.22,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 11.22,
"discountType" : "PERCENT"
} ]
},
"totalShipping" : {
"netValue" : 6.5,
"grossValue" : 6.955,
"taxValue" : 0.455,
"taxCode" : "REDUCED",
"taxRate" : 7.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 0.72,
"discountType" : "PERCENT"
} ]
},
"finalPrice" : {
"netValue" : 101.0,
"grossValue" : 110.455,
"taxValue" : 9.455,
"taxAggregate":
"lines": [
{
"netValue" : 96.5,
"grossValue" : 103.26,
"taxValue" : 6.76,
"taxCode" : "REDUCED",
"taxRate" : 7.0
},
{
"netValue" : 263.19,
"grossValue" : 313.2,
"taxValue" : 50.01,
"taxCode" : "STANDARD",
"taxRate" : 19.0
},
{
"netValue" : 9.0,
"grossValue" : 9.0,
"taxValue" : 0.0
}
]
}
}
This calculation method provides a comprehensive breakdown of prices, including net values, gross values, tax details, fees, and discounts, both at the cart level and for individual line items.
info
See the full payload example
{
"id" : "67b73cf5e4081e623d81fa47",
"yrn" : "urn:yaas:hybris:cart:cart:b2b2cstage;67b73cf5e4081e623d81fa47",
"customerId" : "45620894",
"currency" : "EUR",
"siteCode" : "GrossSite",
"type" : "shopping",
"channel" : {
"name" : "storefront",
"source" : "https://your-storefront.com/"
},
"items" : [ {
"id" : "0",
"type" : "INTERNAL",
"itemYrn" : "urn:yaas:saasag:caasproduct:product:b2b2cstage;samsung-galaxy-s27-gross",
"quantity" : 2.0,
"effectiveQuantity" : 2.0,
"unitPrice" : {
"netValue" : 46.22,
"grossValue" : 55.0,
"taxValue" : 8.78,
"taxCode" : "STANDARD",
"taxRate" : 19.0
},
"couponDiscounts" : [ {
"couponId" : "LS10PTOTAL",
"value" : 11.0
} ],
"calculatedPrice" : {
"price" : {
"netValue" : 92.44,
"grossValue" : 110.0,
"taxValue" : 17.56,
"taxCode" : "STANDARD",
"taxRate" : 19.0
},
"discountedPrice" : {
"netValue" : 83.19,
"grossValue" : 99.0,
"taxValue" : 15.81,
"taxCode" : "STANDARD",
"taxRate" : 19.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 11.0,
"discountType" : "PERCENT"
} ]
},
"totalDiscount" : {
"calculationType" : "ApplyDiscountAfterTax",
"value" : 11.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 11.0,
"discountType" : "PERCENT"
} ]
},
"finalPrice" : {
"netValue" : 83.19,
"grossValue" : 99.0,
"taxValue" : 15.81,
"taxCode" : "STANDARD",
"taxRate" : 19.0
}
}
}, {
"id" : "1",
"type" : "EXTERNAL",
"itemYrn" : "urn:yaas:saasag:caasproduct:product:b2b2cstage;samsung-galaxy-s24-gross",
"quantity" : 1.0,
"effectiveQuantity" : 1.0,
"couponDiscounts" : [ {
"couponId" : "LS10PTOTAL",
"value" : 11.2
} ],
"calculatedPrice" : {
"price" : {
"netValue" : 100.0,
"grossValue" : 107.0,
"taxValue" : 7.0,
"taxCode" : "REDUCED",
"taxRate" : 7.0
},
"upliftValue" : {
"netValue" : 30.0,
"grossValue" : 32.1,
"taxValue" : 2.1,
"taxCode" : "REDUCED",
"taxRate" : 7.0
},
"discountedPrice" : {
"netValue" : 90.0,
"grossValue" : 96.3,
"taxValue" : 6.3,
"taxCode" : "REDUCED",
"taxRate" : 7.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 10.7,
"discountType" : "PERCENT"
} ]
},
"fees" : [ {
"id" : "67b73d01e4081e623d81fa48",
"type" : "ABSOLUTE",
"origin" : "EXTERNAL",
"name" : {
"en" : "Freight Fee"
},
"price" : {
"netValue" : 5.0,
"grossValue" : 5.0,
"taxValue" : 0.0
},
"discountedPrice" : {
"netValue" : 4.5,
"grossValue" : 4.5,
"taxValue" : 0.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 0.5,
"discountType" : "PERCENT"
} ]
}
} ],
"totalFee" : {
"netValue" : 4.5,
"grossValue" : 4.5,
"taxValue" : 0.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 0.5,
"discountType" : "PERCENT"
} ]
},
"totalDiscount" : {
"calculationType" : "ApplyDiscountAfterTax",
"value" : 11.2,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 11.2,
"discountType" : "PERCENT"
} ]
},
"finalPrice" : {
"netValue" : 94.5,
"grossValue" : 100.8,
"taxValue" : 6.3
}
}
}, {
"id" : "2",
"type" : "EXTERNAL",
"product" : {
"id" : "myTestId",
"sku" : "sku",
"name" : "myExternalProduct",
"description" : "testExternalProduct",
"images" : [ {
"id" : "imageid",
"url" : "imageURL"
} ]
},
"quantity" : 2.0,
"effectiveQuantity" : 2.0,
"unitPrice" : {
"netValue" : 100.0,
"grossValue" : 119.0,
"taxValue" : 19.0,
"taxCode" : "STANDARD",
"taxRate" : 19.0
},
"couponDiscounts" : [ {
"couponId" : "LS10PTOTAL",
"value" : 24.3
} ],
"calculatedPrice" : {
"price" : {
"netValue" : 200.0,
"grossValue" : 238.0,
"taxValue" : 38.0,
"taxCode" : "STANDARD",
"taxRate" : 19.0
},
"discountedPrice" : {
"netValue" : 180.0,
"grossValue" : 214.2,
"taxValue" : 34.2,
"taxCode" : "STANDARD",
"taxRate" : 19.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 23.8,
"discountType" : "PERCENT"
} ]
},
"fees" : [ {
"id" : "67b73d04e4081e623d81fa49",
"type" : "ABSOLUTE",
"origin" : "EXTERNAL",
"name" : {
"en" : "Freight Fee"
},
"price" : {
"netValue" : 5.0,
"grossValue" : 5.0,
"taxValue" : 0.0
},
"discountedPrice" : {
"netValue" : 4.5,
"grossValue" : 4.5,
"taxValue" : 0.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 0.5,
"discountType" : "PERCENT"
} ]
}
} ],
"totalFee" : {
"netValue" : 4.5,
"grossValue" : 4.5,
"taxValue" : 0.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 0.5,
"discountType" : "PERCENT"
} ]
},
"totalDiscount" : {
"calculationType" : "ApplyDiscountAfterTax",
"value" : 24.3,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 24.3,
"discountType" : "PERCENT"
} ]
},
"finalPrice" : {
"netValue" : 184.5,
"grossValue" : 218.7,
"taxValue" : 34.2
}
}
} ],
"discounts" : [ {
"id" : "0",
"code" : "LS10PTOTAL",
"currency" : "EUR",
"discountRate" : 10.0,
"name" : "LS10PTOTAL",
"calculationType" : "ApplyDiscountBeforeTax",
"valid" : true,
"links" : [ {
"rel" : "validate",
"title" : "Coupon Validation",
"href" : "https://api-stage.emporix.io/caas-coupon/b2b2cstage/coupons/LS10PTOTAL/validation",
"type" : "application/json"
}, {
"rel" : "redeem",
"title" : "Coupon Redemption",
"href" : "https://api-stage.emporix.io/caas-coupon/b2b2cstage/coupons/LS10PTOTAL/redemptions",
"type" : "application/json"
} ],
"discountType" : "PERCENT",
"discountCalculationType" : "TOTAL",
"categoryRestricted" : false
} ],
"totalUnitsCount" : 5.0,
"metadata" : {
"createdAt" : "2025-02-20T14:32:45.290134Z",
"modifiedAt" : "2025-02-20T14:32:45.290155Z",
"version" : 3
},
"totalTax" : {
"amount" : 0.0,
"currency" : "EUR"
},
"leadTime" : 0,
"calculatedPrice" : {
"price" : {
"netValue" : 392.44,
"grossValue" : 455.0,
"taxValue" : 62.56
},
"upliftValue" : {
"netValue" : 30.0,
"grossValue" : 32.1,
"taxValue" : 2.1,
"taxCode" : "REDUCED",
"taxRate" : 7.0
},
"discountedPrice" : {
"netValue" : 353.19,
"grossValue" : 409.5,
"taxValue" : 56.31,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 45.5,
"discountType" : "PERCENT"
} ]
},
"totalFee" : {
"netValue" : 9.0,
"grossValue" : 9.0,
"taxValue" : 0.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 1.0,
"discountType" : "PERCENT"
} ]
},
"totalDiscount" : {
"calculationType" : "ApplyDiscountAfterTax",
"value" : 47.27,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 47.27,
"discountType" : "PERCENT"
} ]
},
"totalShipping" : {
"netValue" : 6.5,
"grossValue" : 6.96,
"taxValue" : 0.46,
"taxCode" : "REDUCED",
"taxRate" : 7.0,
"appliedDiscounts" : [ {
"id" : "LS10PTOTAL",
"value" : 0.77,
"discountType" : "PERCENT"
} ]
},
"finalPrice" : {
"netValue" : 368.69,
"grossValue" : 425.46,
"taxValue" : 56.77,
"taxAggregate" : {
"lines" : [ {
"netValue" : 96.5,
"grossValue" : 103.26,
"taxValue" : 6.76,
"taxCode" : "REDUCED",
"taxRate" : 7.0
}, {
"netValue" : 263.19,
"grossValue" : 313.2,
"taxValue" : 50.01,
"taxCode" : "STANDARD",
"taxRate" : 19.0
}, {
"netValue" : 9.0,
"grossValue" : 9.0,
"taxValue" : 0.0
} ]
}
}
}
}
Pricing calculations glossary
Calculated price on item level
Term | Definition |
---|---|
price | A unit price from priceMatch , it's multiplied by item quantity.
|
upliftValue | An additional amount authorized for payment to cover potential price adjustments during packing of weight-based products. There are two conditions to have this value for an item line:
|
discountedPrice | The price of the line item is calculated as unit price × quantity, with any applied discounts. If no discounts are applied to a given line item, this attribute is not included in the response. Depending on the site configuration, the includesTax attribute can be true or false . The discount is applied to price.grossValue when includesTax=true or price.netValue when includesTax=false . Based on this, the corresponding netValue or grossValue is recalculated using the taxRate . The calculation method that was used is indicated in totalDiscount.calculationType , which can be either ApplyDiscountAfterTax or ApplyDiscountBeforeTax .
|
totalDiscount | A summary of all discounts applied to the line, including discounts on both the line item's price and its fees. If there are no discounts applied on the line item, it's not returned in the response.
|
fees | A list of fees applied to the line item. If there are no fees on the line item, it's not returned in the response.
|
totalFee | Sum of all fees applied to the line item. It's calculated by summarizing fees[].discountedPrice if any discounts were applied to the fee, or fees[].price for a a not discounted fee.
|
calculationType | Indicates whether discounts were applied to net or gross values.
|
finalPrice | The final price is the sum of the discountedPrice or the original price, depending on whether any discounts were applied to the line item, and the totalFee , which includes all fees applied to the line item.
|
Calculated price on cart level
Term | Definition |
---|---|
price | A sum of all line item prices without discounts.
|
discountedPrice | The sum of all line item prices after discounts. This attribute is included in the response if at least one line item has a discounted price. It represents the total of discounted prices for line items with discounts applied, or the regular prices for line items without discounts. Ultimately, it reflects the total cost of all line items after discounts.
|
totalShipping | The calculated shipping cost. It takes the sum of items[].calculatedPrice.price.grossValue for shipping estimation.
|
paymentFees | A list of payment fees applied to an order. This field is only available after checkout, as payment is not processed in the shopping cart. Payment fees are not discounted even if discount/coupon is set to TOTAL. |
totalDiscount | A summary of all discounts. It's the sum of all lines[].totalDiscount and shipping discounts.
|
finalPrice | The final price is the sum of items[].finalPrice , totalShipping and paymentFee .
|
taxAggregate - lines | A list of tax values grouped by taxCode and taxRate . It includes the sum of item[].calculatedPrice.discountedPrice or item[].calculatedPrice.price , item[].calculatedPrice.fees[].discountedPrice or item[].calculatedPrice.fees[].price , calculatedPrice.totalShipping and calculatedPrice.paymentFees . If any of these values have the same taxRate but different taxCode , they are listed separately. The aggregation also includes items that do not have a taxRate or taxCode defined.
|
See the sections below for shipping, payment fee, tax and discounts calculations.
How is shipping calculated
The shipping calculation depends on the stage at which it is done.
- In the cart, where the address, delivery method, and zone are not available yet, the calculation uses the minimum shipping estimation. At this stage,
sites.homeBase.Address
is used as theshipFromAddress
, and theshipToAddress
is created based on the cart’scountryCode
andzipCode
. See the Calculating the minimum shipping costs endpoint. - In the checkout, where information about the delivery window and zone is already available, the calculation uses the following endpoints: Calculating the final shipping cost, or Calculating the shipping cost for a given slot accordingly.
warning
homeBase.address
has the country
and zip-code
information included. It's mandatory for shipping calculations.How to calculate a payment fee at cart level
At the cart level, only one additional fee is calculated, apart from the fees applied at the item level. ThepaymentFees
is an additional, non-discountable amount that the customer must pay for using a given payment method.The fee has a specific format, and there are two options for calculating it:
- ABSOLUTE - the value of defined fee’s attribute
feeAbsolute.amount
, where the amount is treated asnetValue
. - PERCENT - the fee is calculated as a percentage of the total net value of all item lines'
finalPrice.netValue
, plus the cart’scalculatedPrice.totalShipping.netValue
. The fee is specified by thefeePercentage
attribute.
grossValue
is equal to netValue
.How to determine a tax country at cart level
Since the shipping address is not set in the cart, you need to determine the country to find thetaxRate
for a fee that has a taxCode
only.
Ways to find the country data:- Use the country code that is set on the cart
- If the cart has a customer, check the customer addresses, based on site’s setting
taxDeterminationBasedOn
:- SHIPPING_ADDRESS - use the address that is tagged with
SHIPPING
, select the default address or the first match. - BILLING_ADDRESS - use the address that is tagged with
BILLING
, select the default address or the first match. If the matching address is not found, return an error.
- SHIPPING_ADDRESS - use the address that is tagged with
- Get country code from site’s
homeBase.address.country
.
How to apply discounts at cart level
Discounts are known as coupons and, with the relevant settings that influencecalculatedPrice
, they can be applied to a cart.Depending on the site configuration and the
includesTax=true/false
, the discount is applied to either the gross value - includesTax=true
, or the net value - includesTax=false
.
Based on this setting, the corresponding netValue
or grossValue
is recalculated using the tax rate.The information about which calculation method was used is available in
totalDiscount.calculationType=ApplyDiscountAfterTax/ApplyDiscountBeforeTax
:discountCalculationType
:- SUBTOTAL - the discounts are applied on
items[].calculatedPrice.price
. The line item fees and shipping cost are NOT discounted. - TOTAL - the discounts are applied on
items[].calculatedPrice.price
, the line item fees and shipping cost.
- SUBTOTAL - the discounts are applied on
discountType
:- ABSOLUTE - a coupon that has a given type must have
discountAbsolute
attribute configured. It represents a monetary amount that should be discounted.
ApplyDiscountAfterTax/ApplyDiscountBeforeTax
discount, the absolute amount is subtracted either from thegrossValue
or thenetValue
. The value of the discount on the cart level is divided across all the applicable cart prices, proportionally to theitems[].calculatedPrice.price
,items[].calculatedPrice.fees[].price
and the calculated shipping cost. It's related to the difference betweendiscountCalculationType:SUBTOTAL/TOTAL
described above, to know which items are applicable.- PERCENT - it takes the value of discount’s
discountPercentage
attribute and calculates the percentage discount to the price. - FREE_SHIPPING - this type of a discount fully discounts the price of the
calculatedPrice.totalShipping
. It's applied before any other discount is applied.
- ABSOLUTE - a coupon that has a given type must have
categoryRestricted
- the discount applies only to the line items that belong to a specific category. If thediscountCalculationType=TOTAL
, a fee of an item that fulfills the restriction is discounted. However, any other fees, or shipping are not part of the discounting.
segmentRestricted
- the discount is applied only to the line items that belong to the given customer segment.
Since the system can be configured to allow more than one discount to a cart, it has a few implications:
- The
FREE_SHIPPING
discount is applied on the shipping first. - The rest of the discounts are applied based on the order the discounts were applied to the cart.
- Every PERCENT discount is calculated based on the original price, without applied discounts. Applying two coupons of 10% to 15.0 value results in 12.0 discounted price and two applied discounts of 1,5 value.
- Every ABSOLUTE discount uses the not discounted values for the discount value spread. It means that if the given applicable item is already fully discounted, the remaining amount of the discount is spread proportionally on the discounts that still have some value left.
info
Check the System Preferences documentation for coupons settings related to the number of discounts.
For some cases, you might need to calculate and charge additional fees, for example for packaging, freight, or any additional reasons. The fees calculated externally can be added directly to the customer's cart.
To achieve the communication between Commerce Engine and the fee management tool, you have to configure both systems accordingly. The steps required for such a case are described in the External Products, Pricing and Fees documentation. You need to generate a dedicated scope that serves as the authorization token for the API calls.
To add a custom fee to the cart, you need to send the request to the endpoint. Provide the customer cart's ID in the cartId path parameter. The payload has to include the "itemType" : "EXTERNAL" parameter - see the Adding a product to a cart documentation.
How to apply separation of the same line items in the cart
When you add an item to the cart, it's stored as a single line. If you add the same item multiple times, it remains a single line item, but thequantity
attribute is updated to reflect the total amount, for example when you add 5 items they are stored as item1: productA, qty:5
. If you need to add the same item multiple times on separate lines in the cart, use the
keepAsSeparateLineItem=true
flag - it ensures each instance of the item appears as a distinct line item. This can be useful in a variety of scenarios, such as applying different discounts or fees to the same product, or handling separate delivery options.A common use case is the Buy 2, Get 1 Free promotion. In this case, when a customer adds two of the same line items to the cart, the system can add a third instance as a separate line item marked as free.
Using thekeepAsSeparateLineItem=true
flag stores each addition of the product as an individual line, while the keepAsSeparateLineItem=false
keeps them all in one.By default, all items are grouped into a single line in the cart. This behavior is defined by
keepAsSeparateLineItem=false
. However, even if the keepAsSeparateLineItem
flag is not explicitly included in the payload, the system assumes this default behavior. In other words, unless stated otherwise, keepAsSeparateLineItem=false
is always applied.Adding the keepAsSeparateLineItem":true
flag to the payload example:
{
"itemYrn": "urn:yaas:saasag:caasproduct:product:b2b2cstage;samsung-galaxy-s24-gross",
"keepAsSeparateLineItem":true,
"price": {
"priceId": "679ca63dbcdefe5b380c98bc",
"effectiveAmount": 550,
"originalAmount": 550,
"currency": "EUR"
},
}
Usage examples
Adding multiple productA
items with the keepAsSeparateLineItem=true
flag:
- Adding the first
productA
item withkeepAsSeparateLineItem=true
results in:item0: productA, qty:1, keepAsSeparateLineItem=true
- Adding another
productA
item withkeepAsSeparateLineItem=true
results in:item0: productA, qty:1, keepAsSeparateLineItem=true item1: productA, qty:1, keepAsSeparateLineItem=true
Adding multiple productA
items with the keepAsSeparateLineItem=false
flag:
- Adding the first
productA
item withkeepAsSeparateLineItem=false
results in:item0: productA, qty:1, keepAsSeparateLineItem=false
- Adding another
productA
item withkeepAsSeparateLineItem=false
results in:item0: productA, qty:2, keepAsSeparateLineItem=false
Adding multiple productA
items with the keepAsSeparateLineItem=true
and keepAsSeparateLineItem=false
flags
- Adding the first
productA
item with two different flags results in:item0: productA, qty:1, keepAsSeparateLineItem=true item2: productA, qty:1, keepAsSeparateLineItem=false
- Adding another two
productA
items with different flags results in:item0: productA, qty:1, keepAsSeparateLineItem=true item1: productA, qty:1, keepAsSeparateLineItem=true item2: productA, qty:2, keepAsSeparateLineItem=false
Products with external prices
You can add external prices for both custom products and products from the internal catalog. Line items for the same product can have different prices if they’re added separately withkeepAsSeparateLineItem=true
.For example:
- Adding the first
productA
item withpriceX
andkeepAsSeparateLineItem=true
results in:item0: productA, external, priceX, qty:1, keepAsSeparateLineItem=true
- Adding another
productA
item to it, but withpriceY
andkeepAsSeparateLineItem=true
results in:item0: productA, external, priceX, qty:1, keepAsSeparateLineItem=true item1: productA, external, priceY, qty:1, keepAsSeparateLineItem=true
Products with standard prices
When using internal prices, thepriceId
is the same across all line items - if the product uses a standard price from the catalog, all lines for that item are expected to have the same price.For example:
- Adding the first
productA
item withpriceX
andkeepAsSeparateLineItem=true
results in:item0: productA, internal, priceX, qty:1, keepAsSeparateLineItem=true
- Adding another
productA
item with differentpriceY
andkeepAsSeparateLineItem=true
results in:item0: productA, internal, priceX, qty:1, keepAsSeparateLineItem=true item1: productA, internal, priceY, qty:1, keepAsSeparateLineItem=true
- If
cartItemValidationSkipExistingItemsValidationOnAddToCart=false
, the validation occurs, and an error is thrown due to the price mismatch. - If
cartItemValidationSkipExistingItemsValidationOnAddToCart=true
, the validation does not occur, and the cart accepts the new line item.warning
When the cart item validation is not executed onadd to cart
, you can use the cart validation endpoint. It should return errors informing that the prices are duplicated.EXTERNAL pricing products can have different prices in the cart, INTERNAL pricing products can't.
Adding products with internal and external pricing
When you add the same product first as an internal one and then as an external, the items are split into separate line items even ifkeepAsSeparateLineItem=false
, or if the flag is not present.- Adding
productA
item, with internalpriceX
andkeepAsSeparateLineItem=false
results in:item0: productA, internal, priceX, qty:1, keepAsSeparateLineItem=false
- Adding
productA
item to it, with externalpriceY
andkeepAsSeparateLineItem=false
results in:item0: productA, internal, priceX, qty:1, keepAsSeparateLineItem=false item0: productA, external, priceY, qty:1, keepAsSeparateLineItem=false