Manages shopping carts (Cart) and their checkout, covering cart creation and lookup, adding and removing line items, applying voucher and promotion codes, running the payment provider checkout process, and recording fulfilment and product order status changes. It is registered as the "cartManager" service and is reached from JS by that name. Most methods operate on the current visitor's shopping cart, which is tracked with a browser cookie, or on an explicitly supplied Cart.

Group: Managers


Properties

PropertyReturnsDescription
cartStatesMap<String,String>The available cart states, keyed by their enum name, with a human-readable description as the value.
checkoutItemsCheckoutItemsThe checkout items for the current visitor's shopping cart, if one exists.
countOfUnfulfilledOrdersLongThe number of carts for the current tenant organisation that have been ordered but not yet fully fulfilled.
fulfilmentStatusesMap<String,String>The fulfilment statuses available for the current account: the built-in statuses, overridden or extended by any custom statuses configured in the products app settings.
paymentProvidersList<PaymentProviderApplication>The payment provider applications currently available for checkout.
shoppingCartIdStringThe cart id stored in the current visitor's shopping cart cookie, if any.

Methods

findRecurringTransactions(Profile purchaser) · findOrders(Profile customer) · findOrders(Profile customer, String sortByField) · findPendingOrders(Profile customer, String sortByField) · findVouchers(Cart cart) · toVoucherBean(Voucher v) · setFulfillmentStatus(Cart cart, String status) · setFulfillmentStatus(List<Cart> carts, String status) · newCart(Profile customer) · newCart(Profile customer, ECommerceStore store) · newCart(Profile customer, ECommerceStore store, Website website, boolean isPending) · getCart(long id) · countOfOrders(Date start, Date finish) · getCountOfUnfulfilledOrders() · searchCarts(String fulfilment, int max, String query) · searchCarts(String fulfilment, String sCartState, int max, String query) · searchCarts(Profile purchaser, ProductSku sku, String sCartState) · deleteCart(Cart cart) · applyPromoCodes(Cart cart, ECommerceStore store, List<String> codes) · doProcessCart(FormContext rc, CheckoutItems checkoutItems, Profile purchaser, String paymentProviderId) · doProcessRecurring(FormContext rc, Cart cart, List<CheckoutLineItem> recurringItems, Profile purchaser, String paymentProviderId) · getOrCreateCustomerGroup(String groupName) · getOrCreatePurchaser(FormContext rc, Group customerGroup) · placeOrder(Cart c, ECommerceStore store) · placeOrder(Cart c, ECommerceStore store, InventoryLocation loc) · getCheckoutItems() · checkoutItems(Lead lead) · findByCartId(String cartId) · findCart(Lead lead) · activeCheckoutRules(Cart cart) · activeCheckoutRules(ECommerceStore store) · checkoutItems(Cart cart) · checkoutItems(Cart cart, ECommerceStore store) · pendingShoppingCart(boolean autoCreate) · pendingShoppingCart(boolean autoCreate, ECommerceStore store) · setCurrentCartCookie(Cart cart) · shoppingCart(boolean autoCreate) · shoppingCart(boolean autoCreate, ECommerceStore store) · copyCart(Cart cart) · getShoppingCartId() · clearCart() · cartItemBuilder(Cart cart, ECommerceStore store) · findProductsNotInStore(Cart c, ECommerceStore store) · addOrUpdateItem(Cart cart, ProductSku sku, long quantity, ECommerceStore store, boolean increment) · addOrUpdateItem(Cart cart, ProductSku sku, BigDecimal quantity, ECommerceStore store, boolean increment) · addOrUpdateItem(Cart cart, Long skuId, BigDecimal quantity, ECommerceStore store, boolean increment) · addOrUpdateItem(Cart cart, long skuId, long quantity, ECommerceStore store, boolean increment) · removeItem(String lineId) · removeItem(String lineId, Cart cart) · getPaymentProviders() · numItemsInCart(Product p) · numItemsInCart(ProductSku sku) · promotions() · promotions(Boolean open, Date now) · getCartStates() · cartState(String name) · fulfilmentStatus(String name) · getFulfilmentStatuses() · cartDescription(ShoppingCartBean cart) · cartDescription(Cart cart) · findStore(CheckoutItems checkoutItems) · findStore(Cart cart) · quantityOfCategory(String catCode, List<CheckoutLineItem> items) · quantityOfProduct(String prodCode, List<CheckoutLineItem> items) · quantityOfProductSku(String skuCode, List<CheckoutLineItem> items) · containsCategory(String catCode, List<CheckoutLineItem> items) · containsProduct(String code, List<CheckoutLineItem> items) · containsProductSku(String code, List<CheckoutLineItem> items) · totalCostExTax(List<CheckoutLineItem> items) · totalCostIncTax(List<CheckoutLineItem> items) · getOrCreateProductOrderStatus(ProductOrder productOrder, Date date, String code) · findLastProductOrderStatus(ProductOrder productOrder) · createProductOrderStatus(ProductOrder productOrder, Date date, String code, String desc) · createProductOrderStatus(ProductOrder productOrder, Date date, String code, String desc, String refCode) · findProductOrderInCart(Cart cart, ProductSku productSku)

