Em poucas palavras
A API do Magento 2 (Adobe Commerce) permite que desenvolvedores se integrem a lojas de e-commerce programaticamente. Ela utiliza endpoints REST, SOAP e GraphQL com autenticação OAuth 1.0a e baseada em token, fornecendo acesso a produtos, pedidos, clientes, inventário e muito mais, com limites de taxa configuráveis. Este guia aborda a configuração de autenticação, operações CRUD, webhooks, endpoints personalizados e estratégias de integração de produção.
Introdução
O Adobe Commerce (Magento) impulsiona mais de 250.000 lojas de e-commerce com mais de US$ 155 bilhões em valor bruto de mercadorias anual. Para desenvolvedores que constroem integrações de e-commerce, conectores ERP ou aplicativos móveis, a integração da API do Magento não é opcional — é essencial para alcançar essa enorme base de comerciantes.
Aqui está a realidade: comerciantes que gerenciam múltiplos canais de vendas perdem 20-30 horas semanais em entrada manual de dados entre o Magento e outros sistemas. Uma sólida integração da API do Magento automatiza a sincronização de produtos, processamento de pedidos, atualizações de estoque e gerenciamento de dados de clientes.
Este guia detalha o processo completo de integração da API do Magento 2. Você aprenderá sobre OAuth 1.0a e autenticação por token, endpoints REST/SOAP/GraphQL, gerenciamento de produtos e pedidos, webhooks, desenvolvimento de API personalizada e estratégias de implantação em produção. Ao final, você terá uma integração Magento pronta para produção.
O Que É a API do Magento 2?
O Magento 2 oferece três tipos de API para acesso a dados de e-commerce:
- REST API: Baseada em JSON para aplicações web e móveis
- SOAP API: Baseada em XML para integrações corporativas
- GraphQL: Baseada em query para aplicações frontend eficientes
A API gerencia:
- Produtos, categorias e estoque
- Pedidos, faturas e envios
- Clientes e grupos de clientes
- Carrinho de compras e checkout
- Promoções e regras de precificação
- Páginas e blocos CMS
- Configuração da loja
Principais Recursos
| Recurso | Descrição |
|---|---|
| Múltiplos Protocolos | REST, SOAP, GraphQL |
| OAuth 1.0a | Acesso seguro a terceiros |
| Autenticação por Token | Tokens de administrador e integração |
| Webhooks | Operações assíncronas via filas |
| Limitação de Taxas | Configurável por instalação |
| Endpoints Personalizados | Estender com APIs personalizadas |
| Multi-Store | Uma única API, múltiplas visualizações de loja |
Comparação de APIs
| Tipo de API | Protocolo | Caso de Uso |
|---|---|---|
| REST | JSON | Aplicativos móveis, integrações |
| SOAP | XML | Sistemas corporativos (SAP, Oracle) |
| GraphQL | GraphQL | Storefront, PWA |
Versões do Magento
| Versão | Status | Fim do Suporte |
|---|---|---|
| Magento 2.4.x | Atual | Ativo |
| Adobe Commerce 2.4.x | Atual | Ativo |
| Magento 1.x | Fim da Vida Útil | Junho de 2020 (Não usar) |
Primeiros Passos: Configuração da Autenticação
Passo 1: Criar Conta de Administrador ou Integração
Antes de acessar a API:
- Faça login no Painel de Administração do Magento
- Navegue até Sistema > Permissões > Todos os Usuários
- Crie um usuário administrador (para token de administrador) OU
- Navegue até Sistema > Extensões > Integrações
- Crie uma nova integração (para OAuth)
Passo 2: Escolher Método de Autenticação
| Método | Melhor Para | Tempo de Vida do Token |
|---|---|---|
| Token de Administrador | Integrações internas | Configurável (padrão: 4 horas) |
| Token de Integração | Aplicativos de terceiros | Até ser revogado |
| OAuth 1.0a | Aplicativos de marketplace públicos | Até ser revogado |
| Token de Cliente | Aplicativos voltados para o cliente | Configurável |
Passo 3: Obter Token de Administrador (Método Mais Simples)
Gere token de administrador para integrações internas:
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
const token = await response.text();
return token;
};
// Usage
const token = await getAdminToken();
console.log(`Admin token: ${token}`);
// Store securely - use for subsequent API calls
Nota de segurança: Armazene os tokens de forma segura:
# .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"
Passo 4: Criar Integração (Recomendado para Terceiros)
Crie uma integração via Painel de Administração:
Vá para Sistema > Extensões > Integrações
Clique em Adicionar Nova Integração
Preencha os detalhes:
- Nome: “Minha Integração”
- E-mail: seu-email@example.com
- URL de Retorno (Callback URL): (para OAuth)
- URL de Link de Identidade (Identity Link URL): (para OAuth)
Defina as Permissões da API:
- Recursos: Selecione as permissões necessárias
- Recomendado: Produtos, Pedidos, Clientes, Estoque
Clique em Salvar
Clique em Ativar na nova integração
Copie o Token de Acesso e o Segredo do Token
Passo 5: Obter Token de Cliente
Para aplicações voltadas para o cliente:
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');
Passo 6: Fazer Chamadas de API Autenticadas
Crie um cliente de API reutilizável:
const magentoRequest = async (endpoint, options = {}) => {
const token = await getAdminToken(); // Ou recupere o token armazenado
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}`);
}
return response.json();
};
// Usage
const products = await magentoRequest('/V1/products');
console.log(`Found ${products.items.length} products`);
Gerenciamento de Produtos
Obtendo Produtos
Busque produtos com filtragem:
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}`);
});
Obtendo Um Único Produto
Busque produto por 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}`);
console.log(`Price: $${product.price}`);
console.log(`Stock: ${product.extension_attributes?.stock_item?.qty}`);
Criando um Produto
Crie um produto simples:
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
visibility: productData.visibility || 4, // 4=Catalog & Search
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}`);
Atualizando um Produto
Atualize as informações do produto:
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
}
}
});
Excluindo um Produto
Remova o produto:
const deleteProduct = async (sku) => {
await magentoRequest(`/V1/products/${sku}`, {
method: 'DELETE'
});
console.log(`Product ${sku} deleted`);
};
Tipos de Produto
| Tipo | Descrição | Caso de Uso |
|---|---|---|
| Simples | SKU único, sem variações | Produtos padrão |
| Configurável | Pai com variações de filho | Opções de tamanho/cor |
| Agrupado | Coleção de produtos simples | Pacotes de produtos |
| Virtual | Produtos não físicos | Serviços, downloads |
| Pacote | Pacotes de produtos personalizáveis | Kits "monte o seu" |
| Baixável | Produtos digitais | E-books, software |
Gerenciamento de Pedidos
Obtendo Pedidos
Busque pedidos com filtragem:
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
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}`);
});
Obtendo Um Único Pedido
Busque pedido por 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}`);
console.log(`Status: ${order.status}`);
console.log(`Total: $${order.grand_total}`);
console.log(`Items:`);
order.items.forEach(item => {
console.log(` - ${item.name} x ${item.qty_ordered}`);
});
Fluxo de Status do Pedido
pending → processing → complete
→ canceled
→ on_hold
→ payment_review
Atualizando Status do Pedido
Altere o status do pedido:
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'
});
};
Criando Fatura
Gere fatura para o pedido:
const createInvoice = async (orderId, items = [], notify = true, appendComment = false, comment = null) => {
const invoice = {
capture: true, // true = capture payment
last: true,
items: items // Array of {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}`);
Criando Envio
Envie o pedido:
const createShipment = async (orderId, items = [], notify = true, appendComment = false, comment = null, tracks = []) => {
const shipment = {
items: items, // Array of {order_item_id, qty}
notify: notify ? 1 : 0,
append_comment: appendComment ? 1 : 0,
comment: comment,
tracks: tracks // Array of {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}`);
Gerenciamento de Clientes
Obtendo Clientes
Busque clientes:
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}`);
});
Criando um Cliente
Registre um novo cliente:
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}`);
Gerenciamento de Estoque (MSI)
Obtendo Status de Estoque
Verifique o estoque do produto:
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}`);
console.log(`In Stock: ${stock.is_in_stock}`);
console.log(`Min Qty: ${stock.min_qty}`);
Atualizando Estoque
Atualize a quantidade do produto:
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 e Operações Assíncronas
Configurando Webhooks
O Magento usa filas de mensagens para notificações assíncronas:
// Magento doesn't have native webhooks
// Use these approaches instead:
// 1. Poll orders endpoint periodically
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)
// Configure events in Adobe Developer Console
// 3. Create custom webhook module
// See: https://devdocs.magento.com/guides/v2.4/extension-dev-guide/message-queues/message-queues.html
Limitação de Taxas
Compreendendo os Limites de Taxa
Os limites de taxa do Magento são configuráveis:
- Padrão: Sem limite (configure no Admin)
- Recomendado: 100-1000 requisições/minuto
Configurar no Admin: Lojas > Configuração > Serviços > API Web > Segurança
Implementando o Tratamento de Limites de Taxa
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;
}
}
}
};
Lista de Verificação para Implantação em Produção
Antes de entrar em produção:
- [ ] Use tokens de integração (não credenciais de administrador) em produção
- [ ] Armazene tokens de forma segura (banco de dados criptografado)
- [ ] Implemente limitação de taxa e enfileiramento de requisições
- [ ] Adicione tratamento de erros abrangente
- [ ] Configure o log para todas as chamadas de API
- [ ] Crie uma alternativa de webhook (polling ou Adobe I/O)
- [ ] Teste com o volume de dados de produção
- [ ] Implemente lógica de retry para requisições falhas
Casos de Uso do Mundo Real
Integração ERP
Um fabricante sincroniza o estoque:
- Desafio: Atualizações manuais de estoque entre ERP e Magento
- Solução: Sincronização bidirecional da API a cada 15 minutos
- Resultado: Estoque em tempo real, zero vendas excedentes
Aplicativo Móvel
Um varejista constrói um aplicativo de compras:
- Desafio: Necessidade de experiência móvel nativa
- Solução: API GraphQL para navegação de produtos, REST para checkout
- Resultado: Aumento de 40% na conversão móvel
Conclusão
A API do Magento 2 fornece funcionalidade completa de e-commerce. Principais pontos:
- APIs REST, SOAP e GraphQL disponíveis
- Autenticação baseada em token para integrações
- CRUD completo para produtos, pedidos, clientes
- MSI para gerenciamento avançado de estoque
- Limites de taxa configuráveis por instalação
- Apidog simplifica o teste de API e a colaboração em equipe
Seção de Perguntas Frequentes (FAQ)
Como me autentico com a API do Magento?
Use um token de administrador para integrações internas ou crie uma Integração em Sistema > Extensões para OAuth. Token de cliente para aplicativos voltados para o cliente.
Qual a diferença entre REST e GraphQL no Magento?
REST oferece operações CRUD completas. GraphQL é otimizado para consultas de frontend com busca eficiente de dados.
Como crio um produto via API?
POST para /V1/products com dados do produto, incluindo SKU, nome, preço e stock_item em extension_attributes.
Posso receber webhooks para novos pedidos?
O Magento não possui webhooks nativos. Use polling, Adobe I/O Events (Adobe Commerce) ou crie um módulo personalizado.
Como atualizo as quantidades de estoque?
PUT para /V1/products/{sku}/stockItems/1 com valores de qty e is_in_stock.
