Em poucas palavras
A API do Magento 2 (Adobe Commerce) permite que desenvolvedores integrem lojas de e-commerce de forma programática. Utilizando endpoints REST, SOAP e GraphQL com autenticação OAuth 1.0a e baseada em token, você acessa produtos, pedidos, clientes, inventário e mais, com limites de taxa configuráveis. Este guia ensina a configurar autenticação, executar operações CRUD, usar webhooks, criar endpoints personalizados e estratégias para integração em produção.
Introdução
O Adobe Commerce (Magento) é a base de mais de 250.000 lojas online, movimentando mais de US$ 155 bilhões em mercadorias por ano. Para desenvolvedores criando integrações, conectores ERP ou apps móveis, integrar a API do Magento é fundamental para atingir esse mercado.
Sem integração, lojistas perdem 20-30 horas semanais em tarefas manuais entre Magento e outros sistemas. Automatize a sincronização de produtos, pedidos, estoque e dados de clientes com a API do Magento.
Este guia mostra o processo de integração da API do Magento 2: autenticação OAuth 1.0a/token, endpoints REST/SOAP/GraphQL, gerenciamento de produtos e pedidos, webhooks, APIs personalizadas e implantação. No final, você terá uma integração pronta para produção.
💡 Dica: O Apidog simplifica os testes de integração de API. Teste endpoints do Magento, valide autenticação, inspecione respostas e depure integrações em um só workspace. Importe especificações, simule respostas e compartilhe testes com a equipe.
O Que É a API do Magento 2?
O Magento 2 fornece três tipos de API para acesso aos dados de e-commerce:
- REST API: JSON para web e mobile apps
- SOAP API: XML para integrações empresariais
- GraphQL: Consultas otimizadas para frontend
Você pode gerenciar:
- Produtos, categorias, estoque
- Pedidos, faturas, envios
- Clientes e grupos
- Carrinho e checkout
- Promoções e regras de preço
- CMS (páginas/blocos)
- Configurações 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 | Estenda com APIs customizadas |
| Multi-Store | Uma API, múltiplas lojas |
Comparação de APIs
| Tipo de API | Protocolo | Caso de Uso |
|---|---|---|
| REST | JSON | Mobile apps, integrações |
| SOAP | XML | Sistemas corporativos (SAP etc.) |
| 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/2020 (Não usar) |
Primeiros Passos: Configuração da Autenticação
Passo 1: Criar Conta de Administrador ou Integração
- Acesse o admin do Magento
- Vá em Sistema > Permissões > Todos os Usuários e crie um usuário admin (para token de admin) OU
- Em 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 4h) |
| Token de Integração | Apps de terceiros | Até revogar |
| OAuth 1.0a | Apps públicos/marketplace | Até revogar |
| Token de Cliente | Apps para clientes finais | Configurável |
Passo 3: Obter Token de Administrador (Mais Simples)
Gere o token de admin para uso interno:
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;
};
// Uso
const token = await getAdminToken();
console.log(`Admin token: ${token}`);
// Armazene com segurança e use para chamadas autenticadas
Segurança: Armazene tokens de forma segura:
# .env
MAGENTO_BASE_URL="https://store.example.com"
MAGENTO_ADMIN_USERNAME="api_user"
MAGENTO_ADMIN_PASSWORD="senha_segura"
MAGENTO_ACCESS_TOKEN="token_obtido"
Passo 4: Criar Integração (Terceiros)
- No admin, vá em Sistema > Extensões > Integrações
- Clique em Adicionar Nova Integração
- Preencha Nome, Email, Callback URL (OAuth), Identity Link URL (OAuth)
- Defina Permissões da API: selecione Produtos, Pedidos, Clientes, Estoque conforme necessário
- Salve e ative a integração
- Copie o Token de Acesso e Segredo do Token
Passo 5: Obter Token de Cliente
Para apps voltados para clientes:
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;
};
// Uso
const customerToken = await getCustomerToken('customer@example.com', 'password123');
Passo 6: Fazer Chamadas de API Autenticadas
Crie um cliente reutilizável para requisições autenticadas:
const magentoRequest = async (endpoint, options = {}) => {
const token = await getAdminToken(); // Ou recupere token já 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();
};
// Uso
const products = await magentoRequest('/V1/products');
console.log(`Encontrados ${products.items.length} produtos`);
Gerenciamento de Produtos
Obtendo Produtos
Busque produtos com filtros:
const getProducts = async (filters = {}) => {
const params = new URLSearchParams();
// Monta 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;
};
// Exemplo de uso
const products = await getProducts({ search: 'shirt', priceFrom: 20, limit: 50 });
products.items.forEach(product => {
console.log(`${product.sku}: ${product.name} - R$${product.price}`);
});
Obtendo Um Único Produto
Por SKU:
const getProduct = async (sku) => {
const response = await magentoRequest(`/V1/products/${sku}`);
return response;
};
// Exemplo
const product = await getProduct('TSHIRT-001');
console.log(`Name: ${product.name}`);
console.log(`Price: R$${product.price}`);
console.log(`Stock: ${product.extension_attributes?.stock_item?.qty}`);
Criando um Produto
const createProduct = async (productData) => {
const product = {
product: {
sku: productData.sku,
name: productData.name,
attribute_set_id: productData.attributeSetId || 4,
type_id: 'simple',
price: productData.price,
status: productData.status || 1,
visibility: productData.visibility || 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;
};
// Exemplo
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(`Produto criado: ${newProduct.id}`);
Atualizando um 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;
};
// Exemplo: atualizar preço e estoque
await updateProduct('TSHIRT-001', {
price: 24.99,
extension_attributes: {
stock_item: {
qty: 150,
is_in_stock: true
}
}
});
Excluindo um Produto
const deleteProduct = async (sku) => {
await magentoRequest(`/V1/products/${sku}`, {
method: 'DELETE'
});
console.log(`Produto ${sku} excluído`);
};
Tipos de Produto
| Tipo | Descrição | Caso de Uso |
|---|---|---|
| Simples | SKU único, sem variação | Produto padrão |
| Configurável | Pai com variações filhos | Tamanho/cor |
| Agrupado | Coleção de produtos | Pacotes |
| Virtual | Não físico | Serviços/downloads |
| Pacote | Pacote personalizável | Kits "monte o seu" |
| Baixável | Produto digital | E-books/software |
Gerenciamento de Pedidos
Obtendo Pedidos
Filtrando por status/data:
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;
};
// Exemplo: pedidos pendentes dos últimos 7 dias
const orders = await getOrders({
status: 'pending',
dateFrom: '2026-03-18 00:00:00',
limit: 50
});
orders.items.forEach(order => {
console.log(`Pedido #${order.increment_id}: ${order.customer_email} - R$${order.grand_total}`);
});
Obtendo Um Único Pedido
Por ID:
const getOrder = async (orderId) => {
const response = await magentoRequest(`/V1/orders/${orderId}`);
return response;
};
// Exemplo
const order = await getOrder(12345);
console.log(`Pedido #${order.increment_id}`);
console.log(`Status: ${order.status}`);
console.log(`Total: R$${order.grand_total}`);
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
Alterações diretas de status exigem endpoint customizado. Use o workflow padrão:
// Cancelar pedido
await magentoRequest(`/V1/orders/${orderId}/cancel`, { method: 'POST' });
// Colocar em espera
await magentoRequest(`/V1/orders/${orderId}/hold`, { method: 'POST' });
// Retirar de espera
await magentoRequest(`/V1/orders/${orderId}/unhold`, { method: 'POST' });
Criando Fatura
const createInvoice = async (orderId, items = [], notify = true, appendComment = false, comment = null) => {
const invoice = {
capture: true,
last: true,
items: items
};
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;
};
// Faturar pedido completo
const invoiceId = await createInvoice(12345, [], true, false, 'Obrigado pelo pedido!');
console.log(`Fatura criada: ${invoiceId}`);
Criando Envio
const createShipment = async (orderId, items = [], notify = true, appendComment = false, comment = null, tracks = []) => {
const shipment = {
items: items,
notify: notify ? 1 : 0,
append_comment: appendComment ? 1 : 0,
comment: comment,
tracks: tracks
};
const response = await magentoRequest(`/V1/order/${orderId}/ship`, {
method: 'POST',
body: JSON.stringify(shipment)
});
return response;
};
// Enviar com rastreamento
const shipmentId = await createShipment(12345, [], true, false, 'Seu pedido foi enviado!', [
{
track_number: '1Z999AA10123456784',
title: 'Tracking Number',
carrier_code: 'ups'
}
]);
console.log(`Envio criado: ${shipmentId}`);
Gerenciamento de Clientes
Obtendo 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;
};
// Exemplo
const customers = await getCustomers({ email: 'customer@example.com' });
customers.items.forEach(customer => {
console.log(`${customer.firstname} ${customer.lastname} - ${customer.email}`);
});
Criando um 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;
};
// Exemplo
const newCustomer = await createCustomer({
email: 'newcustomer@example.com',
firstname: 'John',
lastname: 'Doe',
password: 'SecurePass123!',
subscribed: true
});
console.log(`Cliente criado: ID ${newCustomer.id}`);
Gerenciamento de Estoque (MSI)
Obtendo Status de Estoque
const getStockStatus = async (sku) => {
const response = await magentoRequest(`/V1/products/${sku}/stockItems/1`);
return response;
};
// Exemplo
const stock = await getStockStatus('TSHIRT-001');
console.log(`Qtde: ${stock.qty}`);
console.log(`Em estoque: ${stock.is_in_stock}`);
console.log(`Mínimo: ${stock.min_qty}`);
Atualizando Estoque
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;
};
// Exemplo
await updateStock('TSHIRT-001', 100, true);
Webhooks e Operações Assíncronas
Configurando Webhooks
O Magento não tem webhooks nativos. Use estas abordagens:
// 1. Polling periódico
const pollNewOrders = async (lastOrderId) => {
const orders = await getOrders({
dateFrom: new Date().toISOString()
});
const newOrders = orders.items.filter(o => o.id > lastOrderId);
return newOrders;
};
// 2. Adobe I/O Events (Adobe Commerce)
// Configure na Adobe Developer Console
// 3. Crie módulo webhook customizado
// Ver: https://devdocs.magento.com/guides/v2.4/extension-dev-guide/message-queues/message-queues.html
Limitação de Taxas
Compreendendo os Limites de Taxa
- Padrão: Sem limite (configure no Admin)
- Recomendado: 100-1000 requisições/minuto
Configuração em: Lojas > Configuração > Serviços > API Web > Segurança
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 ir para produção:
- [ ] Use tokens de integração (não admin) em produção
- [ ] Armazene tokens de forma segura (banco criptografado)
- [ ] Implemente limitação de taxa e enfileiramento
- [ ] Adicione tratamento robusto de erros
- [ ] Faça log de todas as chamadas de API
- [ ] Implemente alternativa de webhook (polling ou Adobe I/O)
- [ ] Teste com volume de dados real
- [ ] Implemente lógica de retry para falhas
Casos de Uso do Mundo Real
Integração ERP
- Desafio: Atualização manual de estoque entre ERP e Magento
- Solução: Sincronização via API a cada 15 minutos
- Resultado: Estoque em tempo real, sem vendas excedentes
Aplicativo Móvel
- Desafio: Necessidade de experiência nativa
- Solução: GraphQL para navegação, REST para checkout
- Resultado: +40% conversão mobile
Conclusão
A API do Magento 2 oferece e-commerce completo via integração. Pontos principais:
- APIs REST, SOAP e GraphQL disponíveis
- Autenticação baseada em token
- CRUD completo para produtos, pedidos e clientes
- MSI para gestão avançada de estoque
- Limites de taxa configuráveis
- Apidog facilita testes de API e colaboração
Seção de Perguntas Frequentes (FAQ)
Como me autentico com a API do Magento?
Use token de administrador para integrações internas ou crie Integração em Sistema > Extensões para OAuth. Use token de cliente para apps frontend.
Qual a diferença entre REST e GraphQL no Magento?
REST faz operações CRUD completas. GraphQL é otimizado para queries eficientes em frontend.
Como crio um produto via API?
POST para /V1/products com dados do produto (SKU, nome, preço, stock_item em extension_attributes).
Posso receber webhooks para novos pedidos?
Magento não tem webhooks nativos. Use polling, Adobe I/O Events (Adobe Commerce) ou módulo customizado.
Como atualizo as quantidades de estoque?
PUT em /V1/products/{sku}/stockItems/1 com qty e is_in_stock.
Top comments (0)