findRecurringTransactions(Profile purchaser)

Returns: List<RecurringTransaction>

Finds recurring transactions started by the given purchaser, most recent start date first. Looks up to 1000 results using the "recurringTransaction" criteria builder.

ParameterDescription
purchaserthe profile whose recurring transactions are being looked up

findOrders(Profile customer)

Returns: List<Cart>

Finds the completed or unspecified-state carts belonging to the given customer, sorted by order date, most recent first.

ParameterDescription
customerthe profile whose orders are being looked up

findOrders(Profile customer, String sortByField)

Returns: List<Cart>

Finds the completed or unspecified-state carts belonging to the given customer, sorted descending by the given field.

ParameterDescription
customerthe profile whose orders are being looked up
sortByFieldthe Cart property to sort the results by, descending

findPendingOrders(Profile customer, String sortByField)

Returns: List<Cart>

Finds the pending (not yet submitted) or unspecified-state carts belonging to the given customer, sorted descending by the given field.

ParameterDescription
customerthe profile whose pending orders are being looked up
sortByFieldthe Cart property to sort the results by, descending

findVouchers(Cart cart)

Returns: List<Voucher>

Finds all vouchers associated with the given cart.

ParameterDescription
cartthe cart whose vouchers are being looked up

toVoucherBean(Voucher v)

Returns: VoucherBean

Wraps the given voucher in a VoucherBean, which can be a bit easier to work with in templates and scripts than the underlying entity.

ParameterDescription
vthe voucher to wrap

setFulfillmentStatus(Cart cart, String status)

Returns: void

Sets the fulfilment status on the given cart as a whole. Does nothing if cart is null, or if the given status matches the cart's current fulfilment status. Otherwise it saves the change and fires a ShoppingCartFulfillmentStatusEvent.

ParameterDescription
cartthe cart to update, or null to do nothing
statusthe new fulfilment status code to set

setFulfillmentStatus(List<Cart> carts, String status)

Returns: void

Sets the given fulfilment status on each of the given carts in turn.

ParameterDescription
cartsthe carts to update
statusthe new fulfilment status code to set on each cart

newCart(Profile customer)

Returns: Cart

Creates a new pending cart for the given customer in the current website.

ParameterDescription
customerthe profile the new cart is created for

newCart(Profile customer, ECommerceStore store)

Returns: Cart

Creates a new pending cart for the given customer, in the website that the given store is attached to.

ParameterDescription
customerthe profile the new cart is created for
storethe store the cart is created for, whose website the cart belongs to

newCart(Profile customer, ECommerceStore store, Website website, boolean isPending)

Returns: Cart

Creates a new cart for the given customer in the given website, either pending or already submitted.

ParameterDescription
customerthe profile the new cart is created for
storethe store the cart is created for, may be null
websitethe website the cart belongs to
isPendingtrue to create a pending (in-progress) cart, false to create an already-submitted one

getCart(long id)

Returns: Cart

Looks up a cart by its internal database id, scoped to the current tenant organisation.

ParameterDescription
idthe internal id of the cart

countOfOrders(Date start, Date finish)

Returns: Long

Counts new orders (carts) created between the given start and end dates, for the current tenant organisation.

ParameterDescription
startthe start of the date range, inclusive
finishthe end of the date range, inclusive

getCountOfUnfulfilledOrders()

Returns: Long

The number of carts for the current tenant organisation that have been ordered but not yet fully fulfilled.

