Working with baskets
A core part to the shopping experience using Norce Commerce Services is the Basket. This is the container to the list of items the visitor is interested in. The basket in Norce contains a lot of functionality and is dependent on many business rules that are evaluated and applied for every action the visitor does from your commerce application.
Aside from the most common use of the basket object (the cart), there is also other ways to use it. Like wish lists, approval/attests, saved for later, sent to punch out, subscriptions/recurring orders, etc. These functions are not addressed in this document.
- The full Basket Schema
- Check out the examples in Postman as well.
An example basket
{ "Id": 6600304, "CustomerId": null, "CompanyId": null, "SalesContactId": null, "StatusId": 3, "CurrencyId": 2, "CurrencyCode": "SEK", "Comment": null, "OrderReference": null, "DiscountCode": null, "ReferId": null, "ReferUrl": null, "ValidTo": null, "IsEditable": true, "Items": [ { "Id": 16030464, "LineNo": 1, "ParentLineNo": null, "ProductId": 31234584, "PartNo": "PRD0001270", "ManufacturerPartNo": "T540XP", "Name": "T540XP", "SubHeader": "<p>Detta är en kort beskrivning.</p>", "ThumbnailImage": "2/thumb_p31234584.jpg", "FlagIdSeed": "915,1884", "Type": 1, "PriceDisplay": 5743.20, "Price": 0.00, "PriceOriginal": 5743.20, "Cost": 5734.34, "VatRate": 1.2500, "Quantity": 1.000, "UOM": "st", "UOMCount": 1.000, "Comment": null, "PriceListId": 4654, "ReferId": null, "ReferUrl": null, "IsEditable": true, "IsDiscountable": true, "Info": [ { "TypeId": 209, "Value": "", "Code": "bit_size" }, { "TypeId": 241, "Value": "", "Code": "bit_del_time" }, { "TypeId": 95, "Value": "", "Code": "bit_additionalinformation" } ], "OptionalItems": [], "OnHandValue": 0.000, "IncomingValue": 0.000, "NextDeliveryDate": null, "LeadtimeDayCount": null, "PromotionIdSeed": "", "ImageKey": "39e4b7ec-12d8-4f6e-b9c1-cbd7334190e1", "ManufacturerName": "Husqvarna", "CategoryId": 41722, "OnHand": { "Value": 0.000, "IncomingValue": 0.000, "NextDeliveryDate": null, "LeadtimeDayCount": null, "LastChecked": null, "IsActive": false, "IsReturnable": true, "Info": null }, "OnHandSupplier": { "Value": 200.000, "IncomingValue": 0.000, "NextDeliveryDate": null, "LeadtimeDayCount": 7, "LastChecked": null, "IsActive": true, "IsReturnable": true, "Info": null }, "PriceRecommended": 7000.00, "ManufacturerId": 1685, "UniqueName": "t540xp", "StatusId": 1, "StockDisplayBreakPoint": null, "PriceCatalog": null, "IsBuyable": true, "SubDescription": null, "CategoryIdSeed": "41722", "RecommendedQuantity": 4.000, "IsRecommendedQuantityFixed": false, "AppliedPromotions": [], "RequirementPromotionIdSeed": "5093", "IsSubscribable": false, "DescriptionHeader": "Husqvarna T540XP", "IsPriceManual": false, "PriceStandard": 6375.20, "EanCode": "123123123123123", "CostUnit": 0.00, "PriceDisplayIncVat": 7179.00 }, { "Id": 16030465, "LineNo": 2, "ParentLineNo": null, "ProductId": 24706222, "PartNo": "PRD0001212", "ManufacturerPartNo": "FREIGHT01", "Name": "Freight", "SubHeader": null, "ThumbnailImage": null, "FlagIdSeed": "915", "Type": 3, "PriceDisplay": 0.00, "Price": 0.00, "PriceOriginal": 0.00, "Cost": 0.00, "VatRate": 1.25, "Quantity": 1.000, "UOM": "st", "UOMCount": 1.000, "Comment": null, "PriceListId": 1, "ReferId": null, "ReferUrl": null, "IsEditable": true, "IsDiscountable": true, "Info": [ { "TypeId": 209, "Value": "", "Code": "bit_size" }, { "TypeId": 241, "Value": "", "Code": "bit_del_time" }, { "TypeId": 95, "Value": "", "Code": "bit_additionalinformation" } ], "OptionalItems": [], "OnHandValue": 0.000, "IncomingValue": 0.000, "NextDeliveryDate": null, "LeadtimeDayCount": 0, "PromotionIdSeed": null, "ImageKey": null, "ManufacturerName": "Miscellaneous", "CategoryId": null, "OnHand": { "Value": 0.000, "IncomingValue": 0.000, "NextDeliveryDate": null, "LeadtimeDayCount": 0, "LastChecked": "/Date(1325504774807+0100)/", "IsActive": true, "IsReturnable": true, "Info": null }, "OnHandSupplier": { "Value": 0.000, "IncomingValue": 0.000, "NextDeliveryDate": null, "LeadtimeDayCount": null, "LastChecked": null, "IsActive": false, "IsReturnable": true, "Info": null }, "PriceRecommended": null, "ManufacturerId": 4335, "UniqueName": "freight", "StatusId": 1, "StockDisplayBreakPoint": null, "PriceCatalog": null, "IsBuyable": true, "SubDescription": null, "CategoryIdSeed": "", "RecommendedQuantity": 1.000, "IsRecommendedQuantityFixed": false, "AppliedPromotions": [], "RequirementPromotionIdSeed": null, "IsSubscribable": false, "DescriptionHeader": null, "IsPriceManual": false, "PriceStandard": 0.00, "EanCode": "", "CostUnit": 0.00, "PriceDisplayIncVat": 0.00 }, { "Id": 0, "LineNo": 3, "ParentLineNo": 1, "ProductId": 31234588, "PartNo": "PRD0001274", "ManufacturerPartNo": "Underhållskit", "Name": "Underhållskit Motorsåg", "SubHeader": null, "ThumbnailImage": "2/thumb_p31234588.png", "FlagIdSeed": "915", "Type": 1, "PriceDisplay": 111.20, "Price": 0.00, "PriceOriginal": 111.20, "Cost": 100.25, "VatRate": 1.25, "Quantity": 1, "UOM": "st", "UOMCount": 1.000, "Comment": null, "PriceListId": 1, "ReferId": null, "ReferUrl": null, "IsEditable": false, "IsDiscountable": true, "Info": [ { "TypeId": 209, "Value": "", "Code": "bit_size" }, { "TypeId": 241, "Value": "", "Code": "bit_del_time" }, { "TypeId": 95, "Value": "", "Code": "bit_additionalinformation" } ], "OptionalItems": [], "OnHandValue": 12.000, "IncomingValue": 0.000, "NextDeliveryDate": null, "LeadtimeDayCount": 0, "PromotionIdSeed": "", "ImageKey": null, "ManufacturerName": "Husqvarna", "CategoryId": 41722, "OnHand": { "Value": 12.000, "IncomingValue": 0.000, "NextDeliveryDate": null, "LeadtimeDayCount": 0, "LastChecked": null, "IsActive": true, "IsReturnable": true, "Info": null }, "OnHandSupplier": { "Value": 133.000, "IncomingValue": 0.000, "NextDeliveryDate": null, "LeadtimeDayCount": 5, "LastChecked": "/Date(1487085555163+0100)/", "IsActive": true, "IsReturnable": true, "Info": null }, "PriceRecommended": null, "ManufacturerId": 1685, "UniqueName": "underhallskit-motorsag", "StatusId": 1, "StockDisplayBreakPoint": null, "PriceCatalog": null, "IsBuyable": true, "SubDescription": null, "CategoryIdSeed": "41722", "RecommendedQuantity": 1.000, "IsRecommendedQuantityFixed": false, "AppliedPromotions": [], "RequirementPromotionIdSeed": "", "IsSubscribable": false, "DescriptionHeader": null, "IsPriceManual": false, "PriceStandard": 0.00, "EanCode": "345345345345345", "CostUnit": 0.00, "PriceDisplayIncVat": 139.00 } ], "Info": [ { "TypeId": 169, "Value": "", "Code": "bit_expecteddeliverydate" }, { "TypeId": 293, "Value": "", "Code": "bit_additionalorderinfo" }, { "TypeId": 445, "Value": "", "Code": "Norce_Gender" }, { "TypeId": 493, "Value": "", "Code": "recurring" } ], "Summary": { "Items": { "Amount": 5854.40, "Vat": 1463.60, "AmountIncVat": 7318.00 }, "Freigt": { "Amount": 0.00, "Vat": 0.00, "AmountIncVat": 0.00 }, "Fees": { "Amount": 0.00, "Vat": 0.00, "AmountIncVat": 0.00 }, "Total": { "Amount": 5854.40, "Vat": 1463.60, "AmountIncVat": 7318.00 } }, "AppliedPromotions": [ { "Id": 5093, "Name": "Add service", "Header": "", "ShortDescription": "", "Description1": "", "Description2": "", "StartDate": null, "EndDate": null, "ImageKey": null, "RequirementSeed": "3", "DiscountCode": null, "IsExcludedFromPriceCalculation": false, "AllowProductListing": false, "Images": [], "ProductFilters": [ { "ManufacturerId": null, "CategorySeed": null, "TypeId": null, "ProductId": null, "VariantProductId": null, "PartNo": "PRD0001274", "PricelistId": 1, "FlagId": null }, { "ManufacturerId": null, "CategorySeed": null, "TypeId": null, "ProductId": null, "VariantProductId": null, "PartNo": null, "PricelistId": null, "FlagId": 1884 } ], "AppliedAmount": 0.00, "EffectSeed": "5", "FreightDiscountPct": null, "IsStackable": true, "AppliedAmountIncVat": 0.00 } ], "IpAddress": "151.236.200.213", "AttestedBy": null, "TypeId": 1, "DoHold": false, "IsBuyable": true, "InvoiceReference": null, "PaymentMethodId": null, "DeliveryMethodId": 1, "SalesAreaId": 1 }
<Basket xmlns="Enferno.Services.Contracts.Expose.Shopping" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Id>6600304</Id> <CustomerId i:nil="true"/> <CompanyId i:nil="true"/> <SalesContactId i:nil="true"/> <StatusId>3</StatusId> <CurrencyId>2</CurrencyId> <CurrencyCode>SEK</CurrencyCode> <Comment i:nil="true"/> <OrderReference i:nil="true"/> <DiscountCode i:nil="true"/> <ReferId i:nil="true"/> <ReferUrl i:nil="true"/> <ValidTo i:nil="true"/> <IsEditable>true</IsEditable> <Items> <BasketItem> <Id>16030464</Id> <LineNo>1</LineNo> <ParentLineNo i:nil="true"/> <ProductId>31234584</ProductId> <PartNo>PRD0001270</PartNo> <ManufacturerPartNo>T540XP</ManufacturerPartNo> <Name>T540XP</Name> <SubHeader><p>Detta är en kort beskrivning.</p></SubHeader> <ThumbnailImage>2/thumb_p31234584.jpg</ThumbnailImage> <FlagIdSeed>915,1884</FlagIdSeed> <Type>1</Type> <PriceDisplay>5743.20</PriceDisplay> <Price>0.00</Price> <PriceOriginal>5743.20</PriceOriginal> <Cost>5734.34</Cost> <VatRate>1.25</VatRate> <Quantity>1</Quantity> <UOM>st</UOM> <UOMCount>1.000</UOMCount> <Comment i:nil="true"/> <PriceListId>4654</PriceListId> <ReferId i:nil="true"/> <ReferUrl i:nil="true"/> <IsEditable>true</IsEditable> <IsDiscountable>true</IsDiscountable> <Info> <Info> <TypeId>209</TypeId> <Value/> <Code>bit_size</Code> </Info> <Info> <TypeId>241</TypeId> <Value/> <Code>bit_del_time</Code> </Info> <Info> <TypeId>95</TypeId> <Value/> <Code>bit_additionalinformation</Code> </Info> </Info> <OptionalItems/> <OnHandValue>0.000</OnHandValue> <IncomingValue>0.000</IncomingValue> <NextDeliveryDate i:nil="true"/> <LeadtimeDayCount i:nil="true"/> <PromotionIdSeed/> <ImageKey>39e4b7ec-12d8-4f6e-b9c1-cbd7334190e1</ImageKey> <ManufacturerName>Husqvarna</ManufacturerName> <CategoryId>41722</CategoryId> <OnHand xmlns:a="Enferno.Services.Contracts.Expose.Products"> <a:Value>0.000</a:Value> <a:IncomingValue>0.000</a:IncomingValue> <a:NextDeliveryDate i:nil="true"/> <a:LeadtimeDayCount i:nil="true"/> <a:LastChecked i:nil="true"/> <a:IsActive>false</a:IsActive> <a:IsReturnable>true</a:IsReturnable> <a:Info i:nil="true" xmlns:b="Enferno.Services.Contracts.Expose"/> </OnHand> <OnHandSupplier xmlns:a="Enferno.Services.Contracts.Expose.Products"> <a:Value>200.000</a:Value> <a:IncomingValue>0.000</a:IncomingValue> <a:NextDeliveryDate i:nil="true"/> <a:LeadtimeDayCount>7</a:LeadtimeDayCount> <a:LastChecked i:nil="true"/> <a:IsActive>true</a:IsActive> <a:IsReturnable>true</a:IsReturnable> <a:Info i:nil="true" xmlns:b="Enferno.Services.Contracts.Expose"/> </OnHandSupplier> <PriceRecommended>7000.00</PriceRecommended> <ManufacturerId>1685</ManufacturerId> <UniqueName>t540xp</UniqueName> <StatusId>1</StatusId> <StockDisplayBreakPoint i:nil="true"/> <PriceCatalog i:nil="true"/> <IsBuyable>true</IsBuyable> <SubDescription i:nil="true"/> <CategoryIdSeed>41722</CategoryIdSeed> <RecommendedQuantity>4.000</RecommendedQuantity> <IsRecommendedQuantityFixed>false</IsRecommendedQuantityFixed> <AppliedPromotions/> <RequirementPromotionIdSeed>5093</RequirementPromotionIdSeed> <IsSubscribable>false</IsSubscribable> <DescriptionHeader>Husqvarna T540XP</DescriptionHeader> <IsPriceManual>false</IsPriceManual> <PriceStandard>6375.20</PriceStandard> <EanCode>123123123123123</EanCode> <CostUnit>0.00</CostUnit> <PriceDisplayIncVat>7179.00</PriceDisplayIncVat> </BasketItem> <BasketItem> <Id>16030465</Id> <LineNo>2</LineNo> <ParentLineNo i:nil="true"/> <ProductId>24706222</ProductId> <PartNo>PRD0001212</PartNo> <ManufacturerPartNo>FREIGHT01</ManufacturerPartNo> <Name>Freight</Name> <SubHeader i:nil="true"/> <ThumbnailImage i:nil="true"/> <FlagIdSeed>915</FlagIdSeed> <Type>3</Type> <PriceDisplay>0.00</PriceDisplay> <Price>0.00</Price> <PriceOriginal>0.00</PriceOriginal> <Cost>0.00</Cost> <VatRate>1.25</VatRate> <Quantity>1</Quantity> <UOM>st</UOM> <UOMCount>1.000</UOMCount> <Comment i:nil="true"/> <PriceListId>1</PriceListId> <ReferId i:nil="true"/> <ReferUrl i:nil="true"/> <IsEditable>true</IsEditable> <IsDiscountable>true</IsDiscountable> <Info> <Info> <TypeId>209</TypeId> <Value/> <Code>bit_size</Code> </Info> <Info> <TypeId>241</TypeId> <Value/> <Code>bit_del_time</Code> </Info> <Info> <TypeId>95</TypeId> <Value/> <Code>bit_additionalinformation</Code> </Info> </Info> <OptionalItems/> <OnHandValue>0.000</OnHandValue> <IncomingValue>0.000</IncomingValue> <NextDeliveryDate i:nil="true"/> <LeadtimeDayCount>0</LeadtimeDayCount> <PromotionIdSeed i:nil="true"/> <ImageKey i:nil="true"/> <ManufacturerName>Miscellaneous</ManufacturerName> <CategoryId i:nil="true"/> <OnHand xmlns:a="Enferno.Services.Contracts.Expose.Products"> <a:Value>0.000</a:Value> <a:IncomingValue>0.000</a:IncomingValue> <a:NextDeliveryDate i:nil="true"/> <a:LeadtimeDayCount>0</a:LeadtimeDayCount> <a:LastChecked>2012-01-02T12:46:14.807</a:LastChecked> <a:IsActive>true</a:IsActive> <a:IsReturnable>true</a:IsReturnable> <a:Info i:nil="true" xmlns:b="Enferno.Services.Contracts.Expose"/> </OnHand> <OnHandSupplier xmlns:a="Enferno.Services.Contracts.Expose.Products"> <a:Value>0.000</a:Value> <a:IncomingValue>0.000</a:IncomingValue> <a:NextDeliveryDate i:nil="true"/> <a:LeadtimeDayCount i:nil="true"/> <a:LastChecked i:nil="true"/> <a:IsActive>false</a:IsActive> <a:IsReturnable>true</a:IsReturnable> <a:Info i:nil="true" xmlns:b="Enferno.Services.Contracts.Expose"/> </OnHandSupplier> <PriceRecommended i:nil="true"/> <ManufacturerId>4335</ManufacturerId> <UniqueName>freight</UniqueName> <StatusId>1</StatusId> <StockDisplayBreakPoint i:nil="true"/> <PriceCatalog i:nil="true"/> <IsBuyable>true</IsBuyable> <SubDescription i:nil="true"/> <CategoryIdSeed/> <RecommendedQuantity>1.000</RecommendedQuantity> <IsRecommendedQuantityFixed>false</IsRecommendedQuantityFixed> <AppliedPromotions/> <RequirementPromotionIdSeed i:nil="true"/> <IsSubscribable>false</IsSubscribable> <DescriptionHeader i:nil="true"/> <IsPriceManual>false</IsPriceManual> <PriceStandard>0.00</PriceStandard> <EanCode/> <CostUnit>0.00</CostUnit> <PriceDisplayIncVat>0.00</PriceDisplayIncVat> </BasketItem> <BasketItem> <Id>0</Id> <LineNo>3</LineNo> <ParentLineNo>1</ParentLineNo> <ProductId>31234588</ProductId> <PartNo>PRD0001274</PartNo> <ManufacturerPartNo>Underhållskit</ManufacturerPartNo> <Name>Underhållskit Motorsåg</Name> <SubHeader i:nil="true"/> <ThumbnailImage>2/thumb_p31234588.png</ThumbnailImage> <FlagIdSeed>915</FlagIdSeed> <Type>1</Type> <PriceDisplay>111.20</PriceDisplay> <Price>0.00</Price> <PriceOriginal>111.20</PriceOriginal> <Cost>100.25</Cost> <VatRate>1.25</VatRate> <Quantity>1</Quantity> <UOM>st</UOM> <UOMCount>1.000</UOMCount> <Comment i:nil="true"/> <PriceListId>1</PriceListId> <ReferId i:nil="true"/> <ReferUrl i:nil="true"/> <IsEditable>false</IsEditable> <IsDiscountable>true</IsDiscountable> <Info> <Info> <TypeId>209</TypeId> <Value/> <Code>bit_size</Code> </Info> <Info> <TypeId>241</TypeId> <Value/> <Code>bit_del_time</Code> </Info> <Info> <TypeId>95</TypeId> <Value/> <Code>bit_additionalinformation</Code> </Info> </Info> <OptionalItems/> <OnHandValue>12.000</OnHandValue> <IncomingValue>0.000</IncomingValue> <NextDeliveryDate i:nil="true"/> <LeadtimeDayCount>0</LeadtimeDayCount> <PromotionIdSeed/> <ImageKey i:nil="true"/> <ManufacturerName>Husqvarna</ManufacturerName> <CategoryId>41722</CategoryId> <OnHand xmlns:a="Enferno.Services.Contracts.Expose.Products"> <a:Value>12.000</a:Value> <a:IncomingValue>0.000</a:IncomingValue> <a:NextDeliveryDate i:nil="true"/> <a:LeadtimeDayCount>0</a:LeadtimeDayCount> <a:LastChecked i:nil="true"/> <a:IsActive>true</a:IsActive> <a:IsReturnable>true</a:IsReturnable> <a:Info i:nil="true" xmlns:b="Enferno.Services.Contracts.Expose"/> </OnHand> <OnHandSupplier xmlns:a="Enferno.Services.Contracts.Expose.Products"> <a:Value>133.000</a:Value> <a:IncomingValue>0.000</a:IncomingValue> <a:NextDeliveryDate i:nil="true"/> <a:LeadtimeDayCount>5</a:LeadtimeDayCount> <a:LastChecked>2017-02-14T16:19:15.163</a:LastChecked> <a:IsActive>true</a:IsActive> <a:IsReturnable>true</a:IsReturnable> <a:Info i:nil="true" xmlns:b="Enferno.Services.Contracts.Expose"/> </OnHandSupplier> <PriceRecommended i:nil="true"/> <ManufacturerId>1685</ManufacturerId> <UniqueName>underhallskit-motorsag</UniqueName> <StatusId>1</StatusId> <StockDisplayBreakPoint i:nil="true"/> <PriceCatalog i:nil="true"/> <IsBuyable>true</IsBuyable> <SubDescription i:nil="true"/> <CategoryIdSeed>41722</CategoryIdSeed> <RecommendedQuantity>1.000</RecommendedQuantity> <IsRecommendedQuantityFixed>false</IsRecommendedQuantityFixed> <AppliedPromotions/> <RequirementPromotionIdSeed/> <IsSubscribable>false</IsSubscribable> <DescriptionHeader i:nil="true"/> <IsPriceManual>false</IsPriceManual> <PriceStandard>0.00</PriceStandard> <EanCode>345345345345345</EanCode> <CostUnit>0.00</CostUnit> <PriceDisplayIncVat>139.00</PriceDisplayIncVat> </BasketItem> </Items> <Info> <Info> <TypeId>169</TypeId> <Value/> <Code>bit_expecteddeliverydate</Code> </Info> <Info> <TypeId>293</TypeId> <Value/> <Code>bit_additionalorderinfo</Code> </Info> <Info> <TypeId>445</TypeId> <Value/> <Code>Norce_Gender</Code> </Info> <Info> <TypeId>493</TypeId> <Value/> <Code>recurring</Code> </Info> </Info> <Summary> <Items> <Amount>5854.40</Amount> <Vat>1463.60</Vat> <AmountIncVat>7318.00</AmountIncVat> </Items> <Freigt> <Amount>0.00</Amount> <Vat>0.00</Vat> <AmountIncVat>0.00</AmountIncVat> </Freigt> <Fees> <Amount>0.00</Amount> <Vat>0.00</Vat> <AmountIncVat>0.00</AmountIncVat> </Fees> <Total> <Amount>5854.40</Amount> <Vat>1463.60</Vat> <AmountIncVat>7318.00</AmountIncVat> </Total> </Summary> <AppliedPromotions> <Promotion> <Id>5093</Id> <Name>Add service</Name> <Header/> <ShortDescription/> <Description1/> <Description2/> <StartDate i:nil="true"/> <EndDate i:nil="true"/> <ImageKey i:nil="true"/> <RequirementSeed>3</RequirementSeed> <DiscountCode i:nil="true"/> <IsExcludedFromPriceCalculation>false</IsExcludedFromPriceCalculation> <AllowProductListing>false</AllowProductListing> <Images xmlns:a="Enferno.Services.Contracts.Expose"/> <ProductFilters> <Filter> <ManufacturerId i:nil="true"/> <CategorySeed i:nil="true"/> <TypeId i:nil="true"/> <ProductId i:nil="true"/> <VariantProductId i:nil="true"/> <PartNo>PRD0001274</PartNo> <PricelistId>1</PricelistId> <FlagId i:nil="true"/> </Filter> <Filter> <ManufacturerId i:nil="true"/> <CategorySeed i:nil="true"/> <TypeId i:nil="true"/> <ProductId i:nil="true"/> <VariantProductId i:nil="true"/> <PartNo i:nil="true"/> <PricelistId i:nil="true"/> <FlagId>1884</FlagId> </Filter> </ProductFilters> <AppliedAmount>0.00</AppliedAmount> <EffectSeed>5</EffectSeed> <FreightDiscountPct i:nil="true"/> <IsStackable>true</IsStackable> <AppliedAmountIncVat>0.00</AppliedAmountIncVat> </Promotion> </AppliedPromotions> <IpAddress>151.236.200.213</IpAddress> <AttestedBy i:nil="true"/> <TypeId>1</TypeId> <DoHold>false</DoHold> <IsBuyable>true</IsBuyable> <InvoiceReference i:nil="true"/> <PaymentMethodId i:nil="true"/> <DeliveryMethodId>1</DeliveryMethodId> <SalesAreaId>1</SalesAreaId> </Basket>
The basket data model
The basket contains many properties, here are some important ones.
Id
, the identifier of the basket. For the visitors active basket, this is usually stored in a persisted cookieStatus
, basket can have different statuses, depending on the usage. For a cart the most common are "Basket" (3), "Ready for payment" (7), "Payment pending" (12), "Payment Accepted" (8), "Order" (10).Currency
, if the application allowed for different currencies this field can be changed. The basket will the convert the prices and amounts to the chosen currency.IsEditable
andIsBuyable
, in some instances the basket is locked and cannot be updated by the visitor or not able to be processed through a checkout. Some examples are when the basket has become an order, or during the checkout process.Summary
, this contains summary information on the total amount and freight.Items
, are a collection of all the products added to the basket, withId
, the identifier of theBasketItem
(this is required for the update calls)LineNo
, a friendly number of the rowParentLineNo
, for complex items (like packages), or for user friendly grouping of itemsProductId
andPartNo
, identifiers of the product. A basket item must be connected to a product in Norce CommerceType
, the product typePriceDisplay
, the price in a friendly format, for read onlyQuantity
, number of items in the basketPriceListId
, the price list the price is based fromIsEditable
, in some instances the basket item cannot be updated by the visitor
Norce handles quite a lot of the basket business logic behind the scenes.
For example if you add an item to the basket that already exists, Norce does not increment the existing row´s quantity, instead a new line is added to the basket. This is because many solutions needs to have this flexibility, for example: A B2B sales model often needs to separate items into rows and add delivery or invoice references separately for each item.
A common practice is to add these simplifications in your own backend in a service layer where your Norce Commerce requests pass through. This lets you simplify the workflow specific to your needs.
The update pattern
When working with baskets there is a lot of possible changes that will happen to the basket for every action the visitor does. Therefore Norce Commerce Shopping Service always return the whole basket object whenever a change is done. A good common practice is to have the basket stored in a cache, or (if concurrency is an issue i.e. if many clients work with the same lists) ask for the basket first before mapping in your changes and then call the update in the API.
- A user action has occurred.
- A basket object is fetched, either from Norce Commerce or from a local cache
- The changes are mapped into the basket item (from the model object)
- The update is called (UpdateBasket, UpdateBasketItem or similar)
- The whole basket is returned from Norce
- The returned basket is mapped to a model object, written to a local cache and returned to the front end
A basket can change even without user action. For example the state of an item can change so that it is not buyable anymore (not in stock anymore, status set to inactive, etc) or a campaign or a promotion can stop being valid. This is something that your application needs to take into consideration in the fault and exception handling.
Context
There is a lot of contextual information on all gets and updates that you need to make sure to always send in to Norce Commerce Services if you are using them, for example: pricelistSeed
, cultureCode
, currencyId
. They are optional but if you use any one of them in your application, they need to be passed in on all calls.
Another input variable of note is the createdBy
, that should be passed in when a known user is working with their baskets, if user is a guest/unknown set this to 1
.
Lifecycle
Create Basket
A basket is created when the CreateBasket method is called. Preferably this is done when the first item(s) are added to the visitors basket. You can create a basket with default values, by passing in a whole basket object.
A good idea is to pass in CustomerId
and CompanyId
for logged in users, default PaymentMethodId
and default DeliveryMethodId
. Then you dont need to make these update calls in the checkout later.
Add Items
There are several methods to add items to the basket - InsertBasketItem
, InsertBasketItems
, InsertBasketItemsWithChildren
, but also the UpdateBasketItem
calls can increment the quantity on an existing item.
- InsertBasketItem, takes a basketitem as payload and appends it to the basket items collection, generating a LineNo and a unique Id to the line.
- InsertBasketItems, takes a collection of basketitems as payload and appends them to the basket items collection.
- InsertBasketItemWithChildren, takes a collection of basketitems as payload and appends them to the basket items collection. The first item gets to be parent to all the others.
- If you instead of appending wants to increment the quantity on already existing items you need to resolve it yourself before calling a basket metod. Use UpdateBasketItem or its sibling methods.
Norce has a setting called RecommendedQuantity
on the product, which suggest how many of the item that should automatically be added to the cart, check this field when calling InsertBasketItem
.
Note that this field is not enforced by Norce, unless it it also followed with the setting IsRecommendedQuantityFixed
then it is not possible to break up a multiple of the RecommendedQuantity
value.
Remove Items
Use DeleteBasketItem to removes one whole row, UpdateBasketItem calls can decrement quantity on existing items and ClearBasket removes all items on the basket.
UpdateBasketItem with quantity = 0 is the same as calling DeleteBasketItem.
Change Basket
Use UpdateBasket2 to change information on the header of the basket, like status, comment fields, etc. (mostly this is done in the checkout process, see the checkout guide )
Change BasketItems
UpdateBasketItem, UpdateBasketItems lets you update item information on one or several items at the same time. A required field to send in to Norce Commerce Shopping Service is the Id
on the item, without it the update wont take. Make sure to keep it in your cache. Most common field to update is the Quantity
of course, but other fields are Comment
and Price
, read more about this in the checkout process. Read also about some common scenarios under common business logic below.
Remove or reopen the basket
When a basket has been successfully processed through the checkout the status is changed to "Payment Accepted" or a bit later to "Order". Then the basket is locked and should be removed from the active basket slot in session and cookie. If a basket is still there your application should remove it silently and create a new basket when the end customer needs it.
If anything happened on a basket that has moved further in the process, you might not be allowed to continue to make changes on it. An easy way to keep the items and information on the basket is to create a new one passing in the old. Everything that is allowed to be updated to the new one will be. You clone an old basket by calling CreateBasket with the old one as payload.
See a postman example here.
Common business logic
There are some more common business logic that is handled from the basket management code on your side.
Overriding the price
In some scenarios, you might want to manually override the calculated price from Norce. This might be if you create a sales quotation, or want to add an offer to the item from a 3rd party. To do this you must add your new price in the InsertBasketItem or UpdateBasketItem in the field Price
, and confirm this by specifically adding IsPriceManual : true
as well.
Note the the
Price
field takes the unit price, not the row amount.
Here is an example:
{ "PartNo": "TestPartNo", "Price": 160.00, "Quantity": 1.000, "Comment": "This is an insert of a manual price to a new row in the basket", "PriceListId": 1, "IsPriceManual": true }
Then the returned basket item looks like this (shortened):
{ "LineNo": 1, "PartNo": "TestPartNo", "PriceDisplay": 160.00, "Price": 0.00, "PriceOriginal": 160.00, "Quantity": 1.000, "PriceListId": 1, "IsPriceManual": true, "PriceDisplayIncVat": 200.00 }
Note that the field Price
is 0 in the result, instead, the manual price is on PriceDisplay
, just as with any normal price, to recognize this price as a manual price you must check the IsPriceManual
field.
Lock the item to a price list
In some scenarios, you might want to lock the price to a specific price list. This will override any default "best price validations" that Norce normally do on the basket items. This makes it possible to override Norce's best price calculation and point to a specific price list that should be used.
Some use cases:
- The solution should use a price list (agreement) that has a higher price than the current campaign, but might give additional warranties or other prefered value to the customer.
- The solution should set the reservation to a specific warehouse/location. Lock the item to a price list, connected to this warehouse. Read about connected warehouses and reservation, for more info.
To lock the price to a price list, you must add PriceListLocked : true
your the basket item in the InsertBasketItem or UpdateBasketItem.
Here is an example:
{ "PartNo": "TestPartNo", "Quantity": 1.000, "Comment": "This is an insert of locked price list to a new row in the basket", "PriceListId": 15320, "PriceListLocked": true }
Then the returned basket item looks like this (shortened):
{ "LineNo": 1, "PartNo": "TestPartNo", "PriceDisplay": 6000.00, "Price": 0.00, "PriceOriginal": 6000.00, "Quantity": 1.000, "PriceListId": 15320, "PriceStandard": 5900.00, "PriceDisplayIncVat": 7500.00, "PriceListLocked": true }
Note that the PriceStandard
amount might be lower than the current PriceDisplay
here, since this is a locked price.
PriceListLocked
might return to false if
- You call an update to the shoppingservice, or
- The price list is no longer active on the product
Additional isEditable and isBuyable logic
Some clients wants to have more restrictions on what the basket than Norce provides, this could foe example be when a basket is buyable and not. This could be a validation on products that they should be in-stock for example. Or even more complex logic than that.
public bool Buyable(Basket basket) { if (basket.isBuyable) { //Check my custom logic as well (for example, that all products are in stock) return true; } else return false; }
Streamline basket processes
Event though Norce Commerce is flexible, some client solutions could benefit from a simplified view that is tailored to their needs. Examples:
- Add item with RecommendedQuantity set
- Add an already existing item as +1 to quantity
- Handle certain flagged products differently
- Handle overrides of prices as manual prices
Extend the basket model
Many cases the client has need of extending the basket model adding properties as info types in Norce Commerce Shopping Service. A common practice is to map these additional field to an extension to your basket model, so make it easier to use.
Promotions
Baskets applies promotions automatically if the requirements are valid. This means that prices or new items can suddenly be shown on a baskets depending of the effects. All applied promotions are are listed in the AppliedPromotions
list on the basket and on the basket item as well.
Some promotions are applied using a code. Use UpdateBasket
and set the DiscountCode
property to enable these kind of promotions. If no such promotion exists or if it isnt valid, the basket will simply not show a discount code after update.
See a Postman example here.
Complex items
Norce Commerce allowes for more complex items to be added to the basket. By that we mean items containing other items. Use the ParentLineNo
to display these items in an appropriate manner in the UI.
To simplify handling of these items there are some additional methods:
- InsertBasketItemWithChildren, takes a list of Basketitems to insert. The first is the parent.
- UpdateBasketItemQuantityWithChildren, lets you change the quantity of the parent and will also calculate the quantity change on its children.
Examples of items that use this functionality is products of type ManagedStructure
, ManagedErpPackage
and ManagedErpPackageWithCalc
and their Unmanaged counterparts.
Samples in Postman
We have some good samples on how to work with baskets here.