要約
Magento 2(Adobe Commerce)APIは、開発者がEコマースストアとプログラム的に連携することを可能にします。OAuth 1.0aとトークンベースの認証を使用し、REST、SOAP、およびGraphQLのエンドポイントを提供し、設定可能なレート制限付きで、商品、注文、顧客、在庫などにアクセスできます。このガイドでは、認証設定、CRUD操作、Webhooks、カスタムエンドポイント、および本番環境への統合戦略について説明します。
はじめに
Adobe Commerce (Magento) は、年間1,550億ドル以上の総商品価値を持つ25万以上のEコマースストアを支えています。Eコマース連携、ERPコネクタ、またはモバイルアプリを構築する開発者にとって、Magento APIの統合は選択肢ではなく、この膨大なマーチャント基盤に到達するために不可欠です。
現実として、複数の販売チャネルを管理するマーチャントは、Magentoと他のシステム間の手動データ入力に毎週20〜30時間を費やしています。堅牢なMagento API統合は、商品同期、注文処理、在庫更新、顧客データ管理を自動化します。
このガイドでは、完全なMagento 2 API統合プロセスを順を追って説明します。OAuth 1.0aとトークン認証、REST/SOAP/GraphQLエンドポイント、商品と注文の管理、Webhooks、カスタムAPI開発、および本番環境へのデプロイ戦略を学びます。このガイドを読み終える頃には、本番環境に対応したMagento連携を構築できるようになるでしょう。
Magento 2 APIとは?
Magento 2は、Eコマースデータにアクセスするための3種類のAPIを提供します。
- REST API: Webおよびモバイルアプリケーション向けのJSONベース
- SOAP API: 企業連携向けのXMLベース
- GraphQL: 効率的なフロントエンドアプリケーション向けのクエリベース
APIが扱う対象:
- 商品、カテゴリ、在庫
- 注文、請求書、出荷
- 顧客および顧客グループ
- ショッピングカートとチェックアウト
- プロモーションと価格ルール
- CMSページとブロック
- ストア設定
主な機能
| 機能 | 説明 |
|---|---|
| 複数のプロトコル | REST、SOAP、GraphQL |
| OAuth 1.0a | 安全なサードパーティアクセス |
| トークン認証 | 管理者および統合トークン |
| Webhooks | キューを介した非同期操作 |
| レート制限 | インストールごとに設定可能 |
| カスタムエンドポイント | カスタムAPIで拡張 |
| マルチストア | 単一API、複数のストアビュー |
API比較
| APIタイプ | プロトコル | ユースケース |
|---|---|---|
| REST | JSON | モバイルアプリ、連携 |
| SOAP | XML | エンタープライズシステム (SAP, Oracle) |
| GraphQL | GraphQL | ストアフロント、PWA |
Magentoバージョン
| バージョン | ステータス | サポート終了 |
|---|---|---|
| Magento 2.4.x | 現行 | アクティブ |
| Adobe Commerce 2.4.x | 現行 | アクティブ |
| Magento 1.x | EOL | 2020年6月 (使用しないでください) |
利用開始:認証設定
ステップ1:管理者アカウントまたは統合の作成
APIにアクセスする前に:
- Magento管理パネルにログインします
- システム > 権限 > すべてのユーザー に移動します
- 管理者ユーザーを作成します(管理者トークン用)または
- システム > 拡張機能 > 統合 に移動します
- 新しい統合を作成します(OAuth用)
ステップ2:認証方法の選択
| 方法 | 最適用途 | トークン有効期間 |
|---|---|---|
| 管理者トークン | 内部連携 | 設定可能 (デフォルト: 4時間) |
| 統合トークン | サードパーティアプリ | 取り消されるまで |
| OAuth 1.0a | パブリックマーケットプレイスアプリ | 取り消されるまで |
| 顧客トークン | 顧客向けアプリ | 設定可能 |
ステップ3:管理者トークンの取得(最も簡単な方法)
内部連携用の管理者トークンを生成します。
const MAGENTO_BASE_URL = process.env.MAGENTO_BASE_URL;
const MAGENTO_ADMIN_USERNAME = process.env.MAGENTO_ADMIN_USERNAME;
const MAGENTO_ADMIN_PASSWORD = process.env.MAGENTO_ADMIN_PASSWORD;
const getAdminToken = async () => {
const response = await fetch(`${MAGENTO_BASE_URL}/rest/V1/integration/admin/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: MAGENTO_ADMIN_USERNAME,
password: MAGENTO_ADMIN_PASSWORD
})
});
if (!response.ok) {
throw new Error('Invalid admin credentials'); // 無効な管理者認証情報
}
// Response is a plain string (the token), not JSON // レスポンスはプレーンな文字列(トークン)、JSONではない
const token = await response.text();
return token;
};
// Usage // 使用法
const token = await getAdminToken();
console.log(`Admin token: ${token}`);
// Store securely - use for subsequent API calls // 安全に保存 - 以降のAPIコールに使用
セキュリティに関する注意: トークンは安全に保管してください。
# .env file
MAGENTO_BASE_URL="https://store.example.com"
MAGENTO_ADMIN_USERNAME="api_user"
MAGENTO_ADMIN_PASSWORD="secure_password_here"
MAGENTO_ACCESS_TOKEN="obtained_via_auth"
ステップ4:統合の作成(サードパーティ向けに推奨)
管理パネルから統合を作成します。
システム > 拡張機能 > 統合 に移動します
新しい統合を追加 をクリックします
詳細を入力します:
- 名前:「My Integration」
- メール: your-email@example.com
- コールバックURL: (OAuth用)
- アイデンティティリンクURL: (OAuth用)
API権限 を設定します:
- リソース: 必要な権限を選択します
- 推奨: 商品、注文、顧客、在庫
保存 をクリックします
新しい統合で アクティブ化 をクリックします
アクセストークン と トークンシークレット をコピーします
ステップ5:顧客トークンの取得
顧客向けアプリケーションの場合:
const getCustomerToken = async (email, password) => {
const response = await fetch(`${MAGENTO_BASE_URL}/rest/V1/integration/customer/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: email,
password: password
})
});
if (!response.ok) {
throw new Error('Invalid customer credentials'); // 無効な顧客認証情報
}
const token = await response.text();
return token;
};
// Usage // 使用法
const customerToken = await getCustomerToken('customer@example.com', 'password123');
ステップ6:認証済みAPIコールの実行
再利用可能なAPIクライアントを作成します:
const magentoRequest = async (endpoint, options = {}) => {
const token = await getAdminToken(); // Or retrieve stored token // または保存されたトークンを取得
const response = await fetch(`${MAGENTO_BASE_URL}/rest${endpoint}`, {
...options,
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
...options.headers
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Magento API Error: ${error.message}`); // Magento APIエラー
}
return response.json();
};
// Usage // 使用法
const products = await magentoRequest('/V1/products');
console.log(`Found ${products.items.length} products`); // ${products.items.length}件の商品が見つかりました
商品管理
商品の取得
フィルタリングして商品を取得します:
const getProducts = async (filters = {}) => {
const params = new URLSearchParams();
// Build search criteria // 検索条件を構築
if (filters.search) {
params.append('searchCriteria[filterGroups][0][filters][0][field]', 'sku');
params.append('searchCriteria[filterGroups][0][filters][0][value]', `%${filters.search}%`);
params.append('searchCriteria[filterGroups][0][filters][0][conditionType]', 'like');
}
if (filters.priceFrom) {
params.append('searchCriteria[filterGroups][1][filters][0][field]', 'price');
params.append('searchCriteria[filterGroups][1][filters][0][value]', filters.priceFrom);
params.append('searchCriteria[filterGroups][1][filters][0][conditionType]', 'gteq');
}
params.append('searchCriteria[pageSize]', filters.limit || 20);
params.append('searchCriteria[currentPage]', filters.page || 1);
const response = await magentoRequest(`/V1/products?${params.toString()}`);
return response;
};
// Usage // 使用法
const products = await getProducts({ search: 'shirt', priceFrom: 20, limit: 50 });
products.items.forEach(product => {
console.log(`${product.sku}: ${product.name} - $${product.price}`);
});
単一商品の取得
SKUで商品を取得します:
const getProduct = async (sku) => {
const response = await magentoRequest(`/V1/products/${sku}`);
return response;
};
// Usage // 使用法
const product = await getProduct('TSHIRT-001');
console.log(`Name: ${product.name}`); // 名前: ${product.name}
console.log(`Price: $${product.price}`); // 価格: $${product.price}
console.log(`Stock: ${product.extension_attributes?.stock_item?.qty}`); // 在庫: ${product.extension_attributes?.stock_item?.qty}
商品の作成
シンプル商品を作成します:
const createProduct = async (productData) => {
const product = {
product: {
sku: productData.sku,
name: productData.name,
attribute_set_id: productData.attributeSetId || 4, // Default set // デフォルトセット
type_id: 'simple',
price: productData.price,
status: productData.status || 1, // 1=enabled, 2=disabled // 1=有効、2=無効
visibility: productData.visibility || 4, // 4=Catalog & Search // 4=カタログと検索
weight: productData.weight || 1,
extension_attributes: {
stock_item: {
qty: productData.qty || 0,
is_in_stock: productData.qty > 0 ? true : false
}
},
custom_attributes: [
{
attribute_code: 'description',
value: productData.description
},
{
attribute_code: 'short_description',
value: productData.shortDescription
},
{
attribute_code: 'color',
value: productData.color
},
{
attribute_code: 'size',
value: productData.size
}
]
}
};
const response = await magentoRequest('/V1/products', {
method: 'POST',
body: JSON.stringify(product)
});
return response;
};
// Usage // 使用法
const newProduct = await createProduct({
sku: 'TSHIRT-NEW-001',
name: 'Premium Cotton T-Shirt',
price: 29.99,
qty: 100,
description: 'High-quality cotton t-shirt',
shortDescription: 'Premium cotton tee',
color: 'Blue',
size: 'M'
});
console.log(`Product created: ${newProduct.id}`); // 商品が作成されました: ${newProduct.id}
商品の更新
商品情報を更新します:
const updateProduct = async (sku, updates) => {
const product = {
product: {
sku: sku,
...updates
}
};
const response = await magentoRequest(`/V1/products/${sku}`, {
method: 'PUT',
body: JSON.stringify(product)
});
return response;
};
// Usage - Update price and stock // 使用法 - 価格と在庫を更新
await updateProduct('TSHIRT-001', {
price: 24.99,
extension_attributes: {
stock_item: {
qty: 150,
is_in_stock: true
}
}
});
商品の削除
商品を削除します:
const deleteProduct = async (sku) => {
await magentoRequest(`/V1/products/${sku}`, {
method: 'DELETE'
});
console.log(`Product ${sku} deleted`); // 商品 ${sku} が削除されました
};
商品タイプ
| タイプ | 説明 | ユースケース |
|---|---|---|
| シンプル | 単一SKU、バリエーションなし | 標準商品 |
| 設定可能 | 子バリエーションを持つ親商品 | サイズ/色の選択肢 |
| グループ化 | シンプル商品のコレクション | 商品バンドル |
| 仮想 | 非物理的商品 | サービス、ダウンロード |
| バンドル | カスタマイズ可能な商品バンドル | 自分で構築するキット |
| ダウンロード可能 | デジタル商品 | 電子書籍、ソフトウェア |
注文管理
注文の取得
フィルタリングして注文を取得します:
const getOrders = async (filters = {}) => {
const params = new URLSearchParams();
if (filters.status) {
params.append('searchCriteria[filterGroups][0][filters][0][field]', 'status');
params.append('searchCriteria[filterGroups][0][filters][0][value]', filters.status);
params.append('searchCriteria[filterGroups][0][filters][0][conditionType]', 'eq');
}
if (filters.dateFrom) {
params.append('searchCriteria[filterGroups][1][filters][0][field]', 'created_at');
params.append('searchCriteria[filterGroups][1][filters][0][value]', filters.dateFrom);
params.append('searchCriteria[filterGroups][1][filters][0][conditionType]', 'gteq');
}
params.append('searchCriteria[pageSize]', filters.limit || 20);
params.append('searchCriteria[currentPage]', filters.page || 1);
const response = await magentoRequest(`/V1/orders?${params.toString()}`);
return response;
};
// Usage - Get pending orders from last 7 days // 使用法 - 過去7日間の保留中の注文を取得
const orders = await getOrders({
status: 'pending',
dateFrom: '2026-03-18 00:00:00',
limit: 50
});
orders.items.forEach(order => {
console.log(`Order #${order.increment_id}: ${order.customer_email} - $${order.grand_total}`);
});
単一注文の取得
IDで注文を取得します:
const getOrder = async (orderId) => {
const response = await magentoRequest(`/V1/orders/${orderId}`);
return response;
};
// Usage // 使用法
const order = await getOrder(12345);
console.log(`Order #${order.increment_id}`); // 注文 # ${order.increment_id}
console.log(`Status: ${order.status}`); // ステータス: ${order.status}
console.log(`Total: $${order.grand_total}`); // 合計: $${order.grand_total}
console.log(`Items:`); // 商品:
order.items.forEach(item => {
console.log(` - ${item.name} x ${item.qty_ordered}`);
});
注文ステータスの流れ
pending → processing → complete
→ canceled
→ on_hold
→ payment_review
注文ステータスの更新
注文ステータスを変更します:
const updateOrderStatus = async (orderId, newStatus) => {
// Note: Direct status update requires custom endpoint // 注:直接ステータスを更新するにはカスタムエンドポイントが必要です
// Use order management workflow instead: // 代わりに注文管理ワークフローを使用してください:
// For cancel: // キャンセル用:
await magentoRequest(`/V1/orders/${orderId}/cancel`, {
method: 'POST'
});
// For hold: // 保留用:
await magentoRequest(`/V1/orders/${orderId}/hold`, {
method: 'POST'
});
// For unhold: // 保留解除用:
await magentoRequest(`/V1/orders/${orderId}/unhold`, {
method: 'POST'
});
};
請求書の作成
注文の請求書を生成します:
const createInvoice = async (orderId, items = [], notify = true, appendComment = false, comment = null) => {
const invoice = {
capture: true, // true = capture payment // true = 支払いをキャプチャ
last: true,
items: items // Array of {order_item_id, qty} // {order_item_id, qty} の配列
};
if (comment) {
invoice.comment = comment;
invoice.notify_customer = notify ? 1 : 0;
invoice.append_comment = appendComment ? 1 : 0;
}
const response = await magentoRequest(`/V1/order/${orderId}/invoice`, {
method: 'POST',
body: JSON.stringify(invoice)
});
return response;
};
// Usage - Invoice and capture full order // 使用法 - 注文全体の請求書を作成し、支払いをキャプチャ
const invoiceId = await createInvoice(12345, [], true, false, 'Thank you for your order!'); // ご注文ありがとうございます!
console.log(`Invoice created: ${invoiceId}`); // 請求書が作成されました: ${invoiceId}
出荷の作成
注文を出荷します:
const createShipment = async (orderId, items = [], notify = true, appendComment = false, comment = null, tracks = []) => {
const shipment = {
items: items, // Array of {order_item_id, qty} // {order_item_id, qty} の配列
notify: notify ? 1 : 0,
append_comment: appendComment ? 1 : 0,
comment: comment,
tracks: tracks // Array of {track_number, title, carrier_code} // {track_number, title, carrier_code} の配列
};
const response = await magentoRequest(`/V1/order/${orderId}/ship`, {
method: 'POST',
body: JSON.stringify(shipment)
});
return response;
};
// Usage - Ship with tracking // 使用法 - 追跡ありで出荷
const shipmentId = await createShipment(12345, [], true, false, 'Your order has shipped!', [ // ご注文は発送されました!
{
track_number: '1Z999AA10123456784',
title: 'Tracking Number',
carrier_code: 'ups'
}
]);
console.log(`Shipment created: ${shipmentId}`); // 出荷が作成されました: ${shipmentId}
顧客管理
顧客の取得
顧客を取得します:
const getCustomers = async (filters = {}) => {
const params = new URLSearchParams();
if (filters.email) {
params.append('searchCriteria[filterGroups][0][filters][0][field]', 'email');
params.append('searchCriteria[filterGroups][0][filters][0][value]', filters.email);
params.append('searchCriteria[filterGroups][0][filters][0][conditionType]', 'eq');
}
params.append('searchCriteria[pageSize]', filters.limit || 20);
const response = await magentoRequest(`/V1/customers/search?${params.toString()}`);
return response;
};
// Usage // 使用法
const customers = await getCustomers({ email: 'customer@example.com' });
customers.items.forEach(customer => {
console.log(`${customer.firstname} ${customer.lastname} - ${customer.email}`);
});
顧客の作成
新規顧客を登録します:
const createCustomer = async (customerData) => {
const customer = {
customer: {
websiteId: customerData.websiteId || 1,
email: customerData.email,
firstname: customerData.firstname,
lastname: customerData.lastname,
middlename: customerData.middlename || '',
gender: customerData.gender || 0,
store_id: customerData.storeId || 0,
extension_attributes: {
is_subscribed: customerData.subscribed || false
}
},
password: customerData.password
};
const response = await magentoRequest('/V1/customers', {
method: 'POST',
body: JSON.stringify(customer)
});
return response;
};
// Usage // 使用法
const newCustomer = await createCustomer({
email: 'newcustomer@example.com',
firstname: 'John',
lastname: 'Doe',
password: 'SecurePass123!',
subscribed: true
});
console.log(`Customer created: ID ${newCustomer.id}`); // 顧客が作成されました: ID ${newCustomer.id}
在庫管理(MSI)
在庫状況の取得
商品の在庫を確認します:
const getStockStatus = async (sku) => {
const response = await magentoRequest(`/V1/products/${sku}/stockItems/1`);
return response;
};
// Usage // 使用法
const stock = await getStockStatus('TSHIRT-001');
console.log(`Qty: ${stock.qty}`); // 数量: ${stock.qty}
console.log(`In Stock: ${stock.is_in_stock}`); // 在庫あり: ${stock.is_in_stock}
console.log(`Min Qty: ${stock.min_qty}`); // 最小数量: ${stock.min_qty}
在庫の更新
商品数量を更新します:
const updateStock = async (sku, qty, isInStock = null) => {
const stockItem = {
stockItem: {
qty: qty,
is_in_stock: isInStock !== null ? isInStock : qty > 0
}
};
const response = await magentoRequest(`/V1/products/${sku}/stockItems/1`, {
method: 'PUT',
body: JSON.stringify(stockItem)
});
return response;
};
// Usage // 使用法
await updateStock('TSHIRT-001', 100, true);
Webhooksと非同期操作
Webhooksの設定
Magentoは非同期通知にメッセージキューを使用します:
// Magento doesn't have native webhooks // MagentoにはネイティブのWebhooksはありません
// Use these approaches instead: // 代わりにこれらのアプローチを使用してください:
// 1. Poll orders endpoint periodically // 1. 定期的に注文エンドポイントをポーリングする
const pollNewOrders = async (lastOrderId) => {
const orders = await getOrders({
dateFrom: new Date().toISOString()
});
const newOrders = orders.items.filter(o => o.id > lastOrderId);
return newOrders;
};
// 2. Use Adobe I/O Events (Adobe Commerce only) // 2. Adobe I/O Eventsを使用する (Adobe Commerceのみ)
// Configure events in Adobe Developer Console // Adobe Developer Consoleでイベントを設定する
// 3. Create custom webhook module // 3. カスタムwebhookモジュールを作成する
// See: https://devdocs.magento.com/guides/v2.4/extension-dev-guide/message-queues/message-queues.html
レート制限
レート制限の理解
Magentoのレート制限は設定可能です:
- デフォルト: 制限なし(管理画面で設定)
- 推奨: 100-1000リクエスト/分
管理画面で設定: ストア > 設定 > サービス > Web API > セキュリティ
レート制限処理の実装
const makeRateLimitedRequest = async (endpoint, options = {}, maxRetries = 3) => {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await magentoRequest(endpoint, options);
return response;
} catch (error) {
if (error.message.includes('429') && attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
};
本番環境デプロイチェックリスト
本番稼働前に:
- [ ] 本番環境では統合トークンを使用すること(管理者資格情報ではない)
- [ ] トークンを安全に保存すること(暗号化されたデータベース)
- [ ] レート制限とリクエストキューを実装すること
- [ ] 包括的なエラーハンドリングを追加すること
- [ ] すべてのAPIコールについてロギングを設定すること
- [ ] Webhookの代替手段を作成すること(ポーリングまたはAdobe I/O)
- [ ] 本番環境のデータ量でテストすること
- [ ] 失敗したリクエストに対する再試行ロジックを実装すること
実際のユースケース
ERP統合
製造業者が在庫を同期する場合:
- 課題: ERPとMagento間での手動での在庫更新
- 解決策: 15分ごとの双方向API同期
- 結果: リアルタイム在庫、オーバーセリングなし
モバイルアプリ
小売業者がショッピングアプリを構築する場合:
- 課題: ネイティブモバイルエクスペリエンスが必要
- 解決策: 商品閲覧にはGraphQL APIを使用し、チェックアウトにはRESTを使用
- 結果: モバイルコンバージョン率が40%向上
結論
Magento 2 APIは、包括的なEコマース機能を提供します。主なポイント:
- REST、SOAP、およびGraphQL APIが利用可能
- 統合のためのトークンベース認証
- 商品、注文、顧客に対する完全なCRUD
- 高度な在庫管理のためのMSI
- インストールごとに設定可能なレート制限
- ApidogはAPIテストとチームコラボレーションを効率化
よくある質問
Magento APIで認証するにはどうすればよいですか?
内部連携には管理者トークンを使用するか、OAuth用に「システム > 拡張機能」で統合を作成します。顧客向けアプリには顧客トークンを使用します。
MagentoのRESTとGraphQLの違いは何ですか?
RESTは完全なCRUD操作を提供します。GraphQLは、効率的なデータ取得を伴うフロントエンドクエリに最適化されています。
APIを介して商品をどう作成しますか?
/V1/products に、SKU、名前、価格、および `extension_attributes` 内の `stock_item` を含む商品データをPOSTします。
新規注文のwebhookを受け取れますか?
Magentoにはネイティブのwebhookはありません。ポーリング、Adobe I/O Events (Adobe Commerce)、またはカスタムモジュールを作成して使用します。
在庫数量を更新するにはどうすればよいですか?
/V1/products/{sku}/stockItems/1 に、`qty` と `is_in_stock` の値でPUTします。