searchCarts(String fulfilment, int max, String query)

Returns: List<Cart>

Searches submitted carts (ie purchases) with a completed cart state, for the current tenant organisation and common date range.

ParameterDescription
fulfilmentthe fulfilment status to filter by, or blank to not filter on fulfilment status
maxthe maximum number of results to return
queryfree text search query, may be blank

searchCarts(String fulfilment, String sCartState, int max, String query)

Returns: List<Cart>

Searches submitted carts for the current tenant organisation and common date range, filtering by fulfilment status and cart state.

ParameterDescription
fulfilmentthe fulfilment status to filter by, or blank to not filter on fulfilment status
sCartStatethe name of the cart state to filter by, or blank to default to COMPLETED
maxthe maximum number of results to return
queryfree text search query, may be blank

searchCarts(Profile purchaser, ProductSku sku, String sCartState)

Returns: List<Cart>

Finds the carts in which the given purchaser bought the given SKU, filtered by cart state.

ParameterDescription
purchaserthe profile who made the purchase
skuthe product SKU that was purchased
sCartStatethe name of the cart state to filter by, or blank to default to COMPLETED

deleteCart(Cart cart)

Returns: void

Physically deletes the given cart together with its product orders, and removes any references to it from cart promotions, payment item lists and reward entries.

ParameterDescription
cartthe cart to delete

applyPromoCodes(Cart cart, ECommerceStore store, List<String> codes)

Returns: List<PromoCodeResult>

Applies voucher and promotion codes to a pending cart. Each code is checked against available vouchers first, then against available promotions, and a result is returned for each code that matched. Throws if the cart has already been submitted.

ParameterDescription
cartthe pending cart to apply the codes to
storethe store the cart belongs to, used when applying a matching voucher
codesthe voucher or promotion codes to apply

doProcessCart(FormContext rc, CheckoutItems checkoutItems, Profile purchaser, String paymentProviderId)

Returns: PaymentResult

Runs the checkout process for the given cart's items against the named payment provider: validates the items are still available in the store, then delegates to the provider to take payment. Exceptions are caught and rolled back into a failed PaymentResult rather than propagated.

ParameterDescription
rcthe current form context, supplying request parameters to the payment provider
checkoutItemsthe items being checked out
purchaserthe profile making the purchase
paymentProviderIdthe instance id of the payment provider to process the payment with

doProcessRecurring(FormContext rc, Cart cart, List<CheckoutLineItem> recurringItems, Profile purchaser, String paymentProviderId)

Returns: PaymentResult

Starts a recurring payment subscription for the given cart's recurring line items, which must all share the same repeat interval. Validates the purchaser, payment provider, and repeat intervals before delegating to the provider to initiate the recurring transaction.

ParameterDescription
rcthe current form context, supplying request parameters to the payment provider
cartthe cart the recurring items belong to
recurringItemsthe recurring line items to subscribe to, which must all use the same repeat interval
purchaserthe profile the subscription is created for
paymentProviderIdthe instance id of the payment provider to process the subscription with

getOrCreateCustomerGroup(String groupName)

Returns: Group

Finds the customer group with the given name in the current organisation, creating it if it does not already exist.

ParameterDescription
groupNamethe name of the customer group to find or create

getOrCreatePurchaser(FormContext rc, Group customerGroup)

Returns: Profile

Returns the current signed-in profile if there is one, otherwise creates a new profile from the request parameters, adds it to the given customer group, and signs it in as the current principal.

ParameterDescription
rcthe current form context, supplying the request parameters used to create a new profile
customerGroupthe group a newly created profile is added to

placeOrder(Cart c, ECommerceStore store)

Returns: void

Submits the given cart as a completed order, with no inventory location check.

ParameterDescription
cthe cart to place as an order
storethe store the cart belongs to

placeOrder(Cart c, ECommerceStore store, InventoryLocation loc)

Returns: void

Submits the given cart as a completed order: validates the items are still in the store, fires a before-checkout event so apps can reject the order, prices and saves each product order, redeems any applied vouchers, marks the cart completed, optionally checks and decrements stock, and fires related-product and shopping cart events. Throws if any validation step fails.

ParameterDescription
cthe cart to place as an order
storethe store the cart belongs to
locoptional inventory location. If given, stock at this location is checked for sufficient quantity and decremented; if null no stock check is performed

