En algunos proyectos se requiere que una tienda de WooCommerce se integre con algún otro sistema. En este artículo veremos cómo integrar WooCommerce a través de su API para que actualice el stock de productos obtenidos desde un sistema externo.
Generalidades
En la siguiente imagen se muestra la estructura general de lo que queremos conseguir, por el lado derecho tenemos la API externa que nos proveerá los datos de origen, estos serán interpretados por código y llevados a la parte izquierda en donde se encuentra nuestra tienda con WooCommerce.
Stock Inicial: Inicialmente tendremos algunos productos que tienen el stock y el precio desactualizado, tal como se muestra en la siguiente imagen.
Datos API origen: Vemos que la API extena desde la que obtendremos los datos tiene la información actualizada para estos productos.
Ejecución de código: Al ejecutar el código desde la ventana de comandos veremos que el proceso se realiza correctamente.
Resultado Final: Al final obtendremos el stock y el precio de los productos de la tienda actualizados.
Pre requisitos
Tienes que tener en cuenta los siguientes pre requisitos:
- Una API como origen y que devuelva la información en formato Json, la identificación de los productos es a través del SKU.
- La API de WooCommerce como destino, Para realizar esto puedes revisar el artículo: Cómo usar la REST API de WooCommerce.
- Un entorno en donde puedas correr PHP desde la línea de comandos
- El administrador de dependencias Composer instalado
Código para actualizar el stock y precio de productos usando la API de WooCommerce
El siguiente código puedes usarlo como parte de un plugin, como código en un archivo independiente, o ejecutarlo a través de la línea de comandos, tal como vemos en este artículo.
- Antes de ejecutar el código necesitas instalar las dependencias usando Composer.
- Puedes descargarte el código completo desde el repositorio de GitHub: Ir al Repositorio
require __DIR__ . '/vendor/autoload.php';
use Automattic\WooCommerce\Client;
// Conexión WooCommerce API destino
// ================================
$url_API_woo = 'https://tuempresa.site/';
$ck_API_woo = 'ck_5fde0679616fe2363980edf8a2061e815682e2ff';
$cs_API_woo = 'cs_992d905e88b2a119fc8e786d181e309d0685a4c0';
$woocommerce = new Client(
$url_API_woo,
$ck_API_woo,
$cs_API_woo,
['version' => 'wc/v3']
);
// ================================
// Conexión API origen
// ===================
$url_API="http://localhost:3000/inventory/";
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL,$url_API);
echo "➜ Obteniendo datos origen ... \n";
$items_origin = curl_exec($ch);
curl_close($ch);
if ( ! $items_origin ) {
exit('❗Error en API origen');
}
// ===================
// Obtenemos datos de la API de origen
$items_origin = json_decode($items_origin, true);
// formamos el parámetro de lista de SKUs a actualizar
$param_sku ='';
foreach ($items_origin as $item){
$param_sku .= $item['sku'] . ',';
}
echo "➜ Obteniendo los ids de los productos... \n";
// Obtenemos todos los productos de la lista de SKUs
$products = $woocommerce->get('products/?sku='. $param_sku);
// Construimos la data en base a los productos recuperados
$item_data = [];
foreach($products as $product){
// Filtramos el array de origen por sku
$sku = $product->sku;
$search_item = array_filter($items_origin, function($item) use($sku) {
return $item['sku'] == $sku;
});
$search_item = reset($search_item);
// Formamos el array a actualizar
$item_data[] = [
'id' => $product->id,
'regular_price' => $search_item['price'],
'stock_quantity' => $search_item['qty'],
];
}
// Construimos información a actualizar en lotes
$data = [
'update' => $item_data,
];
echo "➜ Actualización en lote ... \n";
// Actualización en lotes
$result = $woocommerce->post('products/batch', $data);
if (! $result) {
echo("❗Error al actualizar productos \n");
} else {
print("✔ Productos actualizados correctamente \n");
}
En el código anterior:
- La primera parte del código establece la conexión con la API de WooCommerce que será el destino al cual actualizaremos los datos
- Luego establecemos la conexión para la API de origen, vemos que en los datos de la API de origen tenemos el SKU del producto
- Puesto que para realizar la ejecución de actualizaciones por lotes necesitamos el ID del producto, entonces antes necesitamos recuperar los productos en base a su SKU
- Recorremos los productos y vamos formando el array de los datos a actualizar
- Finalmente realizamos la actualización por lotes
Conclusión
En algunos proyectos es posible que requieras integrar WooCommerce con otro servicio externo ya sea para actualizar precios o stocks, tal como hemos visto en este artículo puedes hacer esto a través de código usando la API de WooCommerce.
Ver comentarios (127)
Estimado.
Siguiendo su ejemplo no logro actualizar el SRC de la o las imagenes, como se podria hacer?
Mi código es:
Agradezco su ayuda desde ya
Hola,
¿Te aparece algún error?, si el $id_destino y la $ruta_imagen es válido no deberías tener problemas.
Prueba hacerlo sin batch, es decir actualiza un solo producto, puedes guiarte de: https://woocommerce.github.io/woocommerce-rest-api-docs/#update-a-product
Estimado, no me aparece ningún error de hecho logro sacar dos imagenes y en biblioteca de medios quedan adjuntas al producto que corresponde, sin embargo, no las muestra en el producto y no actualiza los demás productos. Usted ha hecho actualización de imagenes de un Woo a otro Woo?
Ya encontré el error, resulta que no hace la actualización cuando el producto tiene más de una imagen.
Cuando el producto tiene una sola imagen no hay problema.
Que podre hacer??
Intento instalar las dependencias en la terminal de mi macbook pro pero no me deja, me regresa esto
MacBook-Pro-de-minombre:Update-inventory-WooCommerce-master minombre$ composer install
-bash: composer: command not found
Hola, tienes que primero instalar Composer
Increíble tus publicaciones, son muy buenas y útiles, realmente te agradezco mucho. Un saludo y sigue asi porque es excelente el material
Gracias Claudio :)
Hola, te consulto como se generan los "Datos API origen" ? Veo que estan en la carpeta 'data-example' del archivo .zip que descargo, pero en el codigo de index.php el acceso a los datos origen es http://localhost:3000/inventory/ Como genero ese link en mi pc para poder acceder y verlo como tu ejemplo.
Jhon aprovecho a decirte GRACIAS por los videos, son geniales y explicados fantasticamente.
Hola Cesar, gracias, en el ejemplo he usado https://nodejs.org/ como servidor y he instalado este paquete: https://www.npmjs.com/package/json-server , con eso tienes un servidor rápido de pruebas que te devuelve un json.
buen dia, excelente tutorial, consulta: cuando me da un error "woocommerce_rest_authentication_missing_parameter" a que se debe? he puesto los parametros url_API_woo, ck_API_woo y cs_API_woo de forma adecuada
Holas estas usando correctamente la librería https://packagist.org/packages/automattic/woocommerce?, revisa primero este artículo y asegúrate de que se conecte correctamente https://decodecms.com/como-usar-la-rest-api-de-woocommerce/
Hola lo intento hacer con una conexion sql como origen.
Hasta ahi todo bien
var_dump($param_sku);
Me devuelve: string(36) "PAI00033,ATL00005,PAI00030,ATL00007,"
pero la siguente linea
$products = $woocommerce->get('products/?sku='. $param_sku);
me devuelve Fatal error:
Sabes a que se debe?
Uncaught Automattic\WooCommerce\HttpClient\HttpClientException: Error: Lo siento, no puedes listar recursos. [woocommerce_rest_cannot_view] in C:\xampp\htdocs\UpWoo\vendor\automattic\woocommerce\src\WooCommerce\HttpClient\HttpClient.php:350 Stack trace: #0 C:\xampp\htdocs\UpWoo\vendor\automattic\woocommerce\src\WooCommerce\HttpClient\HttpClient.php(386): Automattic\WooCommerce\HttpClient\HttpClient->lookForErrors(Object(stdClass)) #1 C:\xampp\htdocs\UpWoo\vendor\automattic\woocommerce\src\WooCommerce\HttpClient\HttpClient.php(422): Automattic\WooCommerce\HttpClient\HttpClient->processResponse() #2 C:\xampp\htdocs\UpWoo\vendor\automattic\woocommerce\src\WooCommerce\Client.php(82): Automattic\WooCommerce\HttpClient\HttpClient->request('products/?sku=P...', 'GET', Array, Array) #3 C:\xampp\htdocs\UpWoo\index.php(83): Automattic\WooCommerce\Client->get('products/?sku=P...') #4 {main} thrown in C:\xampp\htdocs\UpWoo\vendor\automattic\woocommerce\src\WooCommerce\HttpClient\HttpClient.php on line 350
Hola, revisa si tienes activas las urls amigables de tu sitios web, desde Ajustes > Enlaces Permanentes, ya que se requiere esto en el get de WooCommerce.
Tengo el mismo error:
➜ Obteniendo datos origen ... ➜ Obteniendo los ids de los productos...
Fatal error: Uncaught Automattic\WooCommerce\HttpClient\HttpClientException: Error: Lo siento, no puedes listar recursos. [woocommerce_rest_cannot_view] in /home/customer/www/kariokids.com/public_html/conector/vendor/automattic/woocommerce/src/WooCommerce/HttpClient/HttpClient.php:350 Stack trace: #0
Me ha dado varios problemas, en un hosting vps dreamhost no conecto la API (no abre) y no tengo acceso a la configuración. Ahora estoy probando ahora en un siteground y abrió la API, pero me sale el mismo error del amigo anterior, esto con la versión wp 5.5.1 wc 4.5.1. Ayer u hoy hubo un update de WC
Alguna idea?
Hola, usualmente sale porque no tienes las urls amigables configuradas, pero podría ser también alguna configuración de servidor, revisa por ejemplo: https://github.com/woocommerce/wc-api-php/issues/261
hola, tengo un caso en el que la api de origen que genera la información se encuentra en un servidor que requiere autentificarse.
Hola, tendrías que generar entonces antes el token de autenticación y luego seguir el proceso, en la documentación de tu API debería especificarse cómo realizar esto.
Hola solo quiero pasar esto [{"regular_price":"75,83","sku":"codX1","stock_quantity":300,"sale_price":"81,85"}]
desde mi data de origen y me da error.
➜ Obteniendo datos origen ... ➜ Obteniendo los ids de los productos...
Fatal error: Uncaught Automattic\WooCommerce\HttpClient\HttpClientException: Error: [] in C:\xampp\htdocs\ClientephpWoocomerce\vendor\automattic\woocommerce\src\WooCommerce\HttpClient\HttpClient.php:350 Stack trace: #0 C:\xampp\htdocs\ClientephpWoocomerce\vendor\automattic\woocommerce\src\WooCommerce\HttpClient\HttpClient.php(386): Automattic\WooCommerce\HttpClient\HttpClient->lookForErrors(Object(stdClass)) #1 C:\xampp\htdocs\ClientephpWoocomerce\vendor\automattic\woocommerce\src\WooCommerce\HttpClient\HttpClient.php(422): Automattic\WooCommerce\HttpClient\HttpClient->processResponse() #2 C:\xampp\htdocs\ClientephpWoocomerce\vendor\automattic\woocommerce\src\WooCommerce\Client.php(82): Automattic\WooCommerce\HttpClient\HttpClient->request('products/?sku=c...', 'GET', Array, Array) #3 C:\xampp\htdocs\ClientephpWoocomerce\actualizarWoo.php(50): Automattic\WooCommerce\Client->get('products/?sku=c...') #4 {main} thrown in C:\xampp\htdocs\ClientephpWoocomerce\vendor\automattic\woocommerce\src\WooCommerce\HttpClient\HttpClient.php on line 350
Ya verifique las Url amigables y todo ese tema.
cual podra ser el problema?
gracias excelente vídeo y explicación
Hola, hay un problema en la obtención de los IDs, posiblemente tengas problemas de acceso a la API, revisa este artículo de base, ya que primero tienes que asegurarte de que puedas al menos leer los productos.
Saludos.
Gracias por tu post, me ha sido de muchísima ayuda!!!
Estoy trabajando con una gran cantidad de productos, alrededor de 4000....
Haciendo una modificación a tu código logré obtenerlos desde woocommerce haciendo uso de la paginación.
El problema es que no puedo actualizar los productos con "batch" me da un error 500... ¿Alguna idea? y nuevamente gracias por tu explicación....
Hola, prueba actualizarlos de 100 en 100, ya que al parecer el batch no te aceptará 4000.
Saludos.