ecommerce-platform-specialist について
ecommerce-platform-specialistは、Shopifyのドキュメントを参照して実装上の質問に答える開発スキルです。アプリやテーマ、API、チェックアウト、ヘッドレスコマースを扱います。
主な機能
- 01Shopify APIとアプリ開発のガイダンス
- 02Liquidによるテーマ開発
- 03チェックアウトとShopify Functionsのカスタマイズ
- 04Hydrogenによるヘッドレスコマースのガイダンス
- 05認証とWebhookの実践方法
- 06ドキュメントの検索と参照
活用シーン
- 01ShopifyアプリとAPI連携の構築
- 02Liquidテーマとチェックアウトのカスタマイズ
- 03認証とWebhook処理の実装
- 04Hydrogenによるヘッドレスコマース開発
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ qodex-ai/ ai-agent-skills --skill ecommerce-platform-specialistインストール後、Claude Code で/ecommerce-platform-specialistを入力して読み込まれたか確認します。
詳細
Shopify 開発エキスパート
目的
24 件以上の公式ドキュメントファイルに基づき、Shopify プラットフォームでの開発について、包括的で正確なガイダンスを提供します。アプリ開発、テーマのカスタマイズ、API 連携、チェックアウト拡張機能、e コマース機能のあらゆる側面を扱います。
ドキュメントの対象範囲
Shopify の公式ドキュメントに完全にアクセスできます(利用可能な場合):
- 場所:
docs/shopify/ - ファイル: Markdown ファイル 25 件
- 対象範囲: 完全な API リファレンス、ガイド、ベストプラクティス、実装パターン
注: ドキュメントは別途取得する必要があります:
pipx install docpull
docpull https://shopify.dev/docs -o .claude/skills/shopify/docs
主な分野:
- GraphQL Admin API(商品、注文、顧客、在庫)
- Storefront API(カート、チェックアウト、顧客アカウント)
- REST Admin API(レガシーサポート)
- アプリ開発(認証、Webhook、拡張機能)
- テーマ開発(Liquid、セクション、ブロック)
- ヘッドレスコマース(Hydrogen、Oxygen)
- チェックアウトのカスタマイズ(UI 拡張機能、検証)
- Shopify Functions(割引、配送、決済)
- POS 拡張機能(対面販売)
- サブスクリプションと販売プラン
- メタフィールドとカスタムデータ
- Shopify Flow の自動化
- CLI と開発ツール
- プライバシーとコンプライアンス
- パフォーマンスの最適化
使用するタイミング
ユーザーが次の内容に言及した場合に呼び出します:
- プラットフォーム: Shopify、e コマース、オンラインストア、マーチャント
- API: GraphQL、REST、Storefront API、Admin API
- 商品: 商品管理、コレクション、バリエーション、在庫
- 注文: 注文処理、フルフィルメント、配送
- 顧客: 顧客データ、アカウント、認証
- チェックアウト: チェックアウトのカスタマイズ、決済方法、配送オプション
- テーマ: Liquid テンプレート、テーマ開発、セクション、ブロック
- アプリ: アプリ開発、拡張機能、Webhook、OAuth
- ヘッドレス: Hydrogen、React、ヘッドレスコマース、Oxygen
- Functions: Shopify Functions、カスタムロジック、割引
- サブスクリプション: 継続課金、販売プラン、サブスクリプション
- ツール: Shopify CLI、開発ワークフロー
- POS: POS、リテール、対面決済
ドキュメントの使用方法
質問に回答する際は:
-
特定のトピックを検索します:
# Use Grep to find relevant docs grep -r "checkout" .claude/skills/shopify/docs/ --include="*.md" -
特定のドキュメントを読みます:
# API docs cat .claude/skills/shopify/docs/shopify/api-admin-graphql.md cat .claude/skills/shopify/docs/shopify/api-storefront.md -
実装ガイドを探します:
# List all guides ls .claude/skills/shopify/docs/shopify/
基本的な認証
OAuth 2.0 フロー
// Redirect to Shopify OAuth
const authUrl = `https://${shop}/admin/oauth/authorize?` +
`client_id=${process.env.SHOPIFY_API_KEY}&` +
`scope=read_products,write_products&` +
`redirect_uri=${redirectUri}&` +
`state=${nonce}`;
// Exchange code for access token
const response = await fetch(
`https://${shop}/admin/oauth/access_token`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
client_id: process.env.SHOPIFY_API_KEY,
client_secret: process.env.SHOPIFY_API_SECRET,
code
})
}
);
const { access_token } = await response.json();
セッショントークン(最新の埋め込みアプリ)
import { shopifyApi } from '@shopify/shopify-api';
const shopify = shopifyApi({
apiKey: process.env.SHOPIFY_API_KEY,
apiSecretKey: process.env.SHOPIFY_API_SECRET,
scopes: ['read_products', 'write_products'],
hostName: process.env.HOST,
isEmbeddedApp: true,
});
GraphQL Admin API
商品をクエリする
query {
products(first: 10) {
edges {
node {
id
title
handle
priceRange {
minVariantPrice {
amount
currencyCode
}
}
variants(first: 5) {
edges {
node {
id
sku
inventoryQuantity
}
}
}
}
}
}
}
商品を作成する
mutation {
productCreate(input: {
title: "New Product"
vendor: "My Store"
productType: "Apparel"
variants: [{
price: "29.99"
sku: "PROD-001"
}]
}) {
product {
id
title
}
userErrors {
field
message
}
}
}
注文を取得する
query {
orders(first: 25, query: "fulfillment_status:unfulfilled") {
edges {
node {
id
name
createdAt
totalPriceSet {
shopMoney {
amount
currencyCode
}
}
customer {
email
}
lineItems(first: 10) {
edges {
node {
title
quantity
}
}
}
}
}
}
}
Storefront API
カートを作成する
mutation {
cartCreate(input: {
lines: [{
merchandiseId: "gid://shopify/ProductVariant/123"
quantity: 1
}]
}) {
cart {
id
checkoutUrl
cost {
totalAmount {
amount
currencyCode
}
}
}
}
}
カートを更新する
mutation {
cartLinesUpdate(
cartId: "gid://shopify/Cart/xyz"
lines: [{
id: "gid://shopify/CartLine/abc"
quantity: 2
}]
) {
cart {
id
lines(first: 10) {
edges {
node {
quantity
}
}
}
}
}
}
Webhook
Webhook を設定する
// Register webhook via API
const webhook = await shopify.webhooks.register({
topic: 'ORDERS_CREATE',
address: 'https://your-app.com/webhooks/orders-create',
format: 'json'
});
Webhook を検証する
import crypto from 'crypto';
function verifyWebhook(body, hmacHeader, secret) {
const hash = crypto
.createHmac('sha256', secret)
.update(body, 'utf8')
.digest('base64');
return hash === hmacHeader;
}
// In webhook handler
app.post('/webhooks/orders-create', async (req, res) => {
const hmac = req.headers['x-shopify-hmac-sha256'];
const body = await req.text();
if (!verifyWebhook(body, hmac, process.env.SHOPIFY_API_SECRET)) {
return res.status(401).send('Invalid HMAC');
}
const order = JSON.parse(body);
// Process order...
res.status(200).send('OK');
});
Liquid テンプレート
基本的な Liquid
{{ product.title }}
{% if product.available %}
<button>Add to Cart</button>
{% else %}
<span>Sold Out</span>
{% endif %}
{% for variant in product.variants %}
<option value="{{ variant.id }}">
{{ variant.title }} - {{ variant.price | money }}
</option>
{% endfor %}
カスタムセクション
{% schema %}
{
"name": "Featured Product",
"settings": [
{
"type": "product",
"id": "product",
"label": "Product"
}
]
}
{% endschema %}
{% if section.settings.product %}
{% assign product = section.settings.product %}
<div class="featured-product">
<img src="{{ product.featured_image | img_url: '500x' }}" alt="{{ product.title }}">
<h2>{{ product.title }}</h2>
<p>{{ product.price | money }}</p>
</div>
{% endif %}
Shopify Functions
割引関数
// Function to apply volume discount
export default (input) => {
const quantity = input.cart.lines.reduce((sum, line) => sum + line.quantity, 0);
let discountPercentage = 0;
if (quantity >= 10) discountPercentage = 20;
else if (quantity >= 5) discountPercentage = 10;
if (discountPercentage > 0) {
return {
discounts: [{
message: `${discountPercentage}% volume discount`,
targets: [{
orderSubtotal: {
excludedVariantIds: []
}
}],
value: {
percentage: {
value: discountPercentage.toString()
}
}
}]
};
}
return { discounts: [] };
};
配送のカスタマイズ
// Hide specific delivery options
export default (input) => {
const operations = [];
// Hide express shipping for orders under $100
const cartTotal = parseFloat(input.cart.cost.subtotalAmount.amount);
if (cartTotal < 100) {
const expressOptions = input.cart.deliveryGroups[0].deliveryOptions
.filter(option => option.title.toLowerCase().includes('express'));
expressOptions.forEach(option => {
operations.push({
hide: {
deliveryOptionHandle: option.handle
}
});
});
}
return { operations };
};
Hydrogen(ヘッドレスコマース)
商品ページ
// app/routes/products.$handle.tsx
import {json, LoaderFunctionArgs} from '@shopify/remix-oxygen';
import {useLoaderData} from '@remix-run/react';
export async function loader({params, context}: LoaderFunctionArgs) {
const {product} = await context.storefront.query(PRODUCT_QUERY, {
variables: {handle: params.handle},
});
return json({product});
}
export default function Product() {
const {product} = useLoaderData<typeof loader>();
return (
<div>
<h1>{product.title}</h1>
<img src={product.featuredImage.url} alt={product.title} />
<p>{product.description}</p>
<AddToCartButton productId={product.id} />
</div>
);
}
const PRODUCT_QUERY = `#graphql
query Product($handle: String!) {
product(handle: $handle) {
id
title
description
featuredImage {
url
altText
}
variants(first: 10) {
nodes {
id
price {
amount
currencyCode
}
}
}
}
}
`;
Shopify CLI
よく使うコマンド
# Create new app
shopify app init
# Start development server
shopify app dev
# Deploy app
shopify app deploy
# Create extension
shopify app generate extension
# Create theme
shopify theme init
# Serve theme locally
shopify theme dev --store=your-store.myshopify.com
# Push theme
shopify theme push
# Pull theme
shopify theme pull
テスト
テストストア
- Partner アカウントを作成します:https://partners.shopify.com
- 開発ストアを作成します
- アプリをインストールします
- 機能をテストします
テストデータ
// Create test product
const product = await shopify.rest.Product.save({
session,
title: "Test Product",
body_html: "<strong>Test description</strong>",
vendor: "Test Vendor",
product_type: "Test Type",
variants: [{
price: "19.99",
sku: "TEST-001"
}]
});
// Create test order
const order = await shopify.rest.Order.save({
session,
line_items: [{
variant_id: 123456789,
quantity: 1
}],
customer: {
email: "[email protected]"
}
});
セキュリティのベストプラクティス
-
API キー:
- 環境変数に保存します
- バージョン管理にコミットしないでください
- 環境ごとに別のキーを使用します
- 漏えいした場合はローテーションします
-
Webhook:
- 必ず HMAC 署名を検証します
- HTTPS エンドポイントのみを使用します
- 直ちに 200 を返します
- 非同期で処理します
-
アクセススコープ:
- 必要最小限のスコープを要求します
- 各スコープが必要な理由を記録します
- 定期的に見直します
-
レート制限:
- API のレート制限を遵守します
- 指数バックオフを実装します
- API の使用状況を監視します
よくあるエラー
API 認証
Invalid access token- トークンが有効で、適切なスコープを持っていることを確認しますShop not found- ショップドメインの形式を確認しますMissing access token- X-Shopify-Access-Token ヘッダーを含めます
GraphQL エラー
User errors- レスポンスのuserErrorsフィールドを確認しますThrottled- リクエスト頻度を下げますField not found- API バージョンがそのフィールドに対応していることを確認します
Webhook の問題
Invalid HMAC- Webhook シークレットと検証ロジックを確認してくださいDelivery failed- エンドポイントがタイムアウトまでに 200 を返すことを確認してくださいNot receiving webhooks- Webhook の登録とエンドポイント URL を確認してください
リソース
- ダッシュボード: https://partners.shopify.com
- ドキュメント: https://shopify.dev
- GraphiQL Admin: https://shopify.dev/docs/apps/tools/graphiql-admin-api
- コミュニティ: https://community.shopify.com
- ステータス: https://www.shopifystatus.com
ドキュメントのクイックリファレンス
特定の情報をお探しですか?
# Search all docs
grep -r "search term" .claude/skills/shopify/docs/
# Find specific topics
ls .claude/skills/shopify/docs/shopify/
# Read specific guide
cat .claude/skills/shopify/docs/shopify/webhooks.md
一般的なドキュメントファイル:
api-admin-graphql.md- GraphQL Admin APIapi-storefront.md- Storefront APIauthentication.md- OAuth と認証フローwebhooks.md- Webhook の処理apps.md- アプリ開発themes.md- テーマ開発liquid.md- Liquid リファレンスhydrogen.md- ヘッドレスコマースcheckout.md- チェックアウトのカスタマイズfunctions.md- Shopify Functionscli.md- CLI コマンド
コメント
Markdown 対応