commercetools-commerce-patterns について
commercetools の実装を支援する開発者向けスキルです。プロモーション、価格設定、配送、決済、B2B、定期注文を扱い、文書検索と参照資料に基づいて案内します。
主な機能
- 01案内前に必須のドキュメント検索
- 02コマース実装トピックの参照資料
- 03GraphQL スキーマ検索スクリプト
- 04OpenAPI スキーマ検索スクリプト
- 05割引、価格設定、チェックアウトのルール
活用シーン
- 01カートと商品割引フローの設計
- 02B2B の見積もりと注文の実装
- 03配送レートと税処理の設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ commercetools/ commercetools-ai-plugins --skill commercetools-commerce-patternsインストール後、Claude Code で/commercetools-commerce-patternsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/approval-rules.mdas-associate-api.mdb2b-customer-group-pricing.mdbopis-shipping.mdbundle-discounting.mdbundle-modeling.mdbusiness-unit-hierarchy.mdcart-discount-scenarios.mdcustom-associate-roles.mdcustomer-group-pricing.mddiscount-code-usage.mddiscount-fundamentals.mddiscount-groups.mddynamic-shipping-costs.mdfinancing-options.mdfixed-price-combo.mdhigh-precision-money.mditem-substitutes.mdlimited-time-pricing.mdpayments.mdprice-functions.mdquote-lifecycle.mdrecurring-orders.mdshipping-predicates.mdstore-credit.mdtaxes.mdtiered-rates-cart-score.mdscripts/docs-search.mjsgraphql-schemata.mjsopenApi-schemata.mjs詳細
ワークフロー
このスキルが呼び出されたら、必ず次の手順に従います。
-
ドキュメント検索(必須、最初に実行) — このセッションでこのスキルを初めて使用する際は、回答する前に必ずこれを実行してください。このスキルが対象とする製品に絞り込み、最新の検証済みドキュメントを取得して、主要な根拠とします。このスキルの作業中は、ドキュメント検索にこのスクリプトを使用してください。それ以外は Knowledge MCP が対象とします。スキルのテキストだけでなく、取得したドキュメントで必ず詳細を確認してください。
node "<this skill's directory>/scripts/docs-search.mjs" \ --query "<extract key terms from user's question>" \ --app-name "<host app: claude-code, claude-chat, cursor, codex, copilot — or the host's own name>" \ --model "<current-model>" \ --commercetools-project-key "<if known>" \ --commercetools-region "<if known>" \ --limit 10commercetools のプロジェクトキーとリージョン(
api.{region}.commercetools.comの形式)は、すでにコンテキストに含まれている場合に限り指定してください。そうでない場合は、どちらも省略します。ファイルの検索や、ユーザーへのファイルの要求はしないでください。 -
スキルのリファレンスと組み合わせる — 分析結果を
./references/のローカルリファレンスと照合し、完全なコンテキストを確認します。 -
実装ガイダンスを提供する — ドキュメントと、ユーザーが対象とする具体的な統合モードを統合します。
オプションのスクリプト
GraphQL スキーマを取得する — commercetools の GraphQL クエリまたはミューテーションに関するコンテキストが必要な場合に実行します。たとえば、クエリを作成する前にリソースのフィールド、型、利用可能な操作を調べる場合や、生成した GraphQL クエリ/ミューテーションを実際のスキーマに照らして検証する場合です。単一の commercetools リソースの部分的な GraphQL SDL を取得します。
node scripts/graphql-schemata.mjs \
--resource-name "<commercetools resource, e.g. Cart, Product, Order>" \
--app-name "<host app: claude-code, claude-chat, cursor, codex, copilot — or the host's own name>" \
--model "<current-model>"
出力は、そのリソースの GraphQL SDL です。リソース名が認識されない場合、スクリプトは有効なリソース名の一覧を出力します。正しい名前を選び、再実行してください。注: SDL にはスタブ型が含まれる場合があります。これは、参照先のリソースをスタブとして表したもので、実際の型名はコメントに記載されています。必要なものは、このスクリプトをその型名を --resource-name として指定して再実行し、それぞれ取得してください。
OpenAPI(REST)スキーマを取得する — commercetools の REST エンドポイント、リクエスト/レスポンスのペイロード、または更新アクションに関するコンテキストが必要な場合に実行します。たとえば、リクエストを作成する前にリソースの REST 操作を調べる場合や、生成した REST リクエスト/ペイロードを実際の仕様に照らして検証する場合です。単一の commercetools リソースの部分的な OpenAPI 仕様を取得します。
node scripts/openApi-schemata.mjs \
--resource-name "<commercetools resource, e.g. api-Cart-write, api-Customer-read, checkout-Application>" \
--app-name "<host app: claude-code, claude-chat, cursor, codex, copilot — or the host's own name>" \
--model "<current-model>"
出力は、そのリソースの OpenAPI 仕様(YAML)です。REST リソース名には、読み取りと書き込みを分けた形式(例:api-Cart-read、api-Cart-write)を使用します。リソース名が認識されない場合、スクリプトは有効なリソース名の一覧を出力します。正しい名前を選び、再実行してください。注: 仕様には参照先展開のスキーマは含まれません。参照先リソースのスキーマが必要な場合は、そのリソースを --resource-name として指定してスクリプトを再実行し、別途取得してください。
主なポイント
ディスカウントの併用には厳格な優先順位があります。 商品ディスカウント → カートディスカウント → ディスカウントコード → ダイレクトディスカウントの順です。カートにダイレクトディスカウントを適用すると、すべてのディスカウントコードが無効になります。同じカートでダイレクトディスカウントとディスカウントコードのフローを併用しないでください。
sortOrder は値が大きいほど先に適用されます。 商品ディスカウントとカートディスカウントのどちらも、sortOrder の値が最も大きいディスカウント(1 に最も近いもの)が先に適用されます。0.9 は 0.5 より先に適用されます。商品ディスカウントは 1 つだけ適用され(併用不可)、カートディスカウントは stackingMode: StopAfterThisDiscount を設定しない限り、デフォルトで併用されます。
商品ディスカウントは外部価格設定と併用できません。 プロジェクトで外部価格ソースを使用している場合、商品ディスカウントは適用されません。外部価格設定が有効な場合は、プロモーションディスカウントにカートディスカウントを使用してください。
ディスカウントグループは複数のカートディスカウントを 1 つのエンティティにまとめます。 ディスカウントグループには独自の sortOrder と「最もお得な取引」の優先モードがあり、顧客に最も大きな割引をもたらすグループ内のカートディスカウントのみが適用されます。大規模なキャンペーン(例:ブラックフライデー)の管理にはディスカウントグループを使用してください。個々のディスカウントを一度に数十件無効化する際のミスを防げます。
顧客グループの価格設定は、顧客レベルではなく埋め込み価格で行います。 カートの計算時に購入者の顧客グループが解決され、バリアント上で一致する customerGroup を持つ価格が選択されます。顧客には複数の顧客グループを割り当てることができ(customerGroupAssignments 経由で最大500件)、割り当てられたすべてのグループの中から、条件を満たす最適な価格が選択されます。B2Bの購入者の場合、顧客グループは購入者の顧客レコードに直接割り当てるか、ビジネスユニット経由で割り当ててください。
カートスコアは、動的な配送料金を設定するための鍵です。 Merchant Centerでプロジェクトの配送料金入力タイプを「Cart Score」に設定します。Score タイプと整数のスコアを指定して setShippingRateInput を呼び出します。CTはそのスコアに一致する料金階層を検索します。スコアは0以上の整数でなければなりません。
カートスコアは配送料金の述語では使用できません。カートのカスタムフィールドにコピーしてください。 score は述語で直接クエリできません。基になる値(例:距離(km))をカートのカスタムフィールドに書き込みます。そのカスタムフィールドを使って配送料金の述語を記述してください。
価格関数を使うと、カートスコアを連続的な料金に変換できます。 priceFunction(例:(x / 30))を設定します。ここで x はカートスコアです。CTは関数を評価し、その結果の金額を配送料金として設定するため、考えられるすべての値を列挙せずに、料金を滑らかに変化させられます。
ほとんどのPSP/税務サービスとの連携では、taxMode: ExternalAmount を使用してください。 このモードでは、税務サービスが各明細項目の正確な税額を計算し、それをCTに直接渡せます。これにより、CTの計算エンジンと外部税務サービス(AvaTax、Vertex)との間で発生する丸め誤差をなくせます。
CTは支払い状態を記録し、実際の金融取引はPSPが行います。 Paymentオブジェクトは台帳です。PSPの各イベント(Authorization、Charge、Refund、Chargeback)を追跡するには、addTransaction 更新アクションを使用します。PSPでの確認が完了してからのみ、state: "Success" を設定してください。
Paymentの interfaceId は、一度設定すると変更できません。 このフィールドはCTのPaymentをPSPの識別子に関連付けます。最初に正しく記録してください。更新する方法はありません。
注文の作成時にカート価格のスナップショットが保存されます。 カートの作成後、注文の作成前に商品価格が変更されても、カートには古い価格が保持されます。チェックアウト前に価格を更新するには、カートの recalculate アクションを使用してください。
ビジネスユニットはB2Bの中核となるエンティティであり、すべてのB2B操作はこれを通じて実行します。 すべてのB2B操作では as-associate APIチェーンを使用します(構成とスコープについてはreferences/as-associate-api.mdを参照)。B2Bのユーザー向け操作で、プロジェクトレベルのカート/注文APIを使用しないでください。
見積もりのライフサイクルには、QuoteRequest → StagedQuote → Quote → Orderの4つのエンティティがあります。 購入者が QuoteRequest を作成し、営業担当者が StagedQuote(交渉済み価格を含む作業用ドラフト)を作成します。Quote は確定したオファーです。承諾された場合、購入者はこれをOrderに変換します。各ステップには独自の状態遷移があります。
POST /orders と POST /recurring-orders では、根本的に異なる結果になります。 定期注文の明細項目を含むカートに対して POST /orders を呼び出すと、通常の注文(即時)と定期注文の両方が作成されます。POST /recurring-orders を呼び出すと、定期注文のみが作成されます。「定期購入して今すぐ発送」するフローには /orders を、将来の日付に開始する定期購入には /recurring-orders を使用してください。
カート割引の recurringOrderScope で、割引を繰り返し適用するかどうかを制御します。 1回限りのウェルカムプロモーションには "NonRecurringOrdersOnly" を設定します。定期購入の各サイクルで適用する継続的なロイヤルティ割引には "AnyOrder" を設定します。
リファレンス一覧
価格設定とプロモーション
| トピック | リファレンス |
|---|---|
| 割引の併用ルール、sortOrder、ダイレクト割引による割引コードのブロック | references/discount-fundamentals.md |
| 購入/プレゼントのカート割引 — triggerPattern、targetPattern、excludeCount | references/bundle-discounting.md |
| カート割引のシナリオ集 — JSON 全文付きの 12 の名前付きシナリオ | references/cart-discount-scenarios.md |
| 固定価格の組み合わせ割引 — X と Y をそれぞれ N 個購入すると、組み合わせ価格が固定 | references/fixed-price-combo.md |
「セット内の商品を任意に N 個、合計固定価格で購入」(トリガー商品なし)、および maxOccurrence によるカートごとの適用回数上限 | references/cart-discount-scenarios.md |
| 顧客グループベースの価格設定 — 埋め込み価格の選択、グループの割り当て | references/customer-group-pricing.md |
| B2B 顧客グループの価格設定 — 顧客グループによる購入者ごとの価格設定 | references/b2b-customer-group-pricing.md |
| 高精度の金額 — fractionDigits、通貨設定、丸め処理 | references/high-precision-money.md |
| 割引グループとプロモーションの優先順位 — 最適な割引の選択 | references/discount-groups.md |
| ストアクレジットとロイヤルティ通貨 — 外部台帳パターン | references/store-credit.md |
| 期間限定価格 — 埋め込み価格の validFrom/validUntil | references/limited-time-pricing.md |
| 割引コードの利用 — コード生成、引き換え上限 | references/discount-code-usage.md |
配送とフルフィルメント
| トピック | リファレンス |
|---|---|
| 段階料金、カートスコアの設定、ScoreShippingRateInput | references/tiered-rates-cart-score.md |
| 配送条件 — 条件構文、カスタムフィールドによる回避策 | references/shipping-predicates.md |
| 価格関数 — priceFunction の設定、関数構文 | references/price-functions.md |
| 動的な配送コスト — 外部での計算、setCustomShippingMethod | references/dynamic-shipping-costs.md |
| BOPIS 配送 — 複数の配送方法、配送グループの設定 | references/bopis-shipping.md |
決済と税金
| トピック | リファレンス |
|---|---|
| 決済 — Payment オブジェクトモデル、トランザクション、PSP 統合フロー | references/payments.md |
| 税金 — カートの税モード(Platform/External/ExternalAmount/Disabled) | references/taxes.md |
| ファイナンスと分割払い — BNPL 統合、CT の決済モデリング | references/financing-options.md |
B2B 注文フロー
| トピック | リファレンス |
|---|---|
| カスタム担当者ロール — ロール定義、権限キー、BU への割り当て | references/custom-associate-roles.md |
| ビジネスユニット階層 — 親/子 BU、継承されるロール、ストアの割り当て | references/business-unit-hierarchy.md |
| 承認ルール — 条件設計、承認フローのライフサイクル | references/approval-rules.md |
| 見積もりのライフサイクル — QuoteRequest、StagedQuote、Quote、Order への変換 | references/quote-lifecycle.md |
| as-associate API パターン — チェーンの構築、スコープ | references/as-associate-api.md |
定期注文
| トピック | リファレンス |
|---|---|
| 定期注文 — RecurrencePolicy、priceSelectionMode、/orders と /recurring-orders | references/recurring-orders.md |
カタログとインポート
| トピック | リファレンス |
|---|---|
| 商品データのモデリング — 階層、全14種類の属性タイプ、Nested と Custom Object | |
| バンドル商品のモデリング — ProductType の設計、子 SKU の参照、BFF によるオーケストレーション | references/bundle-modeling.md |
| Import API — コンテナ、バッチ処理、非同期処理、差分インポート | |
| Import API のパフォーマンス — 1,500万件のレコードパターン、コンテナ数、バッチサイズ | |
| 商品の代替品 — 代替商品/交換商品のモデリング | references/item-substitutes.md |
| 在庫のモデリング — 供給チャネル、在庫エントリー、バックオーダー |
優先度レベル
CRITICAL
- 直接割引は割引コードをブロックします。 チェックアウトフローでユーザーが割引コードを入力する想定の場合、カートに直接割引を追加しないでください。
- sortOrder:値が大きいほど先に適用されます — 商品割引とカート割引の両方に適用されます。
0.9は0.5より先に適用されます。これはプロモーションの動作を誤らせるよくある誤解です。 - 商品割引は外部価格設定と併用できません。 プロジェクトで外部の価格ソースを使用する場合は、すべてのプロモーション割引をカート割引に切り替えてください。
- triggerPattern の SKU 条件はエントリー間で AND 条件になります。 1つの
CountOnLineItemUnitsエントリーで照合できる SKU は1つだけです。バンドルの構成品ごとに個別のエントリーを追加してください。 - 配送レートを照会する前にスコアを設定する必要があります。
setShippingRateInputは、チェックアウト前かつ配送レートの合計が計算される前に呼び出す必要があります。注文作成後に呼び出しても効果はありません。 - 配送条件の失敗は通知されません。 条件の構文エラーがある場合、CT はメソッドを返さないか、すべてのメソッドを返すことがあります。
GET /shipping-methods?cartId=<id>を使って条件の動作を必ず明示的にテストしてください。 - すべての B2B 書き込みでは、必ず
as-associateAPI チェーンを使用してください。 プロジェクトレベルのapiRoot.carts().*では B2B 権限が適用されません。これは単なる慣例ではなく、セキュリティ要件です。 - Associate が as-associate でカートに商品を追加するには、
CreateMyCarts権限が必要です。 権限がない場合は 403 が返されます。 POST /ordersは、混在カートから通常注文と定期注文の両方を作成します。 注文確認フローでは、複数の注文 ID を処理できるよう設計してください。- 使用中の RecurrencePolicy は削除できません。 削除を試みる前に、すべての明細項目とカートから参照を削除してください。
- PSP の確認前に Payment トランザクションを
Successに設定しないでください。 楽観的に成功を記録すると、照合エラーが発生します。 - Payment の
interfaceIdは一度設定すると変更できません。 PSP のトランザクション識別子は、最初の書き込み時に正しく記録してください。 - Import API には順序の保証がありません。 2つ目を送信する前に、最初のオペレーションのステータスをポーリングしてください。
productDraftImportは破壊的です。 ドラフトに含まれていないフィールドはすべて削除されます。- バージョン競合(409 ConcurrentModification)が発生した場合は、最新バージョンで再試行する必要があります。 失敗したリクエストで使用したバージョンは使用しないでください。
HIGH
- カスタマーグループの価格を適用するには、顧客がログインしており、customerGroup が設定されている必要があります。 匿名カートにはデフォルト価格が適用されます。
- カート内のすべての価格で HighPrecisionMoney を統一する必要があります。 同じカート/注文内で centPrecision と highPrecision の価格を混在させると、計算エラーが発生します。
- ディスカウントコードの
maxApplicationsは、すべての顧客に対する全体の上限です。 顧客ごとの上限にはmaxApplicationsPerCustomerを使用してください。これらは別々のフィールドです。 - 配送条件ではカートスコアを使用できません。 配送条件を記述する前に、距離または重量の値をカートのカスタムフィールドにコピーしてください。
- 倉庫ごとの条件には、カートのカスタムフィールドに倉庫キーが必要です。 配送条件から、カートに割り当てられた供給チャネルを直接検索することはできません。
- StagedQuote には交渉済みのラインアイテム価格が保持されます。 StagedQuote を Quote に変換すると、StagedQuote の価格が固定されます。
- 承認ルールはカート作成時ではなく、注文作成時に評価されます。 承認待ちについて購入者の期待を調整できるよう、カートから注文までの UX を設計してください。
priceSelectionModeはユースケースごとに意図的に設定する必要があります。"Fixed"は価格を保証し、"Dynamic"は常に現在のカタログ価格を適用します。- カートディスカウントの
recurringOrderScopeは、デフォルトですべての注文に適用されます。 初回購入向けディスカウントには、明示的に"NonRecurringOrdersOnly"を設定してください。 - ネストされた属性は検索できず、ディスカウント条件の対象にもできません。 検索フィルターや条件に表示する必要がある属性には、フラットな属性タイプを使用してください。
- Import API のバッチサイズは、1 リクエストあたり最大 20 件です。 必ず分割してください。
- データ作成後に ProductType の属性制約を変更するには、移行が必要です。 初期設計の段階で属性制約を計画してください。
MEDIUM
- Cart Discount の
isActiveは、ソフトな有効/無効の切り替えです。 ディスカウントを作成・削除する代わりに、キャンペーンのスケジュール管理に使用してください。 - 特定のディスカウントを単独適用にするには、
stackingMode: StopAfterThisDiscountを使用してください。 カートディスカウントはデフォルトで併用されます。 - 価格の丸めは
priceRoundingMode(Cart/Order/Quote、および Project のデフォルト設定)で構成できます。 モードはHalfEven(銀行丸め — デフォルト)、HalfUp、HalfDownです。.5を顧客に有利な方向に丸めるのはHalfDownだけです。モードを ERP/税務システムに合わせ、高取引量のキャンペーンではそれに応じた予算上の余裕を確保してください。 - 未対応のディスカウントシナリオには、カート/注文の API Extension で Direct Discount またはカスタムラインアイテムを計算して挿入する方法が一般的です。
- カテゴリの購入額のしきい値には、
lineItemGrossTotal(categories.key = (...)) >= "X.XX USD"の形式を使用します。 値には通貨文字列を含める必要があります。 - 価格関数は、レートの検索時にサーバー側で評価されます。 フロントエンドで関数を再現しようとしないでください。
- Quote の交渉は複数ラウンドに対応しています。 ビジネス上、交渉履歴が必要な場合は、QuoteRequest のカスタムフィールドで交渉ラウンドを管理してください。
- 購入者の顧客レコードにカスタマーグループを割り当てる方法が、最もシンプルな B2B 価格設定です。 その顧客のすべてのカートに、グループ価格が自動的に引き継がれます。
- 注文確認の UX では、複数の注文 ID に対応する必要があります。 頻度の異なる定期購入アイテムを含むカートを一度にチェックアウトすると、N+1 件の注文が生成されます。
- Import API によるスタンドアロン価格は、
validFrom/validUntilに対応しています。 商品を再公開せずに、期間限定価格を設定できます。