AEM (CQ) eCommerce Framework

Post on 08-May-2015

12.133 views 3 download

description

As part of Adobe Experience Manager, CQ 5.6 provides a new Commerce Framework to build Experience Driven Commerce websites on top of a 3rd party Commerce Platform. This session provides an overview of the framework from an architectural perspective and presents some details of the reference implementation, based on the JCR repository.

Transcript of AEM (CQ) eCommerce Framework

eCommerce Integration Framework

Paolo Mo!adelliAdobe Technical Marketing

Adobe® Marketing Cloud

Adobe® Experience Manager

CQ Gems

Commerce Integrated Platform

JCR repo product DB

Experience Manager PIM/ecommerce

surfer

content editor PIM editor

1 2

PIM synch

3

4

dynamic PIM

Commerce Integrated Platform

surfer

content editor PIM editor

1. Product display component2. Shopping cart3. Promotions and vouchers4. Catalog blueprints5. Check-out6. Search

1. Product information integrity2. Pricing3. Stock-keeping inventory4. Variations on shopping cart

AEM eCommerce Integration Modules

1. !e integration framework (API used for eCommerce implementations)

2. AEM native (JCR) implementation

3. hybris implementation

4. A number of out-of-the-box AEM components

5. Search (AEM, eCommerce, 3rd party)

6. Catalog management

7. Promotions management

8. Client context cart storeJCR repo product DB

Experience Manager PIM/ecommerce

Architecture of the Commerce Framework

AEM Commerce API

Implementation

AEM Commerce Components

AEM native impl

JCR Repository

hybris impl

hybris DB

other impl

other

eCommerce Engine Selection

CommerceService commerceService = resource.adaptTo(CommerceService.class);

CommerceSession session = commerceService.login(slingRequest, slingResponse);

Product baseProduct = resource.adaptTo(Product.class);

GeoImpl(geometrixx) hybrisImpl

(hybris)

otherImpl(xyz)

Site Component

OSGi container

bundle

bundlebundle

cq:commerceProvider = geometrixx

1

2

3

CommerceSession

• addCartEntry(Product product, int quantity);• modifyCartEntry(int entryNumber, int quantity);• deleteCartEntry(int entryNumber);

•updateOrderDetails(Map<String, String> orderDetails);•getOrderDetails();•submitOrder();

cart content

pricing

order details

•updateOrderDetails(Map<String, String> orderDetails);•getOrderDetails();•submitOrder();

CommerceSession is RESTful style (1)

CommerceSession is RESTful style (2)

ORDER%3a%3dorderId%253d9c1346bf-3813-4205-80ec-2fdfd1644143%7cCART%3a%3dquantity3%253d1%252cquantity0%253d1%252cquantity1%253d1%252cpromotionCoun

t%253d2%252cquantity2%253d1%252cvoucherCount%253d0%252cpromotion1%253d%252fcontent%252fcampaigns%252fgeometrixx-outdoors%252fcosy-up-to-winter%252fwinter-female%252fcosy-companions%252cpromotion0%253d%252fcontent

%252fcampaigns%252fgeometrixx-outdoors%252!ig-spender%252fordervalueover100%252ffree-shipping%252cproduct3%253d%252fcontent

%252fgeometrixx-outdoors%252fen%252fequipment%252fskiing%252#alifax-winter%252$cr%253acontent%252fpar%252fproduct%252cproduct0%253d%252fcontent

%252fgeometrixx-outdoors%252fen%252fwomen%252fcoats%252fcalgary-winter%252$cr%253acontent%252fpar%252fproduct%252f397122-s%252cproduct2%253d%252fcontent

%252fgeometrixx-outdoors%252fen%252fseasonal%252fwinter%252fequipment%252%amloops-snow%252$cr%253acontent%252fpar%252fproduct

%252f37924450-7%252centryCount%253d4%252cproduct1%253d%252fcontent%252fgeometrixx-outdoors%252fen%252fequipment%252fskiing%252%elowna-snow

%252$cr%253acontent%252fpar%252fproduct%7c

Name: CommercePersistence, Host: geometrixx.com, Path: /

CommerceSession is RESTful style (3)

