Basket Management / Line Item Display

Displaying and managing line items involves creating and sending BasketItem subclass instances to the POI.

 @startuml
 !include uml_styles.iuml
 hide footbox

 actor Cashier order 10
 participant POS order 20
 participant PSDK order 30
 |||
 ...
 POS <- PSDK: CommerceEvent.SESSION_STARTED
 POS <-> PSDK: transactionManager.getBasketManager()

 loop until basket is built
   Cashier -> POS: Select item for basket
   POS -> POS: Create Merchandise object and update calculate basket amount total.
   POS ->> PSDK: basketManager.addMerchandise(merchandise, amountTotal)
   POS <- PSDK: BasketEvent.TYPE with BasketAction.ADDED and the updated items.
   ...add/modify/remove additional items...
 end

 POS ->> PSDK: basketManager.finalizeBasket()
 ...basket adjudication, refer to advanced flows...
 POS <- PSDK: BasketEvent.TYPE with BasketAction.FINALIZED.

 POS -> POS: Setup amount totals and payment
 POS ->> PSDK: mTransactionManager.startPayment()
 ...
 |||
 @enduml

Basket Manager Lifecycle

It’s important to only retrieve the basket manager after a session is started, it is only valid within the context of a session. When a new session is started, a new basket manager should be retrieved, they must not be reused across sessions.

Finishing a Basket

When all of the items are added, it is important to call BasketManager.finalizeBasket() to indicate that the basket is complete. It is still possible to add, modify, or remove items after the basket is finalized, to support those scenarios where the cashier or customer forgot to include something, but if the basket is modified again, the basket should be finalized again.

Restoring a Basket from a Previous Order

A Basket can be restored in one action using BasketManager.registerBasket(basket, amountTotals). This takes all of the items in that basket object and places them on the POI display screen, simplifying the task of re-adding each item from a saved cart. The current Basket can be retrieved using BasketManager.getBasket(), kept locally, and then registered later if this is simpler, or a new Basket object can be populated and then registered.



Best Practices

Adding/Display Items Quickly

Adding items to the display can take a bit of time. Generally cashiers can add items faster than the display can update, so it’s best to add as soon as the cashier enters it, then queue up additional items while waiting for the BasketEvent to arrive. Once the event arrives, add all of the items in the queue at once, since the methods allow for arrays of items to be sent.

Modifying/Removing Items

It’s important to either set the ID using BasketItem.setBasketItemId(...) explicitly or to match the ID returned by the BasketEvent once the item is added. Setting the Basket Item ID explicitly makes it much simpler to later modify or remove the item, since that’s the only reference the payment service has to know which item ought to be modified or removed, since other system identifying information is lost when the object is sent between processes. See Separate Processes means Separate Objects for more information.

Providing the Amount Total

The current running total must be provided with every basket action, allowing the POI display to stay accurate with the items. Neither the payment service nor the POI want to do any math to track the current running total, this must be provided by the POS for the most accurate results.



Basket Item Objects

Basket items are tracked using the BasketItem.getBasketItemId() ID. This ID is automatically created by the service if not already set, and is provided back in the BasketEvent when the item is placed in the basket. This is an important ID, since modifying or removing the item later depends on this field.

Setting the Display Line determines what is shown on the line item display, with an optional Description field being displayed in different text directly below the item. If the Display Line is not provided, it will automatically look to the Name and then the Description to determine what to show to the user.

Note

The payment service runs in a separate process, which means that setting fields on an object in the SDK does not automatically set those fields in the service. In order to carry those changes across, the object must be sent to the service using one of the methods listed.

See also

AmountTotals

Provides an object to contain all of the relevant fields for an item. This is the best way to set the value of an item before sending it, allowing the granular amounts to be communicated when payment is being processed. In some regions, the tax data per item is required, so including this information can ease the work transitioning between regions.

When setting an AmountTotals object on a BasketItem, the other amounts on the BasketItem do not need to be set. The AmountTotals for a BasketItem should only be the amounts for that display line, e.g., if there is a quantity of 4, the AmountTotals should be the total amount for that display line, but should not be the cart total. Gratuity is not expected for basket items.

The amounts can be positive or negative, depending on the purpose. It’s generally useful to set a negative amount for returned merchandise and offers, while positive amounts will be used in most other cases.

See also

Merchandise

Represents normal cart items, such as a chocolate bar, iced coffee, or hat. Allows quantity, unit price, unit of measurement, and extended price in addition to the fields provided by BasketItem.

Many of the different use cases can be satisfied by only using this object, the others are optional, but can provide a better display to the customer when used.

Modifier

Modifies the merchandise to which it is attached. This cannot be sent on its own, it can only be linked to merchandise already in the cart. This is good to show the build of a merchandise, such as adding chocolate sauce to an iced coffee for an additional fee, or specifying that the hat was of a medium size without any additional fee.

Offer

An offer is used to provide some discount or award. There are many types of offers, enumerated by Offer.OfferType. Most of the fields are optional. The amount should be specified as negative if it is reducing the total cost, the payment service and payment app will not modify it. If this offer is linked to a specific item in the basket, use Offer.setReferenceBasketLineItemId(...) to match it to the item.

Donation

Identifies an amount that is to be donated.