注意:
API に関するドキュメントもお読みください。
統合フレームワークには、API を備えた統合レイヤーが含まれます。これにより、特定の e コマースエンジンに依存しない e コマース機能用の AEM コンポーネントを作成できます。さらに、内部 CRX データベースを使用したり、e コマースシステムを組み込んだりして、製品データを AEM に取り込むこともできます。
この統合レイヤーを使用するために、標準の AEM コンポーネントが多数用意されています。現時点では、以下のようなものがあります。
- 製品表示コンポーネント
- 買い物かご
- プロモーションと割引券
- カタログおよびセクションのブループリント
- チェックアウト
- 検索
AEM 検索やサードパーティ検索(Search&Promote など)、またはこれらを組み合わせた検索をおこなうための、統合フックが提供されています。
e コマースフレームワークは任意の e コマースソリューションと組み合わせて使用できますが、使用するエンジは AEM によって識別される必要があります(AEM の汎用エンジンを使用する場合でも同様です)。
- e コマースエンジンは、CommerceService インターフェイスをサポートする OSGi サービスです。
- エンジンは、commerceProvider サービスプロパティによって区別できます。
- AEM は、CommerceService および Product のために Resource.adaptTo() をサポートします。
- adaptTo 実装は、リソースの階層内で cq:commerceProvider プロパティを探します。
- 見つかった場合は、その値を使用してコマースサービスの検索をフィルタリングします。
- 見つからなかった場合は、最上位のコマースサービスが使用されます。
- 厳密に型指定されたリソースに cq:commerceProvider を追加できるよう、cq:Commerce mixin が使用されます。
- adaptTo 実装は、リソースの階層内で cq:commerceProvider プロパティを探します。
- 適切なコマースファクトリ定義を参照するために、cq:commerceProvider プロパティも使用されます。
- 例えば、geometrixx という値を持つ cq:commerceProvider プロパティは、Geometrixx-Outdoors 向け Day CQ コマースファクトリ(com.adobe.cq.commerce.hybris.impl.GeoCommerceServiceFactory)の OSGi 設定に関連付けられます(ここでも、commerceProvider パラメーターの値は geometrixx となります)。
- ここで、その他のプロパティも設定できます(適切かつ使用可能な場合)。
- 例えば、geometrixx という値を持つ cq:commerceProvider プロパティは、Geometrixx-Outdoors 向け Day CQ コマースファクトリ(com.adobe.cq.commerce.hybris.impl.GeoCommerceServiceFactory)の OSGi 設定に関連付けられます(ここでも、commerceProvider パラメーターの値は geometrixx となります)。
/etc/commerce/products/geometrixx-outdoors + cq:commerceProvider = geometrixx + 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 を使用して、AEM の汎用実装の場合に製品コンポーネントでこれがどのように処理されるかを確認できます。
/apps/geometrixx-outdoors/components/product
CommerceSession は、
- 買い物かごを管理します。
- 追加や削除などを実行します。
- 買い物かごに対して様々な計算を実行します。
commerceSession.getProductPriceInfo(Product product, Predicate filter)
- 注文データの持続性を管理します。
CommerceSession.getUserContext() - updateOrder(Map<String, Object> delta) を使用して、配送の詳細情報を取得または更新できます。
- 支払処理の接続も管理します。
- フルフィルメントの接続も管理します。
1 つの製品に複数のバリエーションがある場合があります。例えば、カラーやサイズで異なるバリエーションがある場合があります。製品では、バリエーションを構成するプロパティを定義する必要があります。このようなプロパティをバリアント軸と呼びます。
ただし、すべてのプロパティがバリアント軸になるわけではありません。バリエーションは、他のプロパティにも影響を与えることがあります。例えば、価格はサイズに依存することがあります。買い物客はこのようなプロパティを選択できないので、バリアント軸とは見なされません。
各製品やバリアントはリソースによって表現されるので、リポジトリノードに 1 対 1 でマップされます。必然的に、特定の製品やバリアントはそのパスによって一意に識別できます。
すべての製品リソースは、製品 API で表現できます。製品 API での呼び出しの大部分はバリエーション固有です(ただし、バリエーションは 1 つの祖先から共有されている値を継承できます)が、一連のバリエーションをリストする呼び出し(getVariantAxes()、getVariants() など)もあります。
注意:
実際には、バリアント軸は Product.getVariantAxes() が返すものによって決定されます。
- 汎用実装の場合、AEM が製品データのプロパティ(cq:productVariantAxes)からバリアント軸を読み取ります。
(一般的に)製品には多数のバリアント軸を持たせることができますが、デフォルトの製品コンポーネントでは次の 2 つのバリアント軸のみが処理されます。
- size
- 1 つの追加バリアント
この追加バリアントは、製品リファレンスの variationAxis プロパティ(Geometrixx Outdoors の場合、通常は color)を使用して選択します。
一般的に、
- PIM データは /etc の下に配置されます。
- 製品リファレンスは /content の下に配置されます。
製品バリエーションと製品データノードの間には 1 対 1 のマッピングが必要です。
製品リファレンスには、各バリエーションを表すノードも必要ですが、すべてのバリエーションを表す必要はありません。例えば、製品に S、M、L のバリエーションがある場合、製品データは次のようになりますが、
etc commerce products shirt shirt-s shirt-m shirt-l
content big-and-tall shirt shirt-l
最後に、製品データを使用するための要件はありません。すべての製品データをカタログ内のリファレンスの下に配置できますが、実際には、すべての製品データを複製することなく複数のカタログを作成することはできません。
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; } }
- 一般的なストレージの構成
- 製品ノードは nt:unstructured です。
- 製品ノードは次のどちらかになります。
- リファレンス。製品データは他の場所に保存されています。
- 製品リファレンスには、productData プロパティが含まれます。このプロパティは、製品データ(一般的には /etc/commerce/products の下にあります)を指します。
- 製品データは階層化されています。製品属性は、製品データノードの祖先から継承されます。
- 製品リファレンスには、ローカルプロパティも含めることができます。このようなプロパティは、製品データ内で指定されるプロパティをオーバーライドします。
- 製品自体
- productData プロパティはありません。
- すべてのプロパティをローカルに保持している(そして 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 は、トリガーされた割引券とプロモーションも買い物かごに適用します。
- 買い物かごに直接関連はしませんが、CommerceSession はカタログの価格情報も提供する必要があります(価格を管理しているので)。
- 価格には、次の複数の変更要素があります。
- 数量割引。
- 様々な通貨。
- VAT 支払い義務ありと VAT なし。
- 変更要素は、次のインターフェイスを使用して完全に変更できます。
- int CommerceSession.getQuantityBreakpoints(Product product)
- String CommerceSession.getProductPrice(Product product)
- 価格には、次の複数の変更要素があります。
ストレージ
- ストレージ
- AEM 汎用ケースでは、買い物かごは ClientContext に保存されます。
パーソナライズ
- パーソナライズは、常に ClientContext から取得する必要があります。
- 買い物かごの ClientContext /バージョン/ は、すべてのケースで作成されます。
- 製品は、CommerceSession.addCartEntry() メソッドを使用して追加する必要があります。
- 次の図は、ClientContext に格納される買い物かご情報の例を示しています。

送料の計算
- 多くの場合、注文フォームには複数の出荷オプション(および価格)を表示する必要があります。
- 価格は、品目と注文の詳細(重さや配送先住所など)に基づきます。
- CommerceSession はすべての依存関係にアクセスするので、製品価格と同じ方法で扱うことができます。
- CommerceSession は、送料を管理します。
- updateOrder(Map<String, Object> delta) を使用して、配送の詳細情報を取得または更新できます。
注意:
現在、この検索 API をデフォルトで実装しているのは hybris エンジンだけです。
しかし、検索 API は汎用的なものであり、各 CommerceService で個別に実装できます。
そのため、標準で提供される汎用実装ではこの API は実装されませんが、拡張して検索機能を追加することができます。

ここでは、検索 API を利用して、選択されたコマースエンジンをクエリしています(e コマースエンジンの選択を参照)。
コアプロジェクトは、いくつかの汎用クラスまたはヘルパークラスを提供します。
- CommerceQuery
検索クエリの記述に使用します(クエリテキスト、現在のページ、ページサイズ、並べ替え、選択されているファセットについての情報を含みます)。検索 API を実装するすべての e コマースサービスは、検索を実行するために、このクラスのインスタンスを受け取ります。CommerceQuery は、リクエストオブジェクト(HttpServletRequest)からインスタンス化できます。 - FacetParamHelper
1 つの静的メソッド(toParams)を提供するユーティリティクラス。このメソッドを使用して、ファセットのリストと 1 つのトグル値から GET パラメーター文字列を生成します。これは、UI 側で、ユーザーがハイパーリンクをクリックすると対応する値に切り替わる(選択された場合はクエリから削除され、選択されていない場合は追加される)ように、各ファセットの値ごとのハイパーリンクを表示する必要がある場合に役立ちます。これによって、複数または単一の値を持つファセットの処理や値のオーバーライドなど、すべてのロジックを扱うことができます。
検索 API のエントリポイントは、CommerceResult オブジェクトを返す CommerceService#search メソッドです。このトピックについて詳しくは、API ドキュメントを参照してください。
- 割引券:
- 割引券はページベースのコンポーネントで、Web サイトコンソールを使用して作成および編集され、次の場所に保存されます。
/content/campaigns - 割引券は、以下の項目を提供します。
- 割引券コード(買い物客が買い物かごに入力する)。
- 割引券ラベル(買い物客が買い物かごに入力した後に表示される)。
- プロモーションパス(割引券が適用されるアクションを定義)。
- 割引券には、独自の開始および終了日付/時刻はありませんが、親キャンペーンの開始および終了日付/時刻を使用します。
- 外部のコマースエンジンも割引券を提供できます。少なくとも以下が必要です。
- 割引券コード
- isValid() メソッド
- 割引券コンポーネント(/libs/commerce/components/voucher)は、以下の項目を提供します。
- 割引券管理のためのレンダラー。現在、買い物かごに入っているすべての割引券を表示します。
- 割引券を管理(追加/削除)するための編集ダイアログ(フォーム)。
- 割引券を買い物かごに追加/買い物かごから削除するために必要なアクション。
- 割引券管理のためのレンダラー。現在、買い物かごに入っているすべての割引券を表示します。
- 割引券はページベースのコンポーネントで、Web サイトコンソールを使用して作成および編集され、次の場所に保存されます。
- プロモーション:
- プロモーションは、ページベースのコンポーネントで、Web サイトコンソールを使用して作成/編集され、次の場所に保存されます。
/content/campaigns - プロモーションは、以下の項目を提供します。
- 優先度
- プロモーションハンドラーパス
- プロモーションをキャンペーンに関連付けて、有効/無効日付/回数を定義できます。
- プロモーションをエクスペリエンスに関連付けて、セグメントを定義できます。
- エクスペリエンスに関連付けられていないプロモーションは、単独ではトリガーされませんが、割引券によってトリガーすることはできます。
- プロモーションコンポーネント(/libs/commerce/components/promotion)には、以下が含まれています。
- プロモーション管理のためのレンダラーとダイアログ
- プロモーションハンドラーに固有の設定パラメーターをレンダリングおよび編集するためのサブコンポーネント
- 次の 2 つのプロモーションハンドラーが、デフォルトで提供されています。
- DiscountPromotionHandler。買い物かご全体に絶対価格による割引またはパーセンテージ割引を適用します。
- PerfectPartnerPromotionHandler。パートナー製品も買い物かごに入っている場合に、製品の絶対価格による割引またはパーセンテージ割引を適用します。
- ClientContext SegmentMgr がセグメントを解決し、ClientContext CartMgr がプロモーションを解決します。少なくとも 1 つの解決されたセグメントを対象とする各プロモーションがトリガーされます。
- トリガーされたプロモーションは、買い物かごを再計算する AJAX 呼び出しによって、サーバーに返送されます。
- トリガーされたプロモーション(および追加された割引券)は、ClientContext パネルにも表示されます。
- プロモーションは、ページベースのコンポーネントで、Web サイトコンソールを使用して作成/編集され、次の場所に保存されます。
/** * Apply a voucher to this session's cart. * * @param code the voucher's code * @throws CommerceException */ public void addVoucher(String code) throws CommerceException; /** * Remove a voucher that was previously added with {@link #addVoucher(String)}. * * @param code the voucher's code * @throws CommerceException */ public void removeVoucher(String code) throws CommerceException; /** * Get a list of vouchers that were added to this cart via {@link #addVoucher(String)}. * * @throws CommerceException */ public List<Voucher> getVouchers() throws CommerceException;
このように、CommerceSession
は、割引券が存在するかどうか、割引券を適用できるかどうかをチェックします。このチェックは、特定の条件を満たした場合(例えば、買い物かごの合計価格が 1 万円を超える場合など)にのみ適用できる割引券に対して実行されます。何らかの理由で割引券を適用できない場合は、addVoucher
メソッドが例外をスローします。また、CommerceSession
によって、割引券の追加または削除後に買い物かごの価格の更新もおこないます。
Voucher
は、以下のフィールドを含む、Bean のようなクラスです。
- 割引券コード
- 簡単な説明
- 割引タイプおよび値を示す関連プロモーションの参照
提供される AbstractJcrCommerceSession
によって割引券を適用できます。getVouchers()
クラスが返す割引券は、(特に)次のプロパティを持つ jcr:content ノードを含む cq:Page のインスタンスです。
- sling:resourceType(String) - commerce/components/voucher である必要があります。
jcr:title
(String) - 割引券の説明用。code
(String) - この割引券を適用するためにユーザーが入力する必要があるコード。- promotion(String) - 適用されるプロモーション。例:/content/campaigns/geometrixx-outdoors/article/10-bucks-off
/** * Apply promotion to a cart line item. The method returns a discount * <code>PriceInfo</code> instance or <code>null</code> if no discount * was applied. * @param commerceSession The commerce session * @param promotion The configured promotion * @param cartEntry The cart line item * @return A discounted <code>PriceInfo</code> or <code>null</code> */ public PriceInfo applyCartEntryPromotion(CommerceSession commerceSession, Promotion promotion, CartEntry cartEntry) throws CommerceException; /** * Apply promotion to an order. The method returns a discount * <code>PriceInfo</code> instance or <code>null</code> if no discount * was applied. * @param commerceSession The commerce session * @param promotion The configured promotion * @return A discounted <code>PriceInfo</code> or <code>null</code> */ public PriceInfo applyOrderPromotion(CommerceSession commerceSession, Promotion promotion) throws CommerceException; public PriceInfo applyShippingPromotion(CommerceSession commerceSession, Promotion promotion) throws CommerceException; /** * Allows a promotion handler to define a custom, author-oriented message for a promotion. * The {@link com.adobe.cq.commerce.common.promotion.PerfectPartnerPromotionHandler}, for instance, * uses this to list the qualifying pairs of products in the current cart. * @param commerceSession * @param promotion * @return A message to display * @throws CommerceException */ public String getMessage(SlingHttpServletRequest request, CommerceSession commerceSession, Promotion promotion) throws CommerceException; /** * Informs the promotion handler that something under the promotions root has been edited, and the handler * should invalidate any caches it might be keeping. */ public void invalidateCaches();
次の 3 つのプロモーションハンドラーが、デフォルトで提供されています。
- DiscountPromotionHandler。買い物かご全体に絶対価格による割引またはパーセンテージ割引を適用します。
- PerfectPartnerPromotionHandler。製品パートナーも買い物かごに入っている場合に、製品の絶対価格による割引またはパーセンテージ割引を適用します。
- FreeShippingPromotionHandler。送料無料を適用します。