getCheckoutItems()

Returns: CheckoutItems

The checkout items for the current visitor's shopping cart, if one exists.

checkoutItems(Lead lead)

Returns: CheckoutItems

Finds the checkout items for the cart referenced by the given lead's cart id attribute.

ParameterDescription
leadthe lead whose associated cart is being looked up

findByCartId(String cartId)

Returns: Cart

Finds a cart by its portable string identifier, scoped to the current tenant organisation.

ParameterDescription
cartIdthe string identifier of the cart (its cart id), not its internal database id

findCart(Lead lead)

Returns: Cart

Finds the cart referenced by the given lead's cart id attribute.

ParameterDescription
leadthe lead whose associated cart is being looked up

activeCheckoutRules(Cart cart)

Returns: List<CheckoutRule>

The checkout rules that apply to the store the given cart belongs to.

ParameterDescription
cartthe cart whose store's checkout rules are being looked up

activeCheckoutRules(ECommerceStore store)

Returns: List<CheckoutRule>

The checkout rules that apply to the given store: the built-in voucher and free gift rules, plus any custom checkout rules configured in the store's pricing rules.

ParameterDescription
storethe store whose checkout rules are being looked up, may be null

checkoutItems(Cart cart)

Returns: CheckoutItems

Builds the checkout items for the given cart, resolving its store automatically.

ParameterDescription
cartthe cart to build checkout items for

checkoutItems(Cart cart, ECommerceStore store)

Returns: CheckoutItems

Builds the checkout items for the given cart: one line item per product order, plus any extra items added by active checkout rules (vouchers, free gifts, custom rules) while the cart is still pending. Line items are sorted so ordinary items are listed before promotional ones.

ParameterDescription
cartthe cart to build checkout items for
storethe store the cart belongs to, used to resolve applicable checkout rules

pendingShoppingCart(boolean autoCreate)

Returns: Cart

Returns the current visitor's pending shopping cart, replacing it with a newly created one if the existing cart has already been submitted.

ParameterDescription
autoCreatetrue to create a new cart if none is found, false to return null instead

pendingShoppingCart(boolean autoCreate, ECommerceStore store)

Returns: Cart

Returns the current visitor's pending shopping cart, generating its cart id from the given store's order id template if a new cart needs to be created, and replacing the cart with a newly created one if the existing cart has already been submitted.

ParameterDescription
autoCreatetrue to create a new cart if none is found, false to return null instead
storethe store to use when generating the cart id for a newly created cart, may be null

setCurrentCartCookie(Cart cart)

Returns: void

Sets the browser cookie that tracks the current visitor's shopping cart to the given cart's cart id.

ParameterDescription
cartthe cart to remember as the current shopping cart

shoppingCart(boolean autoCreate)

Returns: Cart

The persisted cart for the current visitor, containing the product orders representing each item they have added to their shopping cart. Generally checkoutItems should be used instead of calling this directly.

ParameterDescription
autoCreatetrue to create a new pending cart if none is found, false to return null instead

shoppingCart(boolean autoCreate, ECommerceStore store)

Returns: Cart

The persisted cart for the current visitor, containing the product orders representing each item they have added to their shopping cart. Generally checkoutItems should be used instead of calling this directly. Locates the cart from the current cart cookie or, failing that, from the current profile; validates its shipping provider and selects a default one if possible. If store is given, a newly created cart's id is generated from the store's order id template where possible.

ParameterDescription
autoCreatetrue to create a new pending cart if none is found, false to return null instead
storethe store to use when generating the cart id for a newly created cart, may be null

copyCart(Cart cart)

Returns: Cart

Duplicates the given cart into a new cart with a freshly generated cart id, noting the source order in the new cart's order notes.

ParameterDescription
cartthe cart to copy

getShoppingCartId()

Returns: String

The cart id stored in the current visitor's shopping cart cookie, if any.

clearCart()

Returns: void

Clears the current visitor's shopping cart and cart id cookies. Only clears cookies when in a website context, not in the admin area.

cartItemBuilder(Cart cart, ECommerceStore store)

Returns: CartItemBuilder

Creates a builder for adding or updating a line item in the given cart.

ParameterDescription
cartthe pending cart to build a line item for
storethe store the item is being purchased from

findProductsNotInStore(Cart c, ECommerceStore store)

Returns: List<Product>

