API Webservice PrestaShop: Integración REST, cliente PHP y sincronización ERP
Guía completa de la API Webservice de PrestaShop — operaciones CRUD, librería PHP, autenticación, filtrado, integración ERP/TPV y vista previa de AdminAPI en PS 9.
Qué es el Webservice de PrestaShop
El Webservice de PrestaShop es una API integrada de tipo REST que permite a las aplicaciónes externas leer y escribir datos de la tienda a través de HTTP. Expone recursos — productos, pedidos, clientes, categorías, stock y docenas más — mediante una interfaz estandarizada. XML es el formato predeterminado; JSON está disponible en PS 1.7+ a través del parámetro &output_format=JSON.
Cada versión de PrestaShop desde la 1.4 incluye el Webservice. No es un módulo — forma parte del núcleo. PS 1.6, 1.7, 8.x y 9.x lo soportan.
El Webservice es la forma oficial de integrar PrestaShop con sistemas externos. Las consultas directas a la base de datos omiten la validación, los hooks y la lógica de negocio. La API no.
Casos de uso comunes: sincronizar productos desde un ERP o PIM, exportar pedidos a sistemas de fulfillment, mantener el stock sincronizado entre canales, gestiónar clientes desde un CRM y automatizar operaciónes masivas como actualizaciones de precios.
Activación y configuración de la API
El Webservice está desactivado por defecto. Actívelo en Advanced Parameters > Webservice y luego haga clic en “Add new webservice key”. Para cada clave se establece una descripción, el estado activado/desactivado y una matriz de permisos — una cuadrícula de recursos y métodos HTTP permitidos (GET, POST, PUT, DELETE, HEAD).
Cree claves API separadas para cada integración. Si su ERP solo lee pedidos y actualiza stock, no le otorgue permiso para eliminar productos. Principio de mínimo privilegio.
El Webservice requiere reescritura de URLs. Apache lo gestióna mediante .htaccess en /api/. En Nginx, añada:
location /api/ {
try_files $uri $uri/ /webservice/dispatcher.php?$args;
}
Autenticación
HTTP Basic Auth — la clave API se coloca en el campo de usuario, la contraseña queda en blanco:
curl -u "YOUR_API_KEY:" https://your-store.com/api/products
HTTPS es obligatorio — las claves viajan en cada cabecera de solicitud. La lista blanca de IPs es la medida de seguridad más efectiva para integraciónes con IP fija:
# .htaccess in /api/
<IfModule mod_authz_core.c>
Require ip 10.0.0.5
Require ip 192.168.1.0/24
</IfModule>
Rote las claves cada 6-12 meses. Almacénelas en variables de entorno, nunca en el código fuente.
Recursos disponibles
Llame al endpoint raíz para ver todo lo que su clave puede acceder:
curl -u "KEY:" https://your-store.com/api/
Catálogo: products, combinations, categories, manufacturers, suppliers, product_features, product_feature_values, product_options (grupos de atributos), product_option_values, tags, images
Ventas: orders, order_details (líneas de pedido), order_states, order_histories (cambios de estado), order_carriers (seguimiento), carts, cart_rules
Clientes: customers, addresses, groups
Inventario: stock_availables (recurso principal de stock), warehouses, supply_orders
Configuración: carriers, countries, currencies, languages, taxes, zones, shops
Operaciones CRUD
GET — Lectura de datos
# List products (IDs only)
curl -u "KEY:" https://your-store.com/api/products
# Full details
curl -u "KEY:" "https://your-store.com/api/products?display=full"
# Selected fields only (faster)
curl -u "KEY:" "https://your-store.com/api/products?display=[id,name,price,reference]"
# Single product in JSON
curl -u "KEY:" "https://your-store.com/api/products/42?output_format=JSON"
POST — Creación
Obtenga el esquema XML en blanco, complete los campos obligatorios y envíelo mediante POST:
curl -u "KEY:" -X POST -H "Content-Type: application/xml" \
-d '<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
<product>
<id_category_default>2</id_category_default>
<id_tax_rules_group>1</id_tax_rules_group>
<active>1</active><state>1</state>
<price>29.99</price>
<name><language id="1">My Product</language></name>
<link_rewrite><language id="1">my-product</language></link_rewrite>
<description_short><language id="1">Short desc</language></description_short>
<associations><categories><category><id>2</id></category></categories></associations>
</product>
</prestashop>' https://your-store.com/api/products
PUT — Actualización
Obtenga el recurso actual con GET, modifique los campos y envíe el XML completo de vuelta con PUT. No se admiten actualizaciones parciales.
curl -u "KEY:" https://your-store.com/api/products/42 -o product.xml
# Edit product.xml, then:
curl -u "KEY:" -X PUT -H "Content-Type: application/xml" \
-d @product.xml https://your-store.com/api/products/42
Siempre haga GET antes de PUT. Si construye el XML desde cero y olvida un campo obligatorio, la API puede vaciarlo o rechazar la solicitud.
DELETE
curl -u "KEY:" -X DELETE https://your-store.com/api/products/42
# Multiple: DELETE "https://your-store.com/api/products/?id=[42|43|44]"
DELETE es permanente — no hay papelera ni opción de deshacer. Prefiera establecer active=0 en producción.
Filtrado, ordenación y páginación
# Exact match
?filter[reference]=ABC-123
# Range (price 10-50)
?filter[price]=[10,50]
# Date range
?filter[date_upd]=[2025-01-01,2025-12-31]
# Starts with (% URL-encoded as %25)
?filter[name]=[Nike]%25
# Combined
?filter[active]=1&filter[id_category_default]=5&display=[id,name,price]
# Sorting
?sort=[price_ASC] ?sort=[date_upd_DESC]
# Pagination (offset,count)
?limit=50 # first 50
?limit=50,50 # results 51-100
Descubrimiento de esquemas — dos modos para inspeccionar la estructura de un recurso sin documentación:
?schema=blank # Empty XML template with all fields
?schema=synopsis # Field types, required flags, max lengths, read-only markers
El synopsis le indica exactamente qué campos son obligatorios y qué formato esperan. Consúltelo siempre antes de escribir código de integración.
Trabajo con imágenes
Las imágenes de productos se suben mediante datos multipart form a un endpoint separado:
# Upload
curl -u "KEY:" -X POST -F "image=@photo.jpg;type=image/jpeg" \
"https://your-store.com/api/images/products/42"
# List images for product
curl -u "KEY:" "https://your-store.com/api/images/products/42"
# Get specific image / image type
curl -u "KEY:" "https://your-store.com/api/images/products/42/15/large_default"
# Delete
curl -u "KEY:" -X DELETE "https://your-store.com/api/images/products/42/15"
Subida con PHP:
$ch = curl_init("$shopUrl/api/images/products/$productId");
curl_setopt($ch, CURLOPT_USERPWD, "$apiKey:");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'image' => new CURLFile($imagePath, mime_content_type($imagePath))
]);
$response = curl_exec($ch);
Optimice las imágenes antes de subirlas. Redimensione a un máximo de 2048px y comprima — las fotos de 5MB de una cámara DSLR ralentizarán su tienda.
Combinaciones y atributos
Las combinaciones son la parte más complicada de la API. El modelo de datos tiene tres capas:
- Product Option (grupo de atributos) — Talla, Color, Material
- Product Option Value — S, M, L, Rojo, Azul
- Combination — un conjunto de valores para un producto (Talla:M + Color:Rojo)
Cree en orden: grupo de atributos → valores → combinación:
# Create combination linking to existing attribute values
curl -u "KEY:" -X POST -H "Content-Type: application/xml" \
-d '<prestashop><combination>
<id_product>42</id_product>
<reference>PROD-42-M-RED</reference>
<price>5.00</price>
<minimal_quantity>1</minimal_quantity>
<associations><product_option_values>
<product_option_value><id>2</id></product_option_value>
<product_option_value><id>7</id></product_option_value>
</product_option_values></associations>
</combination></prestashop>' "https://your-store.com/api/combinations"
El price en una combinación es un impacto de precio que se suma al precio base del producto, no el precio final.
Stock por combinación
El stock se gestióna a través de stock_availables, no de la combinación en sí:
# Find stock record
curl -u "KEY:" "https://your-store.com/api/stock_availables?filter[id_product]=42&filter[id_product_attribute]=15&display=full"
# Update (GET first, modify quantity, PUT back)
curl -u "KEY:" -X PUT -H "Content-Type: application/xml" \
-d '<prestashop><stock_available>
<id>89</id><id_product>42</id_product>
<id_product_attribute>15</id_product_attribute>
<quantity>100</quantity>
</stock_available></prestashop>' "https://your-store.com/api/stock_availables/89"
El registro de stock a nivel de producto (id_product_attribute=0) contiene la suma de todas las combinaciones. Actualice el stock a nivel de combinación y PrestaShop recalcula el total automáticamente.
Pedidos y carrito
# Recent orders
curl -u "KEY:" "https://your-store.com/api/orders?display=[id,reference,total_paid,current_state,date_add]&sort=[id_DESC]&limit=20"
# Full order with line items
curl -u "KEY:" "https://your-store.com/api/orders/1234?display=full"
curl -u "KEY:" "https://your-store.com/api/order_details?filter[id_order]=1234&display=full"
Actualización del estado del pedido
Cree un nuevo registro order_history — esto activa el cambio de estado y envía el correo electrónico al cliente:
curl -u "KEY:" -X POST -H "Content-Type: application/xml" \
-d '<prestashop><order_history>
<id_order>1234</id_order>
<id_order_state>4</id_order_state>
</order_history></prestashop>' "https://your-store.com/api/order_histories"
IDs de estado predeterminados: 1=Esperando pago, 2=Pago aceptado, 3=En preparación, 4=Enviado, 5=Entregado, 6=Cancelado, 7=Reembolsado. Estos varían según la instalación — consulte order_states para obtener la lista real de su tienda.
Números de seguimiento: obtenga el registro order_carriers del pedido, añada tracking_number y envíelo de vuelta con PUT.
Crear pedidos vía API es técnicamente posible pero no recomendable. La creación de pedidos implica validación del carrito, cálculo de impuestos, procesamiento del pago, deducción de stock y ejecución de hooks — la API omite la mayoría de estos pasos. Para importaciones desde marketplaces, cree un carrito vía API y procéselo a través de un front controller personalizado.
Biblioteca cliente PHP
composer require prestashop/prestashop-webservice-lib
O descargue el archivo único desde GitHub.
$ws = new PrestaShopWebservice('https://your-store.com', 'API_KEY', false);
// List products
$xml = $ws->get(['resource' => 'products', 'display' => 'full', 'limit' => 10]);
foreach ($xml->products->product as $p) {
echo $p->id . ' - ' . $p->name->language . "\n";
}
// Create product from blank schema
$blank = $ws->get(['url' => 'https://your-store.com/api/products?schema=blank']);
$blank->product->active = 1;
$blank->product->price = 29.99;
$blank->product->name->language[0] = 'New Product';
$blank->product->name->language[0]['id'] = 1;
$blank->product->link_rewrite->language[0] = 'new-product';
$blank->product->link_rewrite->language[0]['id'] = 1;
$blank->product->id_category_default = 2;
$result = $ws->add(['resource' => 'products', 'postXml' => $blank->asXML()]);
// Update stock
function updateStock($ws, int $pid, int $qty, int $combo = 0): void {
$xml = $ws->get([
'resource' => 'stock_availables',
'filter[id_product]' => $pid,
'filter[id_product_attribute]' => $combo,
'display' => 'full'
]);
$sid = (int)$xml->stock_availables->stock_available->id;
$sxml = $ws->get(['resource' => 'stock_availables', 'id' => $sid]);
$sxml->stock_available->quantity = $qty;
$ws->edit(['resource' => 'stock_availables', 'id' => $sid, 'putXml' => $sxml->asXML()]);
}
// Export orders since date
$xml = $ws->get([
'resource' => 'orders',
'display' => '[id,reference,total_paid,current_state,date_add]',
'filter[date_add]' => '[2025-06-01,9999-12-31]',
'sort' => '[date_add_DESC]', 'limit' => 500
]);
Patrones de integración
Integración con ERP
El escenario más común. Los productos, precios y stock fluyen desde el ERP hacia PrestaShop; los pedidos y datos de clientes fluyen de vuelta. Buenas prácticas: utilice códigos de referencia (SKU/EAN) como identificadores compartidos, programe la sincronización de stock cada 15 minutos y la de productos cada hora, rastree la marca de tiempo de la última sincronización con filter[date_upd], decida la resolución de conflictos de antemano (el ERP suele tener prioridad) y registre todo.
Almacén y TPV
El WMS sigue un ciclo: recibir mercancía → actualizar stock vía API; consultar pedidos → enviar → actualizar seguimiento vía API. La integración con TPV es similar — el stock debe sincronizarse en tiempo casi real para que las compras en tienda física reduzcan inmediatamente la disponibilidad en línea.
Sincronización con marketplaces
Las integraciónes con Allegro, Amazon y eBay necesitan exportación de productos con imágenes, importación de pedidos (mediante carrito + procesamiento personalizado en lugar de POST directo de pedidos) y sincronización bidirecciónal de stock para evitar la sobreventa.
Contabilidad
Solo lectura: extraiga pedidos, facturas y notas de crédito de forma diaria/semanal. Solo necesita permisos GET.
Cambios en la API de PrestaShop 9
El Webservice heredado sigue funcionando en PS 9 — no está obsoleto. Las integraciónes existentes funcionan tras la actualización.
AdminAPI — Nueva API basada en Symfony
PS 9 introduce una nueva AdminAPI junto al Webservice heredado. Diferencias clave:
- Autenticación: OAuth2 con credenciales de cliente (frente a Basic Auth con clave API)
- Formato: Solo JSON (frente a XML por defecto)
- Arquitectura: Symfony / API Platform con documentación OpenAPI/Swagger en
/admin-api/docs - Cobertura: En crecimiento — aún no cubre todos los recursos del Webservice heredado
# Get OAuth2 token
curl -X POST https://your-store.com/admin-api/access_token \
-d "grant_type=client_credentials&client_id=ID&client_secret=SECRET"
# Use bearer token
curl -H "Authorization: Bearer eyJ0eXAi..." https://your-store.com/admin-api/products
Los tokens expiran (por defecto: 1 hora) — gestióne la renovación en su integración. Los scopes (product_read, product_write, order_read) controlan el acceso de forma granular. Cree clientes API en Advanced Parameters > AdminAPI.
Utilice AdminAPI para nuevas integraciónes con PS 9+. Utilice el Webservice heredado para una cobertura amplia de recursos o compatibilidad con PS 1.6/1.7/8.x. Puede usar ambos en la misma integración.
Problemas comunes
401 Unauthorized: Clave incorrecta (verifique espacios en blanco), clave desactivada, Webservice desactivado, o clave enviada como parámetro de consulta en lugar de cabecera Basic Auth.
403 Forbidden: La clave no tiene permiso para el recurso o el método HTTP. Revise la matriz de permisos.
404 Not Found: El recurso no existe o la reescritura de URLs no funciona. Pruebe: curl -u "KEY:" "https://store.com/webservice/dispatcher.php?url=products" — si esto funciona pero /api/products no, corrija las reglas de reescritura.
Errores de análisis XML: Use CDATA para caracteres especiales (<![CDATA[HTML & more]]>), siempre envuelva en el elemento raíz <prestashop> y envíe UTF-8 con la cabecera Content-Type adecuada.
Operaciones masivas lentas: La API procesa una solicitud a la vez. Para más de 10.000 elementos:
- Solicite solo los campos necesarios con
display— evitedisplay=fullen catálogos grandes - Filtre por
date_updpara sincronizar solo los registros modificados - Reutilice los handles de curl para conexiónes persistentes
- Para importaciones iniciales de más de 50.000 elementos, considere el acceso directo a la base de datos con limpieza de caché
// Efficient bulk stock update – reuse handle
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERPWD, "$apiKey:");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/xml']);
foreach ($updates as $stockId => $qty) {
curl_setopt($ch, CURLOPT_URL, "$url/api/stock_availables/$stockId");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS,
"<prestashop><stock_available><id>$stockId</id><quantity>$qty</quantity></stock_available></prestashop>");
curl_exec($ch);
}
curl_close($ch);
Buenas prácticas de seguridad
- Una clave por integración — revoque una sin afectar a las demás
- Permisos mínimos — la sincronización de stock no necesita DELETE en productos
- HTTPS siempre — las claves en HTTP plano son visibles para los rastreadores de red
- Lista blanca de IPs — la medida individual más efectiva para integraciónes servidor a servidor
- Rotación de claves — cada 6-12 meses
- Variables de entorno — nunca suba claves al control de versiones
- Limitación de tasa — la API no tiene una integrada; añádala a nivel de servidor web
# Nginx rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
location /api/ {
limit_req zone=api burst=50 nodelay;
try_files $uri $uri/ /webservice/dispatcher.php?$args;
}
Registro de auditoría: PrestaShop no tiene registro de API integrado. Analice los logs de acceso del servidor web para solicitudes a /api/, o sobrescriba WebserviceRequest para registrar marca de tiempo, IP, recurso, método y código de respuesta. Es esencial para el cumplimiento de GDPR/PCI cuando se accede a datos de clientes.
Alternativas al Webservice
Acceso directo a la base de datos
Órdenes de magnitud más rápido para operaciónes masivas, pero omite la validación, los hooks y la invalidación de caché. Apropiado para importaciones puntuales, informes de solo lectura y correcciones de emergencia. No apropiado para sincronización continua ni para nada que afecte a pedidos o pagos. Siempre limpie las cachés después de cambios directos en la base de datos.
Hooks de módulo para sincronización en tiempo real
En lugar de consultar la API periódicamente, envíe datos mediante hooks cuando ocurran eventos:
public function hookActionProductUpdate($params) {
$product = $params['product'];
$payload = json_encode([
'id' => $product->id, 'reference' => $product->reference,
'price' => $product->price,
'quantity' => StockAvailable::getQuantityAvailableByProduct($product->id),
]);
$ch = curl_init('https://erp.example.com/webhook/product-update');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_exec($ch); curl_close($ch);
}
Endpoints personalizados de módulo
Para operaciónes que el Webservice gestióna de forma deficiente, construya una API personalizada como front controller de módulo. Control total sobre formato, autenticación y lógica de negocio — procese operaciónes masivas en una sola solicitud utilizando las clases nativas de PrestaShop para la validación.
Cómo elegir el enfoque adecuado
| Escenario | Mejor enfoque |
|---|---|
| Integración estándar con ERP/WMS | Webservice API |
| Nueva integración para PS 9+ | AdminAPI (OAuth2, JSON) |
| Importación masiva de más de 50.000 productos | Base de datos directa + limpieza de caché |
| Sincronización de eventos en tiempo real | Hooks de módulo (push mediante webhook) |
| Lógica de negocio personalizada | Endpoint personalizado de módulo |
| Informes de solo lectura | Consultas directas a la base de datos |
El Webservice de PrestaShop ha sido estable durante más de una década. Para PS 9+, la AdminAPI ofrece una alternativa moderna. Elija la herramienta adecuada para cada tarea, implémentela con seguridad y gestión de errores desde el primer día, y siempre pruebe contra la versión específica de PrestaShop a la que se dirige.
More guides available
Browse our knowledge base for more practical PrestaShop tutorials, or reach out if you need help.