Working with the checkout process
The end of the buying experience is the checkout process with payment and order confirmation. The checkout process experience is subject to a number of business rules defined by Norce. Your solution needs to comply with these rules.
The checkout process requires a basket and at least one payment method and one delivery method set up.
- The full Checkout Schema
- Check out the examples in Postman as well.
An example checkout object
{ "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": 14, "DeliveryMethodId": 1, "SalesAreaId": 1 }, "Buyer": { "Id": null, "Key": "86830286-d988-442d-b741-30e637da1880", "Code": null, "Email": "test@test.se", "SSN": null, "FirstName": "TestBuyerName", "LastName": "TestBuyerLastname", "Phone": null, "CellPhone": null, "ReferId": null, "ReferUrl": null, "Account": { "Id": null, "Key": "86830286-d988-442d-b741-30e637da1880", "LoginName": null, "Name": null, "Roles": null, "Authorizations": null, "IsActive": false }, "Companies": [], "DeliveryAddresses": [], "InvoiceAddress": null, "Flags": null, "UseInvoiceAddressAsDeliveryAddress": false, "Info": null, "PricelistIds": null, "CrmId": null, "IsActive": null, "Created": null, "Updated": null }, "Payer": { "Id": null, "Key": "99a312c9-003a-4063-8310-b745e7e27f1e", "Code": null, "Email": "test@test.se", "SSN": null, "FirstName": "TestBuyerName", "LastName": "TestBuyerLastname", "Phone": null, "CellPhone": null, "ReferId": null, "ReferUrl": null, "Account": { "Id": null, "Key": "99a312c9-003a-4063-8310-b745e7e27f1e", "LoginName": null, "Name": null, "Roles": null, "Authorizations": null, "IsActive": false }, "Companies": [], "DeliveryAddresses": [], "InvoiceAddress": { "Id": 12055560, "CareOf": null, "Line1": "TestInvoicestreet 1", "Line2": null, "Zip": "12345", "City": "TestCity", "CountryId": 1, "Country": "Sverige", "Region": null, "IsValidated": false, "GlobalLocationNo": null, "ShippingPhoneNumber": null }, "Flags": null, "UseInvoiceAddressAsDeliveryAddress": false, "Info": null, "PricelistIds": null, "CrmId": null, "IsActive": null, "Created": null, "Updated": null }, "ShipTo": { "Id": null, "Key": "3466a97f-f1fa-4ff1-8ae9-ea641467f584", "Code": null, "Email": "test@test.se", "SSN": null, "FirstName": "TestBuyerName", "LastName": "TestBuyerLastname", "Phone": null, "CellPhone": null, "ReferId": null, "ReferUrl": null, "Account": { "Id": null, "Key": "3466a97f-f1fa-4ff1-8ae9-ea641467f584", "LoginName": null, "Name": null, "Roles": null, "Authorizations": null, "IsActive": false }, "Companies": [], "DeliveryAddresses": [ { "Id": 12055561, "CareOf": null, "Line1": "TestInvoicestreet 1", "Line2": null, "Zip": "12345", "City": "TestCity", "CountryId": 1, "Country": "Sverige", "Region": null, "IsValidated": false, "GlobalLocationNo": null, "ShippingPhoneNumber": null } ], "InvoiceAddress": null, "Flags": null, "UseInvoiceAddressAsDeliveryAddress": false, "Info": null, "PricelistIds": null, "CrmId": null, "IsActive": null, "Created": null, "Updated": null }, "PaymentMethods": [ { "Id": 14, "Name": "Faktura", "TypeId": 7, "TypeName": "ErpInvoice", "Description": "30 dagars faktura", "PartNo": null, "Price": 0.00, "VatRate": 1.00, "ImagePath": null, "IsSelected": true, "Service": { "Id": 3, "Name": "No service", "Description": null, "ImagePath": null, "ImageKey": null }, "ImageKey": null, "IsForCompanyOnly": false, "IsForPersonOnly": false }, { "Id": 18, "Name": "Presentkort", "TypeId": 9, "TypeName": "GiftCertificate", "Description": "Used for giftcards handeled by an ERP or other source outside of Norce Commerce", "PartNo": null, "Price": 0.00, "VatRate": 1.00, "ImagePath": null, "IsSelected": false, "Service": { "Id": 3, "Name": "No service", "Description": null, "ImagePath": null, "ImageKey": null }, "ImageKey": null, "IsForCompanyOnly": false, "IsForPersonOnly": false }, { "Id": 157, "Name": "Svea Ekonomi", "TypeId": 19, "TypeName": "Checkout", "Description": "Form checkout payment.", "PartNo": null, "Price": 0.00, "VatRate": 1.00, "ImagePath": null, "IsSelected": false, "Service": { "Id": 19, "Name": "SveaEkonomi", "Description": null, "ImagePath": null, "ImageKey": null }, "ImageKey": null, "IsForCompanyOnly": false, "IsForPersonOnly": false }, { "Id": 162, "Name": "Adyen checkout", "TypeId": 19, "TypeName": "Checkout", "Description": "Form checkout payment.", "PartNo": null, "Price": 0.00, "VatRate": 1.00, "ImagePath": null, "IsSelected": false, "Service": { "Id": 27, "Name": "AdyenV67", "Description": null, "ImagePath": null, "ImageKey": null }, "ImageKey": null, "IsForCompanyOnly": false, "IsForPersonOnly": false }, { "Id": 156, "Name": "Klarna Checkout v3 (Recurrable)", "TypeId": 19, "TypeName": "Checkout", "Description": "Form checkout payment.", "PartNo": null, "Price": 0.00, "VatRate": 1.00, "ImagePath": null, "IsSelected": false, "Service": { "Id": 18, "Name": "KlarnaCheckoutV3", "Description": null, "ImagePath": null, "ImageKey": null }, "ImageKey": null, "IsForCompanyOnly": false, "IsForPersonOnly": false }, { "Id": 160, "Name": "Dibs Easy Pay", "TypeId": 19, "TypeName": "Checkout", "Description": "Form checkout payment.", "PartNo": null, "Price": 0.00, "VatRate": 1.00, "ImagePath": null, "IsSelected": false, "Service": { "Id": 22, "Name": "DibsEasyCheckout", "Description": null, "ImagePath": null, "ImageKey": null }, "ImageKey": null, "IsForCompanyOnly": false, "IsForPersonOnly": false }, { "Id": 166, "Name": "Walley B2B", "TypeId": 19, "TypeName": "Checkout", "Description": "", "PartNo": null, "Price": 0.00, "VatRate": 1.00, "ImagePath": null, "IsSelected": false, "Service": { "Id": 24, "Name": "Collector", "Description": null, "ImagePath": null, "ImageKey": null }, "ImageKey": null, "IsForCompanyOnly": false, "IsForPersonOnly": false } ], "DeliveryMethods": [ { "Id": 1, "Name": "DB Schenker Utlämningsställe", "TypeId": 6, "TypeName": "Utlämning", "Description": "DB Schenker leverans till vald utlämningsställe", "PartNo": "PRD0001212", "Price": 0.0000, "VatRate": 1.25, "IsNotifiable": false, "ImagePath": null, "IsSelected": true, "ImageKey": null, "IsForCompanyOnly": false, "IsForPersonOnly": false, "Cost": 0.0000, "StoreId": null, "WarehouseId": null, "LocationId": null, "DropPoints": [], "Code": "DBS-UTL", "Carrier": null }, { "Id": 7, "Name": "Hempaket kväll", "TypeId": 1, "TypeName": "Hemleverans", "Description": "Leverans sker hem mellan 17:00 och 22:00.", "PartNo": "PRD0001212", "Price": 49.0000, "VatRate": 1.2500, "IsNotifiable": false, "ImagePath": null, "IsSelected": false, "ImageKey": null, "IsForCompanyOnly": false, "IsForPersonOnly": true, "Cost": 0.0000, "StoreId": null, "WarehouseId": null, "LocationId": null, "DropPoints": [], "Code": "HEMPK", "Carrier": null } ], "Payments": [] }
<Checkout xmlns="Enferno.Services.Contracts.Expose.Shopping" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Basket> <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.2500</VatRate> <Quantity>1.000</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.000</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>14</PaymentMethodId> <DeliveryMethodId>1</DeliveryMethodId> <SalesAreaId>1</SalesAreaId> </Basket> <Buyer xmlns:a="Enferno.Services.Contracts.Expose.Customers"> <a:Id i:nil="true"/> <a:Key>bf335b15-2bf2-49ef-a1e7-5a0e599e96a4</a:Key> <a:Code i:nil="true"/> <a:Email>test@test.se</a:Email> <a:SSN i:nil="true"/> <a:FirstName>TestBuyerName</a:FirstName> <a:LastName>TestBuyerLastname</a:LastName> <a:Phone i:nil="true"/> <a:CellPhone i:nil="true"/> <a:ReferId i:nil="true"/> <a:ReferUrl i:nil="true"/> <a:Account> <a:Id i:nil="true"/> <a:Key>bf335b15-2bf2-49ef-a1e7-5a0e599e96a4</a:Key> <a:LoginName i:nil="true"/> <a:Name i:nil="true"/> <a:Roles i:nil="true" xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/> <a:Authorizations i:nil="true" xmlns:b="Enferno.Services.Contracts.Expose"/> <a:IsActive>false</a:IsActive> </a:Account> <a:Companies/> <a:DeliveryAddresses/> <a:InvoiceAddress i:nil="true"/> <a:Flags i:nil="true"/> <a:UseInvoiceAddressAsDeliveryAddress>false</a:UseInvoiceAddressAsDeliveryAddress> <a:Info i:nil="true" xmlns:b="Enferno.Services.Contracts.Expose"/> <a:PricelistIds i:nil="true" xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/> <a:CrmId i:nil="true"/> <a:IsActive i:nil="true"/> <a:Created i:nil="true"/> <a:Updated i:nil="true"/> </Buyer> <Payer xmlns:a="Enferno.Services.Contracts.Expose.Customers"> <a:Id i:nil="true"/> <a:Key>5ec95f79-75af-43e6-8036-5d69de968510</a:Key> <a:Code i:nil="true"/> <a:Email>test@test.se</a:Email> <a:SSN i:nil="true"/> <a:FirstName>TestBuyerName</a:FirstName> <a:LastName>TestBuyerLastname</a:LastName> <a:Phone i:nil="true"/> <a:CellPhone i:nil="true"/> <a:ReferId i:nil="true"/> <a:ReferUrl i:nil="true"/> <a:Account> <a:Id i:nil="true"/> <a:Key>5ec95f79-75af-43e6-8036-5d69de968510</a:Key> <a:LoginName i:nil="true"/> <a:Name i:nil="true"/> <a:Roles i:nil="true" xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/> <a:Authorizations i:nil="true" xmlns:b="Enferno.Services.Contracts.Expose"/> <a:IsActive>false</a:IsActive> </a:Account> <a:Companies/> <a:DeliveryAddresses/> <a:InvoiceAddress> <a:Id>12055560</a:Id> <a:CareOf i:nil="true"/> <a:Line1>TestInvoicestreet 1</a:Line1> <a:Line2 i:nil="true"/> <a:Zip>12345</a:Zip> <a:City>TestCity</a:City> <a:CountryId>1</a:CountryId> <a:Country>Sverige</a:Country> <a:Region i:nil="true"/> <a:IsValidated>false</a:IsValidated> <a:GlobalLocationNo i:nil="true"/> <a:ShippingPhoneNumber i:nil="true"/> </a:InvoiceAddress> <a:Flags i:nil="true"/> <a:UseInvoiceAddressAsDeliveryAddress>false</a:UseInvoiceAddressAsDeliveryAddress> <a:Info i:nil="true" xmlns:b="Enferno.Services.Contracts.Expose"/> <a:PricelistIds i:nil="true" xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/> <a:CrmId i:nil="true"/> <a:IsActive i:nil="true"/> <a:Created i:nil="true"/> <a:Updated i:nil="true"/> </Payer> <ShipTo xmlns:a="Enferno.Services.Contracts.Expose.Customers"> <a:Id i:nil="true"/> <a:Key>b06fd649-f97d-4e0b-8285-d6a3ca3adf53</a:Key> <a:Code i:nil="true"/> <a:Email>test@test.se</a:Email> <a:SSN i:nil="true"/> <a:FirstName>TestBuyerName</a:FirstName> <a:LastName>TestBuyerLastname</a:LastName> <a:Phone i:nil="true"/> <a:CellPhone i:nil="true"/> <a:ReferId i:nil="true"/> <a:ReferUrl i:nil="true"/> <a:Account> <a:Id i:nil="true"/> <a:Key>b06fd649-f97d-4e0b-8285-d6a3ca3adf53</a:Key> <a:LoginName i:nil="true"/> <a:Name i:nil="true"/> <a:Roles i:nil="true" xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/> <a:Authorizations i:nil="true" xmlns:b="Enferno.Services.Contracts.Expose"/> <a:IsActive>false</a:IsActive> </a:Account> <a:Companies/> <a:DeliveryAddresses> <a:Address> <a:Id>12055561</a:Id> <a:CareOf i:nil="true"/> <a:Line1>TestInvoicestreet 1</a:Line1> <a:Line2 i:nil="true"/> <a:Zip>12345</a:Zip> <a:City>TestCity</a:City> <a:CountryId>1</a:CountryId> <a:Country>Sverige</a:Country> <a:Region i:nil="true"/> <a:IsValidated>false</a:IsValidated> <a:GlobalLocationNo i:nil="true"/> <a:ShippingPhoneNumber i:nil="true"/> </a:Address> </a:DeliveryAddresses> <a:InvoiceAddress i:nil="true"/> <a:Flags i:nil="true"/> <a:UseInvoiceAddressAsDeliveryAddress>false</a:UseInvoiceAddressAsDeliveryAddress> <a:Info i:nil="true" xmlns:b="Enferno.Services.Contracts.Expose"/> <a:PricelistIds i:nil="true" xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/> <a:CrmId i:nil="true"/> <a:IsActive i:nil="true"/> <a:Created i:nil="true"/> <a:Updated i:nil="true"/> </ShipTo> <PaymentMethods> <PaymentMethod> <Id>14</Id> <Name>Faktura</Name> <TypeId>7</TypeId> <TypeName>ErpInvoice</TypeName> <Description>30 dagars faktura</Description> <PartNo i:nil="true"/> <Price>0.00</Price> <VatRate>1.00</VatRate> <ImagePath i:nil="true"/> <IsSelected>true</IsSelected> <Service> <Id>3</Id> <Name>No service</Name> <Description i:nil="true"/> <ImagePath i:nil="true"/> <ImageKey i:nil="true"/> </Service> <ImageKey i:nil="true"/> <IsForCompanyOnly>false</IsForCompanyOnly> <IsForPersonOnly>false</IsForPersonOnly> </PaymentMethod> <PaymentMethod> <Id>18</Id> <Name>Presentkort</Name> <TypeId>9</TypeId> <TypeName>GiftCertificate</TypeName> <Description>Used for giftcards handeled by an ERP or other source outside of Norce Commerce</Description> <PartNo i:nil="true"/> <Price>0.00</Price> <VatRate>1.00</VatRate> <ImagePath i:nil="true"/> <IsSelected>false</IsSelected> <Service> <Id>3</Id> <Name>No service</Name> <Description i:nil="true"/> <ImagePath i:nil="true"/> <ImageKey i:nil="true"/> </Service> <ImageKey i:nil="true"/> <IsForCompanyOnly>false</IsForCompanyOnly> <IsForPersonOnly>false</IsForPersonOnly> </PaymentMethod> <PaymentMethod> <Id>157</Id> <Name>Svea Ekonomi</Name> <TypeId>19</TypeId> <TypeName>Checkout</TypeName> <Description>Form checkout payment.</Description> <PartNo i:nil="true"/> <Price>0.00</Price> <VatRate>1.00</VatRate> <ImagePath i:nil="true"/> <IsSelected>false</IsSelected> <Service> <Id>19</Id> <Name>SveaEkonomi</Name> <Description i:nil="true"/> <ImagePath i:nil="true"/> <ImageKey i:nil="true"/> </Service> <ImageKey i:nil="true"/> <IsForCompanyOnly>false</IsForCompanyOnly> <IsForPersonOnly>false</IsForPersonOnly> </PaymentMethod> <PaymentMethod> <Id>162</Id> <Name>Adyen checkout</Name> <TypeId>19</TypeId> <TypeName>Checkout</TypeName> <Description>Form checkout payment.</Description> <PartNo i:nil="true"/> <Price>0.00</Price> <VatRate>1.00</VatRate> <ImagePath i:nil="true"/> <IsSelected>false</IsSelected> <Service> <Id>27</Id> <Name>AdyenV67</Name> <Description i:nil="true"/> <ImagePath i:nil="true"/> <ImageKey i:nil="true"/> </Service> <ImageKey i:nil="true"/> <IsForCompanyOnly>false</IsForCompanyOnly> <IsForPersonOnly>false</IsForPersonOnly> </PaymentMethod> <PaymentMethod> <Id>156</Id> <Name>Klarna Checkout v3 (Recurrable)</Name> <TypeId>19</TypeId> <TypeName>Checkout</TypeName> <Description>Form checkout payment.</Description> <PartNo i:nil="true"/> <Price>0.00</Price> <VatRate>1.00</VatRate> <ImagePath i:nil="true"/> <IsSelected>false</IsSelected> <Service> <Id>18</Id> <Name>KlarnaCheckoutV3</Name> <Description i:nil="true"/> <ImagePath i:nil="true"/> <ImageKey i:nil="true"/> </Service> <ImageKey i:nil="true"/> <IsForCompanyOnly>false</IsForCompanyOnly> <IsForPersonOnly>false</IsForPersonOnly> </PaymentMethod> <PaymentMethod> <Id>160</Id> <Name>Dibs Easy Pay</Name> <TypeId>19</TypeId> <TypeName>Checkout</TypeName> <Description>Form checkout payment.</Description> <PartNo i:nil="true"/> <Price>0.00</Price> <VatRate>1.00</VatRate> <ImagePath i:nil="true"/> <IsSelected>false</IsSelected> <Service> <Id>22</Id> <Name>DibsEasyCheckout</Name> <Description i:nil="true"/> <ImagePath i:nil="true"/> <ImageKey i:nil="true"/> </Service> <ImageKey i:nil="true"/> <IsForCompanyOnly>false</IsForCompanyOnly> <IsForPersonOnly>false</IsForPersonOnly> </PaymentMethod> <PaymentMethod> <Id>166</Id> <Name>Walley B2B</Name> <TypeId>19</TypeId> <TypeName>Checkout</TypeName> <Description/> <PartNo i:nil="true"/> <Price>0.00</Price> <VatRate>1.00</VatRate> <ImagePath i:nil="true"/> <IsSelected>false</IsSelected> <Service> <Id>24</Id> <Name>Collector</Name> <Description i:nil="true"/> <ImagePath i:nil="true"/> <ImageKey i:nil="true"/> </Service> <ImageKey i:nil="true"/> <IsForCompanyOnly>false</IsForCompanyOnly> <IsForPersonOnly>false</IsForPersonOnly> </PaymentMethod> </PaymentMethods> <DeliveryMethods> <DeliveryMethod> <Id>1</Id> <Name>DB Schenker Utlämningsställe</Name> <TypeId>6</TypeId> <TypeName>Utlämning</TypeName> <Description>DB Schenker leverans till vald utlämningsställe</Description> <PartNo>PRD0001212</PartNo> <Price>0.0000</Price> <VatRate>1.25</VatRate> <IsNotifiable>false</IsNotifiable> <ImagePath i:nil="true"/> <IsSelected>true</IsSelected> <ImageKey i:nil="true"/> <IsForCompanyOnly>false</IsForCompanyOnly> <IsForPersonOnly>false</IsForPersonOnly> <Cost>0.0000</Cost> <StoreId i:nil="true"/> <WarehouseId i:nil="true"/> <LocationId i:nil="true"/> <DropPoints/> <Code>DBS-UTL</Code> <Carrier i:nil="true"/> </DeliveryMethod> <DeliveryMethod> <Id>7</Id> <Name>Hempaket kväll</Name> <TypeId>1</TypeId> <TypeName>Hemleverans</TypeName> <Description>Leverans sker hem mellan 17:00 och 22:00.</Description> <PartNo>PRD0001212</PartNo> <Price>49.0000</Price> <VatRate>1.2500</VatRate> <IsNotifiable>false</IsNotifiable> <ImagePath i:nil="true"/> <IsSelected>false</IsSelected> <ImageKey i:nil="true"/> <IsForCompanyOnly>false</IsForCompanyOnly> <IsForPersonOnly>true</IsForPersonOnly> <Cost>0.0000</Cost> <StoreId i:nil="true"/> <WarehouseId i:nil="true"/> <LocationId i:nil="true"/> <DropPoints/> <Code>HEMPK</Code> <Carrier i:nil="true"/> </DeliveryMethod> </DeliveryMethods> <Payments/> </Checkout>
Checkout data model
In the center of the checkout process is the Checkout
object. This contains other important entities like:
- The
Basket
, all products/items, with its current prices, fees, promotions etc. See the Basket guide. - The
Buyer
,Payer
andShipTo
addresses. They are allCustomer
objects, representing who buys the order. Who pays it and where it should be delivered. - The
Payments
already used. This is in most cases an empty list, but in some, like when using gift card payments for part of the amount you will purchase from each gift card first and pay for the rest as the last step. And in this scenario some already paid payment will show in this list. PaymentMethods
, is a list of the possible payments to use. If you have already chosen one (or if you have one as default) it will have the “IsSelected” flag set to true.DeliveryMethods
, is a list of the possible shipping methods to use. If you have already chosen one (or if you have one as default) it will have the “IsSelected” flag set to true.
The Checkout
object is always resolved from the business rules in Norce Commerce. Depending on the rules set up there are many things that can change between your actions. If you, for example update shipping to another, shipping fees on the basket might change, some promotions on the basket are applied or removed, some payment methods might not be allowed anymore etc.
The update “flow”
Since updates on anything related to the checkout might change any other thing on the checkout the common practice is to
- Catch and handle the user action in the back end.
- Call the method in Norce Commerce Shopping Service and receive the new
Checkout
object in return. - Map the new checkout object to our model and return to the front end.
- Write the new model to the cache.
Also, keep the cache time rather short for the checkout object, since some business rules can change without user action involvement. Read more on updating patterns in the frontend design guide and the basket guide.
Checkout update steps
For a purchase to go through the checkout must have the following:
- One selected payment method
- One selected delivery method
- Customer information on all fields - SellTo, BillTo and ShipTo (*)
(*) When using form payment processes customer information is commonly added from the payment service provider and not from Norce Commerce directly.
Default values can be set to remove several steps in the checkout process. Already when creating the basket, pass in a whole basket object, containing PaymentMethodId
, DeliveryMethodId
, etc. See Working with Baskets.
Freight and delivery
If you use Norce’s built-in freight framework, the only requirement is to set, or allow the customer to select, a delivery method during checkout. Norce will automatically add the correct price and information to the basket and, later, to the order.
It is also possible to work with external delivery selection providers like NShift and Ingrid, passing in their information to the basket and order.
Purchase and payments
After the initial checkout actions are done it is time to let the customer pay.
Norce Commerce supports many different payment service providers, and they might have some differences between them, but Norce tries to make similar PSP processes look as much the same as possible. Norce separate these into three mayor types. The one-step process, the two-step process and the form based process.
One-step payments
(all in the same window)
This is the simplest process, where the customer stays on the same page and initialize the purchase action by pressing a button. This, for example could be a pay later method, or invoice from the ERP system.
The user action is translated to a purchase call to Norce Commerce Shopping Service. And the response ( PaymentResponse
) has all the status information needed to tell the customer of the status.
The Purchase methods
There are three different purchase calls to Norce Commerce Shopping Service, that does the same thing but takes different input parameters.
- Purchase, only a basket id is required. All payment configurations is fetched from settings in Norce Commerce
- PurchaseEx, a list of payment parameters can be passed in. Norce lets the web application override configurations.
- PurchaseEx2, a list of payment parameters and also a whole checkout object can be passed in. By using this call, you can skip a step of updates of the checkout object. Pass in the checkout with your last changes, and they will be applied first before the purchase is done.
The PaymentResponse object
The PaymentResponse is returned by all the Purchase calls and gives the client a status, as well as information on what to do next.
Status
andStatusDescription
, information on what the status is or what is currently happening on the order or payment.IsSynchronous
, true if the payment is a 1-step payment. false if it is a 2-step payment (see below)OrderNo
, the order number or the quotationid, depending on configurations in Norce.PaymentReference
, a transaction reference from the PSP (if applicable), or a snippet (script tag) that should be rendered in an iframe in the checkout page (form based payments, see below)RedirectUrl
, if the purchase process is in 2 steps, this is the redirect url to the PSP payment window.RedirectParameters
, if the purchase process is in 2 steps, this is a list of name-value pairs containing parameters that should be posted to the redirect url.
Two-step payments
(redirect to a payment window)
Some payment service providers uses payment windows where the application should redirect the customers, where they will fill in sensitive payment information before returning back to a confirmation page.
- The purchase is initialized by calling one of Norce Commerce’s purchase methods.
- Redirect URL and sometimes Redirect parameters is returned and the back end redirects the customer to a payment window
- The customer completed the payment in the payment window
- The customer is returned to the site (to a predefined url either as a redirect parameter, as a parameter in the earlier initialize process or a fixed url set up in the merchant settings at the PSP)
- The payment should be validated by calling PaymentCallback or PaymentCallback2 before an order confirmation page is shown to the customer.
- Some PSP setups sends a server-to-server call as a confirmation to Norce as well or when no call has come from Norce for a specific time.
The callback methods
For 2-step payments, a callback is required when the customer is returned to the site. Depending on the PSP implementation, this will either validate the payment using parameters sent in (e.g., checksum validations) or, for some PSPs, make an additional API call to confirm the payment. The callback returns a PaymentResponse object with a successful status if everything is correct, and the order is ready to be processed by Norce.
- PaymentCallback, validates the payment and starts the order process. Send in all the parameters required for the PSP (usually this is all query or post parameters passed from the Payment window).
- PaymentCallback2, validates the payment, but does not start the order process. Use this in more complex solutions.
Form based Payments
(as an embedded form on the checkout page)
Some PSP's (payment service providers) has a payment process that adds a form to the checkout page, like an IFrame. In this way the customer will not be redirected a couple of times, with all the possible added complexities. So for the customer this feels simpler and more like a 1-step purchase process.
Another common difference here is that many PSPs will collect all the customer information on their side and the trigger the purchase process from their form, so a Purchase
call to Norce Commerce Shopping Service will never happen. Here is how it works instead.
- When the customer is ready to pay, GetPaymentForm is called in Norce Commerce Shopping Service.
- The
PaymentResponse
object returned contains embed information in the paymentReference field to render the form in the UI. - The customer provides information in the form to the PSP directly, like personal information or card number etc.
- The customer click on “Buy” in the IFrame and the PSP processes the payment.
- The PSP responds with a confirmation so that the solution can validate the payment by calling Norce Commerce Shopping Service´s PaymentFormCallback.
- Some PSP setups sends a server-to-server call as a confirmation to Norce as well or when no call has come from Norce for a duration.
There are three slightly different PaymentCallback methods:
- PaymentCallback validates the payment and starts the order process.
- PaymentCallback2 validates the payment, but does not start the order process.
- PaymentFormCallback validates the form payment, but does not start the order process. Use
PaymentCallback
if the order should be processed directly.
Show a confirmation page
To get the information you want to show on an order confirmation page you can call GetOrderRequest, to get the order information and also GetCheckout to get the last Checkout
object as well. Between these to you should have most information you need.
For two-step and payment form payments the confirmation page should be passed in to the psp using the payment parameter ShopCallbackUrl
(see below), who in turn redirects the customer back when it's time.
Most commonly the PSP implementation require a URL with just one query value, that is their payment reference. The rest of the information is already something you have, in a cookie for example. But to only trust in a cookie might give you problems if multiple things happen at the same time (customer has many tabs or devices active). A good practice is to add the BasketId
as a query parameter to the ShopCallbackUrl
. This ensures that you have all the information needed to display a confirmation page.
Confirmation notifications
Norce Commerce has a built-in solution to notify the customer by email about the order confirmation. This solution uses Sendgrid as the mail engine and is configured in the Admin UI. If you want to handle the notification in your own way, you can trigger the notification by using Norce Commerce Event and lookup information from Norce Commerce Query.
Availability checks
Some clients need to do an availability check during the checkout process. Norce has two possible ways to help with that.
Calling ListProductOnHandByBasket, this returns OnHand information from Norce on all items in the basket in one go. Aside from basketId
, you can also pass in a list of warehouses that you want specifically to check.
Calling ListExternalProductOnHandByBasket, this is similar to its sister above, but this method checks the actual OnHand of the products in the basket in the clients source system(s). If no such integrations is provided then this is equal to calling the method above. But if this real time check is set up, this method will return will non-cached data as well as update the products in Norce using Norce Commerce Connect.
Norce does not do any availability validations on the baskets. Only the data is provided so that your application can have their own validation rules.
Payment Capture (Settle)
Some payments require a capture, usually later when the order is being delivered. Some solution uses Norce Commerce´s capture functionality for this and others uses built-in functionality in their ERP systems.
Read more about how to do Payment Capture here.
More functionality
Important Payment Parameters
Different PSP´s supports different parameters in their integrations. Read more on the specifics under the PSP adapter documentation. Since every PSP has its own parameters and parameter names Norce tries to map these to its own set of parameters. This eases the transition between different PSP implementations.
Parameter name | Used in | Description |
---|---|---|
CountryCode (*) | PurchaseEx , PurchaseEx2 , GetPaymentForm | A country code that marks in which country the purchase should be handled. This overrides the primary country on the application and must be a country added to the application (check the configurations in admin). This is passed in to the Payment Service provider and is applied on the payment session. (ISO-3166-1 ALPHA-2 two letter country code format, like “SE”, “FI”, “UK”, “DE”) |
CultureCode | PurchaseEx , PurchaseEx2 , GetPaymentForm | A language setting for the generated UI that is shown by the PSP. Overrides primary culture (or chosen culture) on the application level. (ISO 639 two-letter lowercase, or in combination with ISO 3166 two-letter uppercase subculture code, like “sv”, “de”, “sv-SE”, “da-DK”) |
ShopCallbackUrl | PurchaseEx , PurchaseEx2 , GetPaymentForm | The browser will redirect to this page once the purchase has been completed. Used to display a thank-you-page for the end user. |
ShopTermsUrl | PurchaseEx , PurchaseEx2 , GetPaymentForm | The page to which the Checkout will include a link for customers that wish to view the merchant terms for purchase. |
CheckoutId | GetPaymentForm | The PSP’s unique checkout id. Gets set when initializing a new checkout session and should be specified in URL's back to Norce, like CallbackUrl or ValidationUrl etc as ?checkoutId={checkout.id} See specific documentation for PSP. |
ShopValidationUrl | GetPaymentForm | When PSP calls back to Norce Commerce during validation, this url point to an endpoint where Norce should pass the validation on to if you want to do your own validations as well. |
StartNewSession | GetPaymentForm | Force a new session at the PSP, clears out things that are usually persisted from the PSP, like purchase country and customer information, use this to reset the payment process at the PSP. |
(*) For most payment service providers, this setting is not updatable, so if you want to change it you must clear old the checkout id and let the PSP start again, see StartNewSession
parameter.
Samples in Postman
We have some good samples on how to work with the checkouts here.