Finds the products in the given cart's line items that are not available in the given store, ie that have no matching ProductInEComStore entry.

ParameterDescription
cthe cart whose line items are being checked, may be null or empty
storethe store to check the cart's products against

addOrUpdateItem(Cart cart, ProductSku sku, long quantity, ECommerceStore store, boolean increment)

Returns: Cart

Adds the given SKU to the cart, or updates its quantity if it is already present.

ParameterDescription
cartthe pending cart to update
skuthe SKU to add or update, must not be null
quantitythe quantity to set, or add if increment is true
storethe store the item is being purchased from
incrementtrue to add to the existing quantity, false to replace it

addOrUpdateItem(Cart cart, ProductSku sku, BigDecimal quantity, ECommerceStore store, boolean increment)

Returns: Cart

Adds the given SKU to the cart, or updates its quantity if it is already present.

ParameterDescription
cartthe pending cart to update
skuthe SKU to add or update
quantitythe quantity to set, or add if increment is true
storethe store the item is being purchased from
incrementtrue to add to the existing quantity, false to replace it

addOrUpdateItem(Cart cart, Long skuId, BigDecimal quantity, ECommerceStore store, boolean increment)

Returns: Cart

Adds the SKU with the given id to the cart, or updates its quantity if it is already present. Validates that the SKU belongs to the current account before adding it.

ParameterDescription
cartthe pending cart to update
skuIdthe internal id of the SKU to add or update
quantitythe quantity to set, or add if increment is true
storethe store the item is being purchased from, used to resolve the account to validate the SKU against
incrementtrue to add to the existing quantity, false to replace it

addOrUpdateItem(Cart cart, long skuId, long quantity, ECommerceStore store, boolean increment)

Returns: Cart

Adds the SKU with the given id to the cart, or updates its quantity if it is already present. Validates that the SKU belongs to the current account before adding it.

ParameterDescription
cartthe pending cart to update
skuIdthe internal id of the SKU to add or update
quantitythe quantity to set, or add if increment is true
storethe store the item is being purchased from, used to resolve the account to validate the SKU against
incrementtrue to add to the existing quantity, false to replace it

removeItem(String lineId)

Returns: boolean

Removes the line item with the given id from the current visitor's shopping cart. Does nothing if there is no current cart or if it is not pending.

ParameterDescription
lineIdthe id of the line item to remove, either a product order id or a "voucher" prefixed voucher id

removeItem(String lineId, Cart cart)

Returns: boolean

Removes the line item with the given id from the given cart. The id may identify either a product order or an applied voucher, which is unallocated rather than deleted.

ParameterDescription
lineIdthe id of the line item to remove, either a product order id or a "voucher" prefixed voucher id
cartthe cart to remove the item from

getPaymentProviders()

Returns: List<PaymentProviderApplication>

The payment provider applications currently available for checkout.

numItemsInCart(Product p)

Returns: BigDecimal

The total quantity of the given product in the current visitor's shopping cart, summed across all of the product's SKUs.

ParameterDescription
pthe product to total the quantity of

numItemsInCart(ProductSku sku)

Returns: BigDecimal

The total quantity of the given SKU in the current visitor's shopping cart.

ParameterDescription
skuthe SKU to total the quantity of

promotions()

Returns: List<Reward>

All promotions configured for the current account.

promotions(Boolean open, Date now)

Returns: List<Reward>

Finds promotions for the current account, optionally filtered to those open at the given date.

ParameterDescription
openif true, only promotions open at the given date are returned; if null or false, all promotions are returned
nowthe date to check promotions are open at, when open is true

getCartStates()

Returns: Map<String,String>

The available cart states, keyed by their enum name, with a human-readable description as the value.

cartState(String name)

Returns: ShoppingCartState

Parses the given cart state name into its enum representation, which can be used in KCriteria.

ParameterDescription
namethe name of the cart state, must match one of the ShoppingCartState enum values

fulfilmentStatus(String name)

Returns: FULFILMENT_STATUS_CODE

Parses the given fulfilment status name into its enum representation, which can be used in KCriteria.

ParameterDescription
namethe name of the fulfilment status, must match one of the FULFILMENT_STATUS_CODE enum values

getFulfilmentStatuses()

Returns: Map<String,String>

The fulfilment statuses available for the current account: the built-in statuses, overridden or extended by any custom statuses configured in the products app settings.

