TL;DR
La API de Magento 2 (Adobe Commerce) permite integrarte programáticamente con tiendas de e-commerce usando endpoints REST, SOAP y GraphQL, con autenticación OAuth 1.0a y tokens. Podrás acceder y gestionar productos, pedidos, clientes, inventario y más, con límites de velocidad configurables. Esta guía te lleva paso a paso por la autenticación, operaciones CRUD, webhooks, creación de endpoints personalizados y buenas prácticas para producción.
💡 Apidog simplifica las pruebas de integración de API. Testea tus endpoints de Magento, valida autenticaciones, inspecciona respuestas y depura integraciones en un solo workspace. Importa specs, simula respuestas y comparte escenarios de prueba con tu equipo.
¿Qué es la API de Magento 2?
Magento 2 ofrece tres APIs principales:
- API REST: JSON, ideal para web y móviles.
- API SOAP: XML, preferida para integraciones empresariales.
- GraphQL: consultas potentes para frontends modernos.
Puedes manejar:
- Productos, categorías e inventario
- Pedidos, facturas, envíos
- Clientes y grupos de clientes
- Carrito y pago
- Promociones, reglas de precios
- CMS (páginas, bloques)
- Configuración de tienda
Características Clave
| Característica | Descripción |
|---|---|
| Múltiples Protocolos | REST, SOAP, GraphQL |
| OAuth 1.0a | Acceso seguro de terceros |
| Autenticación por Token | Tokens admin/integración |
| Webhooks | Asíncrono vía colas |
| Límite de Velocidad | Configurable |
| Endpoints Personalizados | Extensible mediante módulos |
| Multitienda | Una API, varias vistas de tienda |
Comparación de APIs
| Tipo de API | Protocolo | Caso de Uso |
|---|---|---|
| REST | JSON | Móviles, integraciones externas |
| SOAP | XML | SAP, Oracle, ERPs |
| GraphQL | GraphQL | Frontend, PWA |
Versiones de Magento
| Versión | Estado | Fin de Soporte |
|---|---|---|
| Magento 2.4.x | Actual | Activo |
| Adobe Commerce 2.4.x | Actual | Activo |
| Magento 1.x | EOL | Junio 2020 (No usar) |
Primeros Pasos: Configuración de la Autenticación
Paso 1: Crear Cuenta de Administrador o Integración
- Ingresa al panel de Magento.
- Ve a Sistema > Permisos > Todos los Usuarios para crear un usuario admin (para token de admin).
- O ve a Sistema > Extensiones > Integraciones para crear integración OAuth.
Paso 2: Elige el Método de Autenticación
| Método | Mejor para | Vida Útil del Token |
|---|---|---|
| Token de Admin | Integraciones internas | Configurable (default 4h) |
| Token de Integración | Apps de terceros | Hasta revocación |
| OAuth 1.0a | Apps públicas de mercado | Hasta revocación |
| Token de Cliente | Apps orientadas al cliente | Configurable |
Paso 3: Obtener Token de Administrador (más simple)
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('Credenciales admin inválidas');
const token = await response.text();
return token;
};
// Uso
const token = await getAdminToken();
console.log(`Admin token: ${token}`);
// Guarda el token de forma segura
Recomendación de seguridad: Usa variables de entorno y nunca hardcodees credenciales:
# .env
MAGENTO_BASE_URL="https://store.example.com"
MAGENTO_ADMIN_USERNAME="api_user"
MAGENTO_ADMIN_PASSWORD="secure_password_here"
Paso 4: Crear Integración (recomendado para terceros)
- Ve a Sistema > Extensiones > Integraciones
- Haz clic en Añadir Nueva Integración
- Completa:
- Nombre: “Mi Integración”
- Email: tu-correo@example.com
- URL de Retorno/Enlace de Identidad (si usas OAuth)
- En permisos de API, selecciona los recursos requeridos (productos, pedidos, clientes, inventario).
- Guarda y activa la integración.
- Copia el Token de Acceso y Secreto.
Paso 5: Obtener Token de Cliente
Para apps orientadas al usuario final:
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('Credenciales cliente inválidas');
return await response.text();
};
// Uso
const customerToken = await getCustomerToken('customer@example.com', 'password123');
Paso 6: Llamadas a la API Autenticadas
Crea un cliente reutilizable:
const magentoRequest = async (endpoint, options = {}) => {
const token = await getAdminToken(); // O usa un token almacenado
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(`Productos encontrados: ${products.items.length}`);
Gestión de Productos
Obtener Productos
Consulta con filtros:
const getProducts = async (filters = {}) => {
const params = new URLSearchParams();
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);
return await magentoRequest(`/V1/products?${params.toString()}`);
};
// Uso
const products = await getProducts({ search: 'camiseta', priceFrom: 20, limit: 50 });
products.items.forEach(product => {
console.log(`${product.sku}: ${product.name} - $${product.price}`);
});
Obtener un Solo Producto
const getProduct = async (sku) => {
return await magentoRequest(`/V1/products/${sku}`);
};
// Uso
const product = await getProduct('TSHIRT-001');
console.log(`Nombre: ${product.name}`);
console.log(`Precio: $${product.price}`);
console.log(`Stock: ${product.extension_attributes?.stock_item?.qty}`);
Crear un Producto
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 }
]
}
};
return await magentoRequest('/V1/products', {
method: 'POST',
body: JSON.stringify(product)
});
};
// Uso
const newProduct = await createProduct({
sku: 'TSHIRT-NEW-001',
name: 'Camiseta de Algodón Premium',
price: 29.99,
qty: 100,
description: 'Camiseta de algodón de alta calidad',
shortDescription: 'Camiseta de algodón premium',
color: 'Azul',
size: 'M'
});
console.log(`Producto creado: ${newProduct.id}`);
Actualizar un Producto
const updateProduct = async (sku, updates) => {
const product = {
product: {
sku: sku,
...updates
}
};
return await magentoRequest(`/V1/products/${sku}`, {
method: 'PUT',
body: JSON.stringify(product)
});
};
// Uso
await updateProduct('TSHIRT-001', {
price: 24.99,
extension_attributes: {
stock_item: {
qty: 150,
is_in_stock: true
}
}
});
Eliminar un Producto
const deleteProduct = async (sku) => {
await magentoRequest(`/V1/products/${sku}`, { method: 'DELETE' });
console.log(`Producto ${sku} eliminado`);
};
Tipos de Productos
| Tipo | Descripción | Caso de Uso |
|---|---|---|
| Simple | Un solo SKU, sin variaciones | Productos estándar |
| Configurable | Padre con hijos variaciones | Tallas, colores |
| Agrupado | Colección de simples | Paquetes |
| Virtual | Sin físico | Servicios, descargas |
| Paquete | Kits personalizables | "Arma tu kit" |
| Descargable | Digitales | E-books, software |
Gestión de Pedidos
Obtener Pedidos
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);
return await magentoRequest(`/V1/orders?${params.toString()}`);
};
// Uso
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} - $${order.grand_total}`);
});
Obtener un Solo Pedido
const getOrder = async (orderId) => {
return await magentoRequest(`/V1/orders/${orderId}`);
};
// Uso
const order = await getOrder(12345);
console.log(`Pedido #${order.increment_id}`);
console.log(`Estado: ${order.status}`);
console.log(`Total: $${order.grand_total}`);
console.log(`Artículos:`);
order.items.forEach(item => {
console.log(` - ${item.name} x ${item.qty_ordered}`);
});
Flujo de Estado de Pedido
pendiente → en_proceso → completado
→ cancelado
→ en_espera
→ revisión_de_pago
Actualizar el Estado del Pedido
const updateOrderStatus = async (orderId, newStatus) => {
// Para cancelar:
await magentoRequest(`/V1/orders/${orderId}/cancel`, { method: 'POST' });
// Para poner en espera:
await magentoRequest(`/V1/orders/${orderId}/hold`, { method: 'POST' });
// Para quitar de espera:
await magentoRequest(`/V1/orders/${orderId}/unhold`, { method: 'POST' });
};
Crear Factura
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;
}
return await magentoRequest(`/V1/order/${orderId}/invoice`, {
method: 'POST',
body: JSON.stringify(invoice)
});
};
// Uso
const invoiceId = await createInvoice(12345, [], true, false, '¡Gracias por tu pedido!');
console.log(`Factura creada: ${invoiceId}`);
Crear Envío
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
};
return await magentoRequest(`/V1/order/${orderId}/ship`, {
method: 'POST',
body: JSON.stringify(shipment)
});
};
// Uso
const shipmentId = await createShipment(12345, [], true, false, '¡Tu pedido ha sido enviado!', [
{
track_number: '1Z999AA10123456784',
title: 'Número de Seguimiento',
carrier_code: 'ups'
}
]);
console.log(`Envío creado: ${shipmentId}`);
Gestión de Clientes
Obtener 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);
return await magentoRequest(`/V1/customers/search?${params.toString()}`);
};
// Uso
const customers = await getCustomers({ email: 'customer@example.com' });
customers.items.forEach(customer => {
console.log(`${customer.firstname} ${customer.lastname} - ${customer.email}`);
});
Crear un 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
};
return await magentoRequest('/V1/customers', {
method: 'POST',
body: JSON.stringify(customer)
});
};
// Uso
const newCustomer = await createCustomer({
email: 'newcustomer@example.com',
firstname: 'Juan',
lastname: 'Pérez',
password: 'ContraseñaSegura123!',
subscribed: true
});
console.log(`Cliente creado: ID ${newCustomer.id}`);
Gestión de Inventario (MSI)
Obtener Estado de Stock
const getStockStatus = async (sku) => {
return await magentoRequest(`/V1/products/${sku}/stockItems/1`);
};
// Uso
const stock = await getStockStatus('TSHIRT-001');
console.log(`Cantidad: ${stock.qty}`);
console.log(`En Stock: ${stock.is_in_stock}`);
console.log(`Cantidad Mínima: ${stock.min_qty}`);
Actualizar Stock
const updateStock = async (sku, qty, isInStock = null) => {
const stockItem = {
stockItem: {
qty: qty,
is_in_stock: isInStock !== null ? isInStock : qty > 0
}
};
return await magentoRequest(`/V1/products/${sku}/stockItems/1`, {
method: 'PUT',
body: JSON.stringify(stockItem)
});
};
// Uso
await updateStock('TSHIRT-001', 100, true);
Webhooks y Operaciones Asíncronas
Configurar Webhooks
Magento no tiene webhooks nativos. Alternativas:
// 1. Sondear pedidos periódicamente
const pollNewOrders = async (lastOrderId) => {
const orders = await getOrders({
dateFrom: new Date().toISOString()
});
return orders.items.filter(o => o.id > lastOrderId);
};
// 2. Usar Adobe I/O Events (solo Adobe Commerce)
// Configura eventos en la consola de Adobe
// 3. Desarrolla un módulo webhook personalizado
// Ver: https://devdocs.magento.com/guides/v2.4/extension-dev-guide/message-queues/message-queues.html
Límite de Velocidad
Comprender los Límites
- Por defecto: sin límite (puedes configurarlo)
- Recomendado: 100-1000 req/min
Configura en: Tiendas > Configuración > Servicios > API Web > Seguridad
Implementar Manejo de Límite
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 Verificación de Despliegue en Producción
- [ ] Usa tokens de integración (no admin) en producción
- [ ] Almacena tokens en base de datos cifrada
- [ ] Implementa control de tasa y colas de peticiones
- [ ] Maneja errores exhaustivamente
- [ ] Registra todas las llamadas API
- [ ] Si necesitas webhooks, usa polling o Adobe I/O
- [ ] Testea con volúmenes de datos reales
- [ ] Implementa lógica de reintentos en fallos
Casos de Uso del Mundo Real
Integración ERP
- Problema: Actualización manual de stock ERP-Magento
- Solución: Sincronización API bidireccional cada 15 min
- Resultado: Inventario en tiempo real, sin overselling
Aplicación Móvil
- Problema: Falta de experiencia móvil nativa
- Solución: GraphQL para productos, REST para checkout
- Resultado: +40% conversión móvil
Conclusión
La API de Magento 2 es robusta y cubre todo lo necesario para e-commerce:
- APIs REST, SOAP y GraphQL listas
- Autenticación tokenizada
- CRUD completo para productos, pedidos y clientes
- MSI para inventario avanzado
- Límite de velocidad configurable
- Apidog agiliza pruebas y colaboración
Sección de Preguntas Frecuentes
¿Cómo me autentico con la API de Magento?
Usa token de admin para integraciones internas, o crea una integración en Sistema > Extensiones para OAuth. Para apps cliente, usa token de cliente.
¿Cuál es la diferencia entre REST y GraphQL en Magento?
REST permite CRUD completo. GraphQL es óptimo para queries frontend y obtener solo los datos necesarios.
¿Cómo creo un producto vía API?
Haz POST a /V1/products con datos: SKU, nombre, precio y stock_item en extension_attributes.
¿Puedo tener webhooks para nuevos pedidos?
Magento no ofrece webhooks nativos. Usa polling, Adobe I/O Events (Adobe Commerce) o desarrolla un módulo personalizado.
¿Cómo actualizo cantidades de stock?
Haz PUT a /V1/products/{sku}/stockItems/1 con qty e is_in_stock.
Top comments (0)