public class AbstractJcrCommerceSession implements CommerceSession {

...

cartStore = ContextSessionPersistence.getStore(request, "CART", CommerceConstants.COMMERCE_COOKIE_NAME);

...

}

Products and Variants architecture:

- variant - color: purple- id: 397122.1

- variant - size: S

- variant - size: L

- variant - size: M

- variant - size: XL

- variant - color: purple-id: 397122.2- price: 199

- variant - size: S

- variant - size: L

- variant - size: M

- variant - size: XL

- type: product- axes: color, size - id: 397122- title: Saskatoon- price: 299

11

1

1 1

1 1

1 1

1 1

PIM Data & Product References

11

1

1 1

1 1

1 1

1 1

1 /etc/commerce/products 2 /content

Product interface

public interface Product extends Adaptable { public String getPath(); // path to speci!c variation public String getPagePath(); // path to presentation page for all variations public String getSKU(); // unique ID of speci!c variation public String getTitle(); // shortcut to getProperty(TITLE) public String getDescription(); // shortcut to getProperty(DESCRIPTION) public String getImageUrl(); // shortcut to getProperty(IMAGE_URL) public String get"umbnailUrl(); // shortcut to getProperty(THUMBNAIL_URL) public <T> T getProperty(String name, Class<T> type); public Iterator<String> getVariantAxes(); public boolean axisIsVariant(String axis); public Iterator<Product> getVariants(VariantFilter !lter) throws CommerceException;}

AxisFilter implements VariantFilter

public class AxisFilter implements VariantFilter { ...

public boolean includes(Product product) { ValueMap values = product.adaptTo(ValueMap.class); if(values != null) { String v = values.get(axis, String.class); return v != null && v == value; } return false; }}

Shopping Cart architecture (CommerceSession)

"e CommerceSession performs add, remove, etc."e CommerceSession also performs the various calculations on the cart."e CommerceSession also applies vouchers and promotions that have !red to the cart.

Pricing modi&ers:- Quantity discounts. - Different currencies.- VAT-liable and VAT-free.

session.calcCart()

protected void calcCart() { ... for (int i = 0; i < cart.size(); i++) { ... for (Promotion p : promotions) { try { PromotionHandler ph = p.adaptTo(PromotionHandler.class); PriceInfo discount = ph.applyCartEntryPromotion(this, p, entry); if (discount != null && discount.getAmount().compareTo(BigDecimal.ZERO) > 0) { ... entry.calcPrices(); ... } ... cartTotalPrice = cartTotalPrice.add(entry.getPriceInfo(new PriceFilter("POST_TAX", currencyCode)).get(0).getAmount()); } setPrice(new PriceInfo(cartPreTaxPrice, currency), "CART", "PRE_TAX"); setPrice(new PriceInfo(cartTax, currency), "CART", "TAX"); setPrice(new PriceInfo(cartTotalPrice, currency), "CART", "POST_TAX"); ... }

Shopping Cart architecture (Storage)

In AEM-native carts are stored in the ClientContext

Personalization should always be driven through the ClientContext.CommerceSession.addCartEntry()

Checkout architectureCart and Order Data

"e CommerceSession owns the three elements:

Cart contents Pricing "e order details

Cart contents

"e cart contents schema is !xed by the API: public void addCartEntry(Product product, int quantity); public void modifyCartEntry(int entryNumber, int quantity); public void deleteCartEntry(int entryNumber);

Pricing

"e pricing schema is also !xed by the API: public String getCartPreTaxPrice(); public String getCartTax(); public String getCartTotalPrice(); public String getOrderShipping(); public String getOrderTotalTax(); public String getOrderTotalPrice();

Checkout architecture (order details)

Order details are not !xed by the API: updateOrderDetails(Map<String, String> orderDetails);

Shipping options (and prices) depend on weight, delivery address, etc...

"e CommerceSession owns shipping pricing; to retrieve and update delivery details:updateOrder(Map<String, Object> delta)

Hands on

De!ning the scope

1. Build a new Commerce Implementation: “training”

2. Apply the new implementation to Geometrixx Outdoors

3. Store the cart data in the repository (/home/users/a/admin/commerce/cart)

adobe.com/go/gems@CQDev