cartDescription(ShoppingCartBean cart)

Returns: String

Builds a description of the items in the given shopping cart bean's underlying cart.

ParameterDescription
cartthe shopping cart bean to describe

cartDescription(Cart cart)

Returns: String

Builds a description of the items in the given cart, eg "2 x Widget, Gadget", listing the product title (or SKU's product title) for each product order and its quantity where more than one.

ParameterDescription
cartthe cart to describe

findStore(CheckoutItems checkoutItems)

Returns: ECommerceStore

Finds the store the given checkout items' cart was purchased from. The cart does not directly hold a reference to its store, so this is resolved from its product orders.

ParameterDescription
checkoutItemsthe checkout items whose store is being looked up

findStore(Cart cart)

Returns: ECommerceStore

Finds the store the given cart was purchased from. The cart does not directly hold a reference to its store, so this is resolved first from its product orders, falling back to the first store found on its website.

ParameterDescription
cartthe cart whose store is being looked up

quantityOfCategory(String catCode, List<CheckoutLineItem> items)

Returns: BigDecimal

Totals the quantity of the given line items whose product has the given category.

ParameterDescription
catCodethe category code to match products against
itemsthe checkout line items to total

quantityOfProduct(String prodCode, List<CheckoutLineItem> items)

Returns: BigDecimal

Totals the quantity of the given line items whose product has the given name.

ParameterDescription
prodCodethe product name to match against
itemsthe checkout line items to total

quantityOfProductSku(String skuCode, List<CheckoutLineItem> items)

Returns: BigDecimal

Totals the quantity of the given line items whose SKU has the given name.

ParameterDescription
skuCodethe SKU name to match against
itemsthe checkout line items to total

containsCategory(String catCode, List<CheckoutLineItem> items)

Returns: boolean

Checks whether any of the given line items belong to the given category.

ParameterDescription
catCodethe category code to check for
itemsthe checkout line items to check

containsProduct(String code, List<CheckoutLineItem> items)

Returns: boolean

Checks whether any of the given line items are for the product with the given name.

ParameterDescription
codethe product name to check for
itemsthe checkout line items to check

containsProductSku(String code, List<CheckoutLineItem> items)

Returns: boolean

Checks whether any of the given line items are for the SKU with the given name.

ParameterDescription
codethe SKU name to check for
itemsthe checkout line items to check

totalCostExTax(List<CheckoutLineItem> items)

Returns: BigDecimal

Totals the tax-exclusive final price of the given line items.

ParameterDescription
itemsthe checkout line items to total

totalCostIncTax(List<CheckoutLineItem> items)

Returns: BigDecimal

Totals the tax-inclusive final cost of the given line items.

ParameterDescription
itemsthe checkout line items to total

getOrCreateProductOrderStatus(ProductOrder productOrder, Date date, String code)

Returns: ProductOrderStatus

Finds the status entry with the given date and code on the given product order, creating one with the code used as its description if none is found.

ParameterDescription
productOrderthe product order to find or create a status entry on
datethe date of the status entry
codethe status code to find or create

findLastProductOrderStatus(ProductOrder productOrder)

Returns: ProductOrderStatus

Finds the most recent status entry recorded against the given product order.

ParameterDescription
productOrderthe product order whose status history is being looked up

createProductOrderStatus(ProductOrder productOrder, Date date, String code, String desc)

Returns: ProductOrderStatus

Adds a status entry to the given product order and fires a ProductOrderStatusEvent.

ParameterDescription
productOrderthe product order to add a status entry to
datethe date of the status entry
codethe status code
desca human-readable description of the status

createProductOrderStatus(ProductOrder productOrder, Date date, String code, String desc, String refCode)

Returns: ProductOrderStatus

Adds a status entry to the given product order, with an external reference code, and fires a ProductOrderStatusEvent.

ParameterDescription
productOrderthe product order to add a status entry to
datethe date of the status entry
codethe status code
desca human-readable description of the status
refCodean external reference code associated with the status, may be null

findProductOrderInCart(Cart cart, ProductSku productSku)

Returns: ProductOrder

Finds the existing product order for the given SKU in the given cart.

ParameterDescription
cartthe cart to search
productSkuthe SKU to find a matching product order for
To get full access to the Kademi Hub existing customers can login here, or new customers can register here.