eCommerce 프레임워크는 모든 eCommerce 솔루션에서 사용할 수 있습니다. 여기서 다루는 특정 세부 사항 및 예는 hybris 솔루션.
통합 프레임워크는 API와 통합 레이어를 포함합니다. 이를 통해 다음을 수행할 수 있습니다.
API 설명서 도 사용할 수 있습니다.
통합 레이어를 사용하기 위해 즉시 사용 가능한 여러 AEM 구성 요소가 제공됩니다. 현재는 다음과 같습니다.
검색 시 AEM 검색, eCommerce 시스템 검색, 타사 검색 또는 이들의 조합을 사용할 수 있는 통합 후크가 제공됩니다.
eCommerce 프레임워크는 모든 eCommerce 솔루션에서 사용할 수 있으며, 사용 중인 엔진을 AEM에서 확인해야 합니다.
eCommerce Engine은 CommerceService
인터페이스
commerceProvider
서비스 속성AEM 지원 Resource.adaptTo()
대상 CommerceService
및 Product
다음 adaptTo
구현에서 cq:commerceProvider
리소스 계층 구조의 속성:
A cq:Commerce
mixin이 사용되므로 cq:commerceProvider
강력한 형식의 리소스에 추가할 수 있습니다.
다음 cq:commerceProvider
속성은 적절한 상거래 공장 정의를 참조하는 데에도 사용됩니다.
예: cq:commerceProvider
값이 있는 속성 hybris
은 의 OSGi 구성과 상호 연결됩니다. Hybris용 Day CQ Commerce Factory (com.adobe.cq.commerce.hybris.impl.HybrisServiceFactory) - 여기서 매개 변수 commerceProvider
에도 값이 있습니다 hybris
.
여기에는 다음과 같은 추가 속성이 있습니다 카탈로그 버전 구성할 수 있습니다(적절하고 사용 가능한 경우).
아래 예를 참조하십시오.
cq:commerceProvider = geometrixx |
표준 AEM 설치에서는 특정 구현이 필요합니다. 예를 들어, geometrixx 예에서는 일반 API에 대한 최소 확장 기능을 포함합니다 |
---|---|
cq:commerceProvider = hybris |
hybris 구현 |
/content/store
+ cq:commerceProvider = hybris
+ mens
+ polo-shirt-1
+ polo-shirt-2
+ employee
+ cq:commerceProvider = jcr
+ adobe-logo-shirt
+ cq:commerceType = product
+ price = 12.50
+ adobe-logo-shirt_S
+ cq:commerceType = variant
+ size = S
+ adobe-logo-shirt_XL
+ cq:commerceType = variant
+ size = XL
+ price = 14.50
CRXDE Lite을 사용하면 hybris 구현을 위한 제품 구성 요소에서 이 작업이 처리되는 방식을 확인할 수 있습니다.
/apps/geometrixx-outdoors/components/hybris/product/product.jsp
eCommerce Integration Framework의 hybris 확장이 Hybris 4와의 이전 호환성을 유지하면서 Hybris 5를 지원하도록 업데이트되었습니다.
코드의 기본 설정이 Hybris 5에 대해 조정됩니다.
Hybris 4에 대해 개발하려면 다음을 수행해야 합니다.
maven을 호출할 때 다음 명령줄 인수를 명령에 추가합니다
-P hybris4
사전 구성된 Hybris 4 배포를 다운로드하고 번들에 포함합니다.
cq-commerce-hybris-server
OSGi 구성 관리자에서
hybris는 사용자 세션을 사용하여 고객의 장바구니와 같은 정보를 저장합니다. 세션 ID는 의 hybris에서 반환됩니다 JSESSIONID
hybris에 대한 후속 요청 시 전송해야 하는 쿠키입니다. 세션 ID를 저장소에 저장하지 않도록 하기 위해 쇼핑객의 브라우저에 저장된 다른 쿠키로 인코딩됩니다. 다음 단계가 수행됩니다.
hybris-session-rest
)를 클릭하여 쇼핑객에 대한 응답을 설정합니다. 원래 쿠키는 특정 경로에만 유효하고 후속 요청에서 브라우저에서 다시 전송되지 않으므로 새 쿠키의 인코딩이 필요합니다. 경로 정보도 쿠키 값에 추가해야 합니다.hybris-session-<*xxx*>
쿠키를 설정하고 hybris에서 데이터를 요청하는 데 사용되는 HTTP 클라이언트에서 설정합니다.원래 세션이 더 이상 유효하지 않을 때 새로운 익명 세션이 만들어집니다.
이 세션은 장바구니
추가/제거/등 수행
장바구니에서 다양한 계산을 수행합니다.
commerceSession.getProductPrice(Product product)
를 소유합니다. 저장소 위치 대상 주문 데이터
CommerceSession.getUserContext()
또한 는 결제 연결 처리
또한 는 이행 연결
hybris에서 유지 관리되는 제품 데이터는 AEM에서 사용할 수 있어야 합니다. 다음 메커니즘이 구현되었습니다.
가져오기(b)는 카탈로그의 AEM에서 페이지 트리 구조의 초기 설정에 사용됩니다.
hybris의 카탈로그 변경 사항은 피드를 통해 AEM에 표시된 다음 AEM(b)로 전파됩니다
hybris 확장은 지정된 간격(예: 간격이 초 단위로 지정된 24시간마다 AEM으로 변경 사항을 가져오도록 구성할 수 있는 폴링 가져오기("hybris" 구성표)를 제공합니다.
http://localhost:4502/content/geometrixx-outdoors/en_US/jcr:content.json
{
* "jcr:mixinTypes": ["cq:PollConfig"],
* "enabled": true,
* "source": "hybris:outdoors",
* "jcr:primaryType": "cq:PageContent",
* "interval": 86400
}
AEM의 카탈로그 구성은 스테이징됨 및 온라인 카탈로그 버전.
카탈로그 버전 간에 제품을 동기화하려면 해당 AEM 페이지(a, c)를 (비)활성화해야 합니다
AEM©에서 페이지를 활성화하려면 확인(b)이 필요하며,
활성화된 제품 페이지에서 제품 데이터에 액세스해야 합니다 온라인 버전 (d)
AEM 게시 인스턴스를 사용하려면 제품 및 개인화된 데이터(d)를 검색하기 위해 hybris에 액세스해야 합니다.
단일 제품에는 여러 변형이 있을 수 있습니다. 예를 들어 색상 및/또는 크기에 따라 다를 수 있습니다. 제품은 변형이 시작되는 속성을 정의해야 합니다. 우리는 이것을 변형 축.
그러나 일부 속성이 변형 축인 것은 아닙니다. 변형은 다른 속성에도 영향을 줄 수 있습니다. 예를 들어 가격은 크기에 따라 달라질 수 있습니다. 이러한 속성은 쇼퍼에서 선택할 수 없으므로 변형 축으로 간주되지 않습니다.
각 제품 및/또는 변형은 리소스로 표시되므로 1:1을 저장소 노드에 매핑합니다. 특정 제품 및/또는 변형을 해당 경로로 고유하게 식별할 수 있는 것은 당연한 귀결입니다.
제품/변형 리소스가 항상 실제 제품 데이터를 보유하는 것은 아닙니다. 하이브리스와 같은 다른 시스템에 실제로 있는 데이터의 표현일 수 있습니다. 예를 들어 제품 설명, 가격 책정 등은 AEM에 저장되지는 않지만 eCommerce 엔진에서 실시간으로 검색됩니다.
모든 제품 리소스는 Product API
. 제품 API의 대부분의 호출은 변형별로 고유하지만(변형은 조상에서 공유 값을 상속할 수 있지만), 변형 세트를 나열하는 호출도 있습니다( getVariantAxes()
, getVariants()
등)
사실상 변형 축은 모든 방법으로 결정됩니다 Product.getVariantAxes()
반환:
제품(일반적으로)은 많은 변형 축을 가질 수 있지만 기본적으로 제공되는 제품 구성 요소는 두 개만 처리합니다.
size
하나 더
이 추가 변형은 variationAxis
제품 참조의 속성(일반적으로 color
Geometrixx Outdoors).
일반적으로
제품 데이터는 /etc
아래의 제품 참조 /content
.
제품 변형과 제품 데이터 노드 사이에는 1:1 맵이 있어야 합니다.
제품 참조에는 표시된 각 변형에 대한 노드도 있어야 합니다. 하지만 모든 변형을 표시할 필요는 없습니다. 예를 들어 제품에 S, M, L 변형이 있는 경우 제품 데이터는 다음과 같을 수 있습니다.
etc
commerce
products
shirt
shirt-s
shirt-m
shirt-l
"크고 긴" 카탈로그만 있을 수 있지만
content
big-and-tall
shirt
shirt-l
마지막으로, 제품 데이터를 사용할 필요는 없습니다. 모든 제품 데이터를 카탈로그의 참조 아래에 배치할 수 있습니다. 그러나 제품 데이터를 복제하지 않으면 실제로 여러 카탈로그를 가질 수는 없습니다.
API
public interface Product extends Adaptable {
public String getPath(); // path to specific variation
public String getPagePath(); // path to presentation page for all variations
public String getSKU(); // unique ID of specific 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 getThumbnailUrl(); // 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 filter) throws CommerceException;
}
/**
* Interface for filtering variants and AxisFilter provided as common implementation
*
* The <code>VariantFilter</code> is used to filter variants,
* e.g. when using {@link Product#getVariants(VariantFilter filter)}.
*/
public interface VariantFilter {
public boolean includes(Product product);
}
/**
* A {@link VariantFilter} for filtering variants by the given
* axis and value. The following example returns a list of
* variant products that have a value of <i>blue</i> on the
* <i>color</i> axis.
*
* <p>
* <code>product.getVariants(new AxisFilter("color", "blue"));</code>
*/
public class AxisFilter implements VariantFilter {
private String axis;
private String value;
public AxisFilter(String axis, String value) {
this.axis = axis;
this.value = value;
}
/**
* {@inheritDoc}
*/
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;
}
}
일반 스토리지 메커니즘
제품 노드는 구조화되지 않습니다.
제품 노드는 다음 중 하나일 수 있습니다.
제품 데이터가 다른 위치에 저장된 참조:
productData
제품 데이터를 가리키는 속성(일반적으로 /etc/commerce/products
).제품 자체:
productData
속성을 사용합니다.AEM-일반 제품 구조
+ banyan_shirt
- cq:commerceType = product
- cq:productAttributes = [jcr:title, jcr:description, size, price, color]
- cq:productVariantAxes = [color, size]
- jcr:title = Banyan Shirt
- jcr:description = Flowery, all-cotton shirt.
- price = 14.00
+ banyan_shirt_s
- cq:commerceType = variant
- size = S
+ banyan_shirt_s_red
- cq:commerceType = variant
- color = red
+ banyan_shirt_s_blue
- cq:commerceType = variant
- color = blue
+ banyan_shirt_m
- cq:commerceType = variant
- size = M
+ banyan_shirt_m_red
- cq:commerceType = variant
- color = red
+ banyan_shirt_m_blue
- cq:commerceType = variant
- color = blue
+ banyan_shirt_l
- cq:commerceType = variant
- size = L
+ banyan_shirt_l_red
- cq:commerceType = variant
- color = red
+ banyan_shirt_l_blue
- cq:commerceType = variant
- color = blue
+ banyan_shirt_xl
- cq:commerceType = variant
- size = XL
- price = 18.00
구성 요소
장바구니는 CommerceSession:
CommerceSession
추가/제거/등을 수행합니다.CommerceSession
또한 장바구니에서 다양한 계산을 수행합니다. "장바구니와 직접 관련이 없지만 CommerceSession
또한 카탈로그 가격 정보를 제공해야 합니다(가격 책정 소유).
가격책정에 다음과 같은 몇 가지 수정자가 있을 수 있습니다.
수정자는 다음 인터페이스로 완전히 개방됩니다.
int CommerceSession.getQuantityBreakpoints(Product product)
String CommerceSession.getProductPrice(Product product)
스토리지
스토리지
개인화
개인화는 항상 ClientContext.
ClientContext /version/
모든 경우에 장바구니가 만들어집니다.
CommerceSession.addCartEntry()
메서드를 사용합니다.다음은 ClientContext 장바구니의 장바구니 정보의 예입니다.
장바구니 및 주문 데이터
다음 CommerceSession
는 다음 세 가지 요소를 소유합니다.
장바구니 컨텐츠
가격 책정
주문 세부 사항
장바구니 컨텐츠
장바구니 컨텐츠 스키마는 API로 수정되었습니다.
public void addCartEntry(Product product, int quantity);
public void modifyCartEntry(int entryNumber, int quantity);
public void deleteCartEntry(int entryNumber);
가격 책정
가격 책정 스키마는 API로도 수정되었습니다.
public String getCartPreTaxPrice();
public String getCartTax();
public String getCartTotalPrice();
public String getOrderShipping();
public String getOrderTotalTax();
public String getOrderTotalPrice();
주문 세부 사항
그러나 주문 세부 사항은 다음과 같습니다 not api에 의해 수정되었습니다.
public void updateOrderDetails(Map<String, String> orderDetails);
public Map<String, String> getOrderDetails();
public void submitOrder();
배송 계산
주문 양식은 종종 여러 배송 옵션(및 가격)을 제공해야 합니다.
가격은 중량 및/또는 배달 주소와 같은 주문 및 세부 사항을 기반으로 할 수 있습니다.
다음 CommerceSession
는 모든 종속성에 액세스할 수 있으므로 제품 가격과 유사한 방식으로 처리할 수 있습니다.
CommerceSession
운송 가격을 소유합니다.updateOrder(Map<String, Object> delta)
운송 선택기를 구현할 수 있습니다. 예:
yourProject/commerce/components/shippingpicker
:
기본적으로 이것은 foundation/components/form/radio
하지만 콜백이 CommerceSession
대상:
메서드를 사용할 수 있는지 확인
가격 정보 추가
고객이 AEM에서 주문 페이지를 업데이트할 수 있도록 하려면(배송 방법의 상위 세트 및 이를 설명하는 텍스트 포함), 여전히 관련 항목을 노출하도록 제어할 수 있습니다 CommerceSession
정보.
결제 처리
CommerceSession
또한 결제 처리 연결을 소유합니다.CommerceSession
구현 을 참조하십시오.주문 이행
CommerceSession
이행 연결도 소유합니다.CommerceSession
구현 을 참조하십시오.표준 서비스 API 모델에 따라 eCommerce 프로젝트는 개별 상거래 엔진에서 구현할 수 있는 검색 관련 API 세트를 제공합니다.
현재, hybris 엔진만 검색 API를 즉시 구현합니다.
그러나 검색 API는 제네릭이므로 각 CommerceService에서 개별적으로 구현할 수 있습니다.
eCommerce 프로젝트에는 다음과 같은 기본 검색 구성 요소가 포함되어 있습니다.
/libs/commerce/components/search
이렇게 하면 검색 API를 사용하여 선택한 상거래 엔진을 쿼리합니다(참조) 전자 상거래 엔진 선택):
핵심 프로젝트에서 제공하는 몇 가지 일반/도우미 클래스가 있습니다.
CommerceQuery
검색 쿼리를 설명하는 데 사용됩니다(쿼리 텍스트, 현재 페이지, 페이지 크기, 정렬 및 선택한 패싯에 대한 정보가 포함됨). 검색 API를 구현하는 모든 eCommerce 서비스는 검색을 수행하기 위해 이 클래스의 인스턴스를 수신합니다. A CommerceQuery
요청 개체( HttpServletRequest
).
FacetParamHelper
하나의 정적 메서드를 제공하는 유틸리티 클래스입니다. toParams
- 생성용 GET
패싯 목록 및 전환된 값 중 하나의 매개변수 문자열 이 기능은 UI 측에서 각 패싯의 각 값에 대한 하이퍼링크를 표시해야 할 때 사용자가 하이퍼링크를 클릭하면 각 값이 전환됩니다(즉, 선택한 경우 쿼리에서 제거되고 그렇지 않으면 추가됨). 이렇게 하면 여러/단일 값을 갖는 패싯을 처리하고 값을 재정의하는 등의 모든 로직이 관리됩니다.
검색 API의 시작 지점은 입니다 CommerceService#search
를 반환하는 메서드 CommerceResult
개체. 자세한 내용은 API 설명서 자세한 내용은 이 항목을 참조하십시오.
AEM과 다양한 eCommerce 시스템 간에 통합이 제공됩니다. 이렇게 하려면 AEM 관련 코드만 AEM에 대해 알고 또는 그 반대의 경우 알 수 있도록 여러 시스템 간에 구매자를 동기화하는 전략이 필요합니다.
인증
AEM은 다음과 같이 간주됩니다 전용 웹 프런트 엔드 및 모두 인증.
Hybris의 계정
AEM에서는 각 구매자에 대한 hybris에 해당(하위) 계정을 만듭니다. 이 계정의 사용자 이름은 AEM 사용자 이름과 동일합니다. 암호학적으로 임의의 비밀번호는 자동으로 생성되어 AEM에 저장(암호화)됩니다.
AEM 프런트 엔드는 기존 hybris 구현 앞에 배치할 수 있습니다. 또한 기존 AEM 설치에 hybris 엔진을 추가할 수 있습니다. 이렇게 하려면 두 시스템 중 하나에서 기존 사용자를 올바르게 처리할 수 있어야 합니다.
AEM -> hybris
hybris에 로그인할 때 AEM 사용자가 아직 없는 경우:
자세한 내용은: com.adobe.cq.commerce.hybris.impl.HybrisSessionImpl#login()
hybris -> AEM
AEM에 로그인할 때 시스템에서 사용자를 인식하면 다음과 같이 됩니다.
위의 알고리즘은 Sling에서 구현됩니다 AuthenticationInfoPostProcessor
com.adobe.cq.commerce.hybris.impl.user.LazyUserImporter.java
기존 기능을 기반으로 빌드하려면 사용자 지정 가져오기 처리기입니다.
를 구현해야 합니다 ImportHandler
인터페이스
확장 가능 DefaultImportHandler
/**
* Services implementing the <code>ImportHandler</code> interface are
* called by the {@link HybrisImporter} to create actual commerce entities
* such as products.
*/
public interface ImportHandler {
/**
* Not used.
*/
public void createTaxonomie(ImporterContext ctx);
/**
* Creates a catalog with the given name.
* @param ctx The importer context
* @param name The catalog's name
* @return Path of created catalog
*/
public String createCatalog(ImporterContext ctx, String name) throws Exception;
/**
* Creates a product from the given values.
* @param ctx The importer context
* @param values The product's properties
* @param parentCategoryPath The containing category's path
* @return Path of created product
*/
public String createProduct(ImporterContext ctx, ValueMap values, String parentCategoryPath) throws Exception;
/**
* Creates a variant product from the given values.
* @param ctx The importer context
* @param values The product's properties
* @param baseProductPath The base product's path
* @return Path of created product
*/
public String createVariantProduct(ImporterContext ctx, ValueMap values, String baseProductPath) throws Exception;
/**
* Creates an asset for a product. This is usually a product
* image.
* @param ctx The importer context
* @param values The product's properties
* @param baseProductPath The product's path
* @return Path of created asset
*/
public String createAsset(ImporterContext ctx, ValueMap values, String productPath) throws Exception;
/**
* Creates a category from the given values.
* @param ctx The importer context
* @param values The category's properties
* @param parentPath Path of parent category or base path of import in case of root category
* @return Path of created category
*/
public String createCategory(ImporterContext ctx, ValueMap values, String parentCategoryPath) throws Exception;
}
사용자 지정 처리기가 임포터에서 인식되도록 하려면 service.ranking
값이 0보다 큰 속성 예:
@Component
@Service
@Property(name = "service.ranking", value = 100)
public class MyImportHandler extends DefaultImportHandler {
...
}