flamingo.me/flamingo-commerce/v3@v3.11.0/cart/Readme.md (about)

     1  # Cart Module
     2  
     3  The cart module is one of the main modules in Flamingo Commerce. It offers:
     4  
     5  * *domain layer*: 
     6      * domain models for carts, deliveries and their items. 
     7      * cartservices: the secondary ports required for modifying the cart.
     8      * orderservice: the secondary port called when placing the cart as order
     9      * support for multiple deliveries
    10      * support for multipayment
    11  * *application layer* useful application services, that should be used to get and modify the carts. That also includes a transparent session based cart cache to cache carts in cases where updating and reading the cart (e.g. against an external API) is too slow.
    12  * *interface layer* Controllers and Actions to render the carrt pages. Also a flexible to use Ajax API that can be used to modify the cart.
    13  * *infrastructure layer* 
    14      * Sample adapter for the secondary ports that maneges the cart in memory.
    15      * Sample adapter that will log a json file with every for placing an order
    16  
    17  There will be additional Flamingo modules that provide adapters for the secondary ports against common e-commerce APIs like Magento 2.
    18  The cart module and its services are used by the checkout module.
    19  
    20  ## Usage
    21  
    22  ### Configurations
    23  
    24  For all possible configurations you can check the `module.go` (CueConfig function)
    25  As always you can also dump the current configuration with the "config" Flamingo command.
    26  
    27  Here is a typical configuration
    28  ```yaml
    29    commerce.cart:
    30      # enable the secondary adapters for the cart services.  (e.g. for testing or development mode)
    31      useInMemoryCartServiceAdapters: true
    32      # enable the cache
    33      enableCartCache: true
    34      # set the default delivery code that is used if no other is given
    35      defaultDeliveryCode: "delivery"
    36  ```
    37  
    38  ## Domain Model Details
    39  
    40  ### Cart Aggregate
    41  
    42  Represents the Cart with PaymentInfos, DeliveryInfos and its Items:
    43  
    44  ![Cart Model](cart-model.png)
    45  
    46  ### Immutable cart / Updating the cart
    47  * The "Cart" aggregate in the Domain Model is a complex object that should be used as a pure **immutable value object**:
    48      * Never change it directly!
    49      * Only read from it
    50  * The Cart is only **modified by Commands** send to a CartBehaviour Object
    51  * If you want to retrieve or change a  cart - **ONLY work with the application services**. This will ensure that the correct cache is used
    52  
    53  
    54  ### About Delivery
    55  
    56  In order to support Multidelivery the cart cannot directly have Items attached, instead the Items belong to a Delivery.
    57  
    58  That also means when adding Items to the cart you need to specify the delivery with a "code".
    59  
    60  In cases where you only need one Delivery this can be configured as default and will be added on the fly for you.
    61  
    62  #### DeliveryInfo
    63  
    64  DeliveryInfo represents the information about which delivery method should be used and what delivery location should be used.
    65  
    66  A DeliveryInfo has:
    67  * a `code` that should identify a Delivery unique under the cart. It's up to you what code you want. You may want to follow the conventions used by the Default `DeliveryInfoBuilder`
    68  * a `workflow` - that is used to be able to differentiate between different fulfillment workflows (e.g. pickup or delivery)
    69  * a `method` - used to specify details for the delivery. It's up for the project what you want to use. E.g. use it to differentiate between `standard` and `express`
    70  * a `deliverylocation` - A deliverylocation can be an address, but also a location defined by a code (e.g. such as a collection point).
    71  
    72  The DeliveryInfo object is normally completed with all required infos during the checkout using the DeliveryInfoUpdateCommand
    73  
    74  ##### Optional Port: DeliveryInfoBuilder
    75  
    76  The DeliveryInfoBuilder interface defines an interface that builds initial `DeliveryInfo` for a cart.
    77  
    78  The `DefaultDeliveryInfoBuilder` that is part of the package should be ok for most cases, it simply takes the passed `deliverycode` and builds an initial `DeliveryInfo` object.
    79  The code used by the `DefaultDeliveryInfoBuilder` should be speaking for that reason and is used to initially create the `DeliveryInfo`:
    80  
    81  The convention used by this default builder is as follow: `WORKFLOW_LOCATIONTYPE_LOCATIONCODE_METHOD_anythingelse`
    82  
    83  Valid codes are:
    84  * `delivery` (default)
    85      * DeliveryInfo to have the item (home) delivered
    86  * `pickup_store_LOCATIONCODE`
    87      * DeliveryInfo to pickup the item in a (in)store pickup location
    88  * `pickup_collection_LOCATIONCODE`
    89      * DeliveryInfo to pickup the item in a special pickup location (central collection point)
    90  
    91  
    92  ### CartItem details
    93  
    94  There are special properties that require some explanations:
    95  
    96  * `SourceId`: Optional represents a location that should be used to fulfill this item. 
    97  This can be the code of a certain warehouse or even the code of a retail store (if the item should be picked(sourced) from that location)
    98      * There is a SourcingService interface - that allows you to register the logic of how to decide on the `SourceId`
    99  
   100  ### Decorated Cart
   101  
   102  If you need all the product information at hand - use the Decorated Cart - its decorating the cart with references to the product (dependency product package)
   103  
   104  ```graphviz
   105  digraph hierarchy {
   106  size="5,5"
   107  node[shape=record,style=filled,fillcolor=gray95]
   108  edge[dir=both, arrowtail=diamond, arrowhead=open]
   109  
   110  decoratedCart[label = "{decoratedCart||...}"]
   111  decoratedItem[label = "{decoratedItem||...}"]
   112  
   113  product[label = "{BasicProduct|+ ID\n|...}"]
   114  
   115  cart[label = "{Cart|+ ID\n|...}"]
   116  item[label = "{Item|ID\nPrice\nMarketplaceCode\nVariantMarketPlaceCode\nPrice\nQty|...}"]
   117  
   118  decoratedCart->cart[arrowtail=none]
   119  decoratedItem->item[arrowtail=odiamond]
   120  
   121  decoratedItem->product[arrowtail="none"]
   122  decoratedCart->decoratedItem
   123  
   124  cart->item[]
   125  
   126  }
   127  
   128  ```
   129  
   130  ## Details about Price fields
   131  
   132  Make sure you read the product package details about prices.
   133  
   134  The cart needs to show prices with their taxes and additional cart discounts and all different subtotals etc.
   135  What you want to show depends on the project, the type of shop (B2B or B2C), the discount logic and the implemented calculation details of the underlying cartservice implementation.
   136  
   137  Some of the prices you may want to show are "calculable" on the fly (in this cases they are offered as methods) - but some highly depend on the tax and discount logic and they need to have the correct values set by the underlying cartservice implementation.
   138  
   139  ### Cart invariants
   140  
   141  * While the Flamingo price model (which is used) can calculate exact prices internal, we need "payable prices" to be set in the cart. This is to allow consistent adding and subtracting of prices and still always get a price that is payable.
   142  
   143  * All sums - also the cart grand total is calculated and can be "tracked" back to the item row prices.
   144  
   145  In order to get consistent sub totals in the cart, the cart model needs certain invariants to be matched:
   146  * Item level: RowPriceNet + TotalTaxAmount = RowPriceGross
   147  * Item level: TotalDiscount <= RowPriceGross
   148  * All main prices need to have same currency (that may be extended later but currently it is a constraint)
   149  
   150  ### About Tax calculation in general
   151  
   152  It makes sense to understand the details of tax calculations - so please take the following example of a cart with 2 items:
   153  * item1 net price 14,71
   154  * item2 net price 10,18
   155  * and a 19% VAT (G.S.T)
   156  
   157  There are two principal ways of tax calculations (called vertical and horizontal)
   158  * vertical: the final tax is calculated from the sum of all rounded item taxes: 
   159      * item1 +19% gross price rounded: 17,50 (tax 2,79)
   160      * item2 +19% gross price rounded: 12,11 (tax 1,93)
   161      * = GrandTotal = 29,61 / = totalTax: 4,72
   162      * => SubTotalNet = 24,89
   163      * Often preferred for B2C, when the item prices are shown as gross prices first.
   164      * Pro: Easier to calculate 
   165      * Con: rounding errors may sum up in big orders
   166      
   167  * horizontal: The final tax is calculated from the sum of all net prices of the item and then rounded
   168      * => SubTotalNet: 24,89  => +19% rounded GrandTotal: 29,62 / included Tax: 4,73
   169      * Often preferred for B2B or when the prices shown to the customer are as net prices at first.
   170  
   171  * In both cases the tax might be calculated from a given net price or a given gross price (see product package config `commerce.product.priceIsGross`).
   172  
   173  * discounts are normally subtracted before tax calculation
   174  
   175  * At least in germany the law doesn't force one algorithm over the other. In this cart module it is up to the cart behaviour implementation what algorithm it uses to fill the tax.
   176  
   177  
   178  ### Cartitems - price fields and method 
   179  
   180  The Key with "()" in the list are methods and it is assumed as an invariant, that all prices in an item have the same currency.
   181  
   182  | Key                                  | Desc                                                                                                                                                                                                                                                                    | Math Invariants                                                                    |
   183  |--------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------|
   184  | SinglePriceGross                     | Single price of product (gross) (was SinglePrice)                                                                                                                                                                                                                       |                                                                                    |
   185  | SinglePriceNet                       | Net price (excl. taxes) for the product                                                                                                                                                                                                                                 |                                                                                    |
   186  | Qty                                  | Quantity                                                                                                                                                                                                                                                                |                                                                                    |
   187  | RowPriceGross                        | Price incl. taxes for the whole Qty of products (was RowTotal)                                                                                                                                                                                                          | SinglePriceGross * Qty                                                             |
   188  | RowPriceGrossWithDiscount            | Price incl. taxes with deducted discounts for the whole Qty of products. This is in most cases the final price for the customer to pay.                                                                                                                                 | RowPriceGross-TotalDiscountAmount()                                                |
   189  | RowPriceGrossWithItemRelatedDiscount | Price incl. taxes with deducted item related discounts for the whole Qty of products                                                                                                                                                                                    | RowPriceGross-ItemRelatedDiscountAmount()                                          |
   190  | RowPriceNet                          | Price excl. taxes for the whole Qty of products                                                                                                                                                                                                                         | SinglePriceNet * Qty                                                               |
   191  | RowPriceNetWithDiscount              | The discounted net price for the whole Qty of products                                                                                                                                                                                                                  |                                                                                    |
   192  | RowPriceNetWithItemRelatedDiscount   | price excl. taxes with deducted item related discounts for the whole Qty of products                                                                                                                                                                                    |                                                                                    |
   193  | RowTaxes                             | Collection of all taxes applied for the given Qty of products                                                                                                                                                                                                           |                                                                                    |
   194  | TotalTaxAmount()                     | sum of all applied taxes for the whole Qty of products                                                                                                                                                                                                                  | RowPriceGross-RowPriceNet                                                          |
   195  | AppliedDiscounts                     | List with the applied Discounts for this Item  (There are ItemRelated Discounts and Discounts that are not ItemRelated (CartRelated). However it is important to know that at the end all DiscountAmounts are applied to an item (to make refunding logic easier later) |                                                                                    |
   196  | TotalDiscountAmount                  | Sum of all applied discounts (aka the savings for the customer)                                                                                                                                                                                                         | Sum of AppliedDiscounts (ItemRelatedDiscountAmount + NonItemRelatedDiscountAmount) |
   197  | ItemRelatedDiscountAmount            | Sum of all itemrelated Discounts, e.g. promo due to product attribute                                                                                                                                                                                                                                        |                                                                                    |
   198  | NonItemRelatedDiscountAmount         | Sum of non-itemrelated Discounts, e.g. a general promo                                                                                                                                                                                                                                      |                                                                                    |
   199  
   200  [comment]: <> (use https://www.tablesgenerator.com/markdown_tables to update the table)
   201  
   202  ### Delivery - price fields and method 
   203  
   204  | Key                             | Desc                                                                             | Math                                                             |
   205  |---------------------------------|----------------------------------------------------------------------------------|------------------------------------------------------------------|
   206  | GrandTotal                      | The final amount that need to be paid by the customer (Gross)                    | SubTotalGross + ShippingItem.PriceGross + TotalDiscountAmount    |
   207  | SubTotalGross                   | Sum of items RowPriceGross (without shipping/discounts)                          |                                                                  |
   208  | SubTotalGrossWithDiscounts      | Sum of row gross prices reduced by the applied discounts                         | SubTotalGross() + SumSubTotalDiscountAmount()                    |
   209  | SubTotalNetWithDiscounts        | Sum of row net prices reduced by the net value of the applied discounts          | SubTotalNet() + SumSubTotalDiscountAmount()                      |
   210  | SubTotalNet                     | Sum of items RowPriceNet                                                         |                                                                  |
   211  | SumRowTaxes()                   | List of the sum of the different RowTaxes (of cart items)                        |                                                                  |
   212  | SumTotalTaxAmount()             | Sum of all applied item taxes including shipping taxes                           |                                                                  |
   213  | TotalDiscountAmount             | Sum off all discounts affecting the delivery (on cart items and shipping)        | SumSubTotalDiscountAmount + shippingItem.AppliedDiscounts.Sum()  |
   214  | SubTotalDiscountAmount          | Sum of all cart items discounts (without shipping)                               | Sum of items TotalDiscountAmount                                 |
   215  | NonItemRelatedDiscountAmount    | Sum of discounts that are not related to the item (including shipping discounts) |                                                                  |
   216  | ItemRelatedDiscountAmount       | Sum of discounts that are related to the item (including shipping discounts)     |                                                                  |
   217  
   218  ### Cart - price fields and method 
   219  
   220  | Key                             | Desc                                                                                                           | Math                                                                         |
   221  |---------------------------------|----------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------|
   222  | GrandTotal                      | The final amount that need to be paid by the customer (gross)                                                  | SubtotalGrossWithDiscounts + SumShippingGrossWithDiscounts + Sum(Totalitems) |
   223  | Totalitems                      | List of (additional) Totalitems. Each have a certain type - you may want to show some of them in the frontend. |                                                                              |
   224  | SumShippingNet                  | Sum of all shipping costs                                                                                      | Sum of all deliveries shipping items PriceNet                                |
   225  | SumShippingNetWithDiscounts     | Sum of all shipping costs with all shipping discounts                                                          | SumShippingNet + Sum of all applied shipping discounts                       |
   226  | SumShippingGross                | Sum of all shipping costs including tax                                                                        | Sum of all deliveries shipping items PriceGross                              |
   227  | SumShippingGrossWithDiscounts   | Sum of all shipping costs with all shipping discounts including tax                                            | Sum of shipping items PriceGrossWithDiscounts                                |
   228  | SubTotalGross                   | Sum of all delivery subtotals (without shipping / discounts)                                                   | Sum of deliveries SubTotalGross                                              |
   229  | SubTotalNet                     | Sum of all delivery net subtotals (without shipping / discounts)                                               | Sum of deliveries SubTotalNet                                                |
   230  | SumTaxes()                      | The total taxes of the cart - as list of Tax                                                                   |                                                                              |
   231  | SumTotalTaxAmount()             | The overall Tax of cart                                                                                        |                                                                              |
   232  | SubTotalGrossWithDiscounts      | Sum of row gross prices reduced by the applied discounts                                                       | Sum of deliveries SubTotalGrossWithDiscounts                                 |
   233  | SubTotalNetWithDiscounts        | Sum of row net prices reduced by the net value of the applied discounts                                        | Sum of deliveries SubTotalNetWithDiscounts                                   |
   234  | TotalDiscountAmount             | Sum of all discounts (incl. shipping)                                                                          | Sum of deliveries TotalDiscountAmount                                        |
   235  | NonItemRelatedDiscountAmount    | Sum of discounts that are not related to the item (including shipping discounts)                               | Sum of deliveries NonItemRelatedDiscountAmount                               |
   236  | ItemRelatedDiscountAmount       | Sum of discounts that are related to the item (including shipping discounts)                                   | Sum of deliveries ItemRelatedDiscountAmount                                  |
   237  | TotalGiftCardAmount             | The part of GrandTotal which is paid by gift cards                                                             |                                                                              |
   238  | GrandTotalWithGiftCards         | The final amount with the applied gift cards subtracted. If there are no gift cards, equal to GrandTotal.      | GrandTotal - SumAppliedGiftCards                                             |
   239  | GetVoucherSavings()             | Returns the sum of Totalitems of type voucher                                                                  |                                                                              |
   240  
   241  ### Typical B2C vs B2B usecases
   242  
   243  B2C use cases:
   244  * The item price is with all fees (gross). The discount will be reduced from the price and all the fees, duty and net price will be calculated from this.
   245  * Typically you want to show per row:
   246      * SinglePriceGross
   247      * Qty
   248      * RowPriceGross
   249      * RowPriceGrossWithDiscount
   250  
   251  * The cart normally shows:
   252     * SubTotalGross
   253     * Carttotals (non taxable extra lines on cart level)
   254     * Shipping
   255     * The included Total Tax in Cart (SumTaxes) 
   256     * GrandTotal (is what the customer needs to pay at the end including all fees)
   257  
   258  B2B use cases:
   259  * The item price is without fees (net). The discount will be reduced and then the fees will be added to get the gross price. You probably do want to show per row:
   260      *  SinglePriceNet
   261      *  RowPriceNet
   262      *  RowPriceNetWithDiscount
   263      
   264  * The cart then normally shows:
   265     * SubTotalNet
   266     * Carttotals (non taxable extra lines on cart level)
   267     * Shipping
   268     * The included Total Tax in Cart (SumTaxes) 
   269     * GrandTotal (is what the customer need to pay at the end inkl all fees)
   270   
   271  ### Building a Cart with its deliveries and items
   272  
   273  The domain concept is that the cart is returned and updated by the "Cartservice" and the underlying modify behaviour, which is the main secondary port of the package that needs to be implemented (see below).
   274  All calculations for the public price fields must be done by the modify behaviour implementation.
   275   
   276  ### About charges
   277  
   278  If you have read the sections above you know about the different prices that are available at item, delivery and cart level and how they are calculated.
   279  
   280  There is something else that this cart model supports - we call it "charges". All the price amounts mentioned in the previous chapters represents the value of the items in the carts default currency.
   281  
   282  However this value need to be paid - when paying the value it can be that:
   283  - customer wants to pay with different payment methods (e.g. 50% of the value with PayPal and the rest with credit card)
   284  - also the value can be paid in a different currency
   285  
   286  
   287  The desired split of charges is saved on the cart with the "UpdatePaymentSelection" command.
   288  If you dont need the full flexibility of the charges, than you will simply always pay one charge that matches the grand total of your cart.
   289  Use the factory `NewDefaultPaymentSelection` for this, which also supports gift cards out of the box.
   290  
   291  The PaymentSelection supports the [Idempotency Key pattern](https://stripe.com/blog/idempotency), the `DefaultPaymentSelection` will generate a new random UUID v4 during creation.
   292  In cases of a payment error (e.g. aborted by customer / general error) the Idempotency Key needs to be regenerated to avoid a loop and enable the customer to retry the payment.
   293  The PaymentSelection therefore offers a `GenerateNewIdempotencyKey()` function, which should also called during generation of the PaymentSelection.
   294  
   295  If you want to use the feature it is important to know how the cart charge split should be generated:
   296  
   297  1. the product that is in the cart might require that his price is paid in certain charges. An example for this is products that need to be paid in miles.
   298  2. the customer might want to select a split by himself
   299  
   300  You can use the factory on the decorated cart to get a valid PaymentSelection based on the two facts
   301  
   302  It is also important to note that changes to the shopping cart may affect an existing PaymentSelection. We therefore recommend that you validate PaymentSelection after each shopping cart transaction.
   303  
   304  ## Domain - Secondary Ports
   305  
   306  ### Must Have Secondary Ports
   307  
   308  **GuestCartService, CustomerCartService (and ModifyBehavior)**
   309  
   310  `GuestCartService` and `CustomerCartService` are the two interfaces that act as secondary ports.
   311  They need to be implemented and registered:
   312  
   313  ```go
   314  injector.Bind((*cart.GuestCartService)(nil)).To(infrastructure.YourAdapter{})
   315  injector.Bind((*cart.CustomerCartService)(nil)).To(infrastructure.YourAdapter{})
   316  ```
   317  
   318  Most of the cart modification methods are part of the `ModifyBehaviour` interface - if you look at the secondary ports you will see, that they need to return an (initialized) implementation of the
   319  `ModifyBehaviour` interface - so in fact this interface needs to be implemented when writing an adapter as well.
   320  
   321  **in-memory cart adapter**
   322  There is a "DefaultCartBehaviour" implementation as part of the package. It allows basic cart operations with a cart that is stored in memory.
   323  Since the cart storage is not persisted in any way we currently recommend the usage only for demo / testing.
   324  
   325  The in memory adapter supports custom gift card / voucher logic by implementing the `GiftCardHandler` and `VoucherHandler` interfaces.
   326  
   327  **PlaceOrderService**
   328  
   329  There is also a `PlaceOrderService` interface as secondary port.
   330  Implement an adapter for it to define what should happen in case the cart is placed.
   331  
   332  There is a `EmailAdapter` implementation as part of the package, that sends out the content of the cart as mail.
   333  
   334  #### Optional Port: CartValidator
   335  
   336  The CartValidator interface defines an interface to validate the cart.
   337  
   338  If you want to register an implementation, it will be used to pass the validation results to the web view.
   339  Also the cart validator will be used by the checkout - to make sure only valid carts can be placed as order.
   340  
   341  #### Optional Port: ItemValidator
   342  
   343  ItemValidator defines an interface to validate an item **BEFORE** it is added to the cart.
   344  
   345  If an Item is not valid according to the result of the registered *ItemValidator* it will **not** be added to the cart.
   346  
   347  ### Store "any" data on the cart
   348  
   349  This package offers also a flexible way to store any additional objects on the cart:
   350  
   351  See this example:
   352  
   353  ```go
   354  type (
   355    // FlightData value object
   356    FlightData struct {
   357      Direction          string
   358      FlightNumber       string
   359    }
   360  )
   361  
   362  var (
   363    // need to implement the cart interface AdditionalDeliverInfo
   364    _ cart.AdditionalDeliverInfo = new(FlightData)
   365  )
   366  
   367  func (f *FlightData) Marshal() ([]byte, error) {
   368    return json.Marshal(f)
   369  }
   370  
   371  func (f *FlightData) Unmarshal(data []byte) error {
   372    return json.Unmarshal(data, f)
   373  }
   374  
   375  
   376  // Helper for storing additional data
   377  func StoreFlightData(duc *cart.DeliveryInfoUpdateCommand, flight *FlightData) ( error) {
   378    if flight == nil {
   379      return nil
   380    }
   381    return duc.SetAdditional("flight",flight)
   382  }
   383  
   384  // Helper for getting stored data:
   385  func GetStoredFlightData(d cart.DeliveryInfo) (*FlightData, error) {
   386    flight := new(FlightData)
   387    err := d.LoadAdditionalInfo("flight",flight)
   388    if err != nil {
   389      return nil,err
   390    }
   391    return flight, nil
   392  }
   393  ```
   394  
   395  ## Application Layer
   396  
   397  Offers the following services:
   398  
   399  * CartReceiverService:
   400      * Responsible to get the current users cart. This is either a GuestCart or a CustomerCart
   401      * Interacts with the local CartCache (if enabled)
   402  * CartService
   403      * All manipulation actions should go over this service (!)
   404      * Interacts with the local CartCache (if enabled)
   405  
   406  Example Sequence for AddToCart Application Services to
   407  
   408  ![Cart Flow](cart-flow.png)
   409  
   410  ### RestrictionService
   411  
   412  The Restriction Service provides a port for implementing product restrictions. By using Dingo multibinding to `cart.MaxQuantityRestrictor`,
   413  you can add your own restriction to the service. The Restriction Service is called during cart add / update item.
   414  
   415  The `Restrict` function returns a `RestrictionResult` containing information about the restriction. This `RestrictionResult` specifies whether a restriction applies,
   416  the maximum allowed quantity and the remaining difference in relation to the current cart.
   417  
   418  The Service itself consolidates the results of all bound restrictors and returns the most restricting result.
   419  
   420  ### Event Handling
   421  
   422  Event Handling is mainly concerned with the transformation of a guest shopping cart into a customer shopping cart.
   423  Various options are available for this. By default, the content of both shopping carts is merged.
   424  
   425  The following strategies can be set via the config `commerce.cart.mergeStrategy`:
   426  * `merge` (default): Merge the content of the guest and customer cart
   427  * `replace`: Replace the customer cart with the guest cart content
   428  * `none`: Don't do anything, guest cart is lost during customer sign-in.
   429  
   430  ## A typical Checkout "Flow"
   431  
   432  A checkout package would use the cart package for adding information to the cart, typically that would involve:
   433  
   434  * Checkout might want to update Items:
   435      * Set sourceId (Sourcing logic) on an item and then call `CartBehaviour.UpdateItem(item,itemId)`
   436  
   437  * Updating DeliveryInformation by calling `CartBehaviour.UpdateDeliveryInfo()`
   438      * (for updating ShippingAddress, WishDate, ...)
   439  
   440  * Optional updating Purchaser Infos by calling `CartBehaviour.UpdatePurchaser()`
   441  
   442  * Finish by calling `CartService.PlaceOrder(CartPayment)`
   443      * CartPayment is an object, which holds the information which Payment is used for which item
   444  
   445  ## Interface Layer
   446  
   447  ### Cart Controller
   448  
   449  The main Cart Controller expects the following templates by default:
   450  
   451  * checkout/cart
   452  * checkout/carterror
   453  
   454  The templates get the following variables passed:
   455  
   456  * DecoratedCart
   457  * CartValidationResult
   458  
   459  ### Cart template function
   460  
   461  Use the `getCart` template function to get the cart.
   462  Use the `getDecoratedCart` template function to get the decorated cart.
   463  
   464  ```pug
   465  -
   466    var cart = getCart()
   467    var decoratedCart = getDecoratedCart()
   468    var currentCount = decoratedCart.cart.getCartTeaser.itemCount
   469  ```
   470  
   471  ### Cart Ajax API
   472  
   473  There are also of course ajax endpoints, that can be used to interact with the cart directly from your browser and the javascript functionality of your template.
   474  To get an idea of all endpoints, have a look at the module.go, especially the apiRoutes method where endpoints are handled.
   475  
   476  
   477  ### GraphQL
   478  
   479  The module exposes most of its functionality also via GraphQL, have a look at the [schema](interfaces/graphql/schema.graphql) to see all available querys / mutations.