Skip to main content

Overview

The Tandex Electronics API integrates with WooCommerce to automatically publish products from your internal catalog to your WooCommerce store. This integration uses the official WooCommerce REST API client.

WooCommerce API Configuration

The WooCommerce REST API is configured in the application using consumer keys and secrets:
cliente.js
const WooCommerceRestApi = require("@woocommerce/woocommerce-rest-api").default;

// Configuration of the WooCommerce API
const WooCommerce = new WooCommerceRestApi({
    url: 'https://hometoys.com.mx/pruebas2021/', // Your store URL
    consumerKey: 'ck_fc785525dec737adb8050dcd4a72d0b162066630', // Your consumer key
    consumerSecret: 'cs_bf9e30331b1d3031dbd90e82670839b060804b3e', // Your consumer secret
    version: 'wc/v3' // WooCommerce WP REST API version
});
The example above contains demo credentials. Replace these with your actual WooCommerce API keys before deploying to production.

Setting Up Consumer Keys

1

Access WooCommerce Settings

Log in to your WordPress admin panel and navigate to:WooCommerce → Settings → Advanced → REST API
2

Create API Keys

  1. Click “Add key”
  2. Enter a description (e.g., “Tandex API Integration”)
  3. Select the user for the API
  4. Set permissions to Read/Write
  5. Click “Generate API key”
3

Copy Credentials

Save both the Consumer Key and Consumer Secret immediately. You won’t be able to view the secret again.
The Consumer Key starts with ck_ and the Consumer Secret starts with cs_
4

Update Configuration

Update your application code with the new credentials in routes/setup/servicios/cliente.js:
const WooCommerce = new WooCommerceRestApi({
    url: 'https://your-store-url.com/',
    consumerKey: 'your_consumer_key',
    consumerSecret: 'your_consumer_secret',
    version: 'wc/v3'
});

Product Publishing Workflow

The uploadProducts function handles the complete workflow of publishing products to WooCommerce:
cliente.js
function uploadProducts(req, res){
    const datos = req.body
    const user = req.headers.user

    if(datos.length === 0){
        res.status(401).json({
            error:'Productos no seleccionados',
            message:'Reintente seleccionar archivos'
        })
    }
    else{
        for(let i = 0; i < datos.length; i++){
            const data = {
                name: datos[i].descripcionP,
                type: datos[i].typeWOO,
                description: datos[i].descriptionWoo,
                short_description: "<p>CARACTERÍSTICAS</p>\n<ul>\n<li>"+datos[i].shortDescriptionWOO+"</li>\n</ul>\n",
                regular_price: datos[i].precio.toString(),
                categories: [
                    {
                        "id": 123,
                        "name": datos[i].categoryWOO,
                        "slug": "desconocido"
                    }
                ],
                images: [
                    {
                        src: "http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_4_front.jpg"
                    },
                    {
                        src: "http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_4_back.jpg"
                    },
                    {
                        src: "http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_3_front.jpg"
                    },
                    {
                        src: "http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_3_back.jpg"
                    }
                ],
            };
        
            // Request to upload to WooCommerce
            WooCommerce.post("products", data)
            .then(response => {
                controlProducto(user, datos[i].claveProducto)
            })
            .catch(error => {
                res.status(400).json({msg: error})
            })  
        } 
        bitacora(user, datos)
        res.status(200).json({'msg':'Productos subidos correctamente'})
    }  
}

Workflow Steps

  1. Validation: Checks if products are selected
  2. Data Mapping: Transforms internal product data to WooCommerce format
  3. API Request: Posts product to WooCommerce using REST API
  4. Tracking: Records published product in productos_publicados table
  5. Logging: Creates audit log entry in bitacora table

Product Data Mapping

The product data structure sent to WooCommerce:
const data = {
    name: datos[i].descripcionP,                    // Product name
    type: datos[i].typeWOO,                         // Product type (simple, variable, etc.)
    description: datos[i].descriptionWoo,           // Full product description
    short_description: "<p>CARACTERÍSTICAS</p>\n<ul>\n<li>"+datos[i].shortDescriptionWOO+"</li>\n</ul>\n",
    regular_price: datos[i].precio.toString(),      // Price as string
    categories: [
        {
            "id": 123,
            "name": datos[i].categoryWOO,
            "slug": "desconocido"
        }
    ],
    images: [
        {
            src: "http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_4_front.jpg"
        }
        // Additional images...
    ],
};

Field Mapping

Mapped from descripcionP field in the internal database. This becomes the main product title in WooCommerce.
Specifies the WooCommerce product type. Common values:
  • simple - Standard product
  • variable - Product with variations
  • grouped - Collection of products
  • external - External/affiliate product
  • description: Full HTML description displayed on product page
  • short_description: Brief description shown on product listings
The short description is formatted with HTML for features list.
Must be sent as a string. Automatically converted from the numeric precio field.
WooCommerce expects price as string to handle decimal precision correctly.
Products are assigned to categories using category ID and name. The slug is currently set to “desconocido” (unknown).
Update the category ID (123) to match your actual WooCommerce category IDs.
Array of image objects with src URLs. Currently uses placeholder images.
Replace demo image URLs with actual product images from your image server.

Product Tracking

After successful publication, products are tracked in the database:
function controlProducto(user, datos){
    dbconn.query('SELECT * FROM heroku_1a378f873641606.usuarios where correo=?', [user])
    .then(rows => {
        dbconn.query(
            'INSERT INTO `heroku_1a378f873641606`.`productos_publicados` (`claveProductoP`,`woocomerce`,`idUsuarioPP`) VALUES(?,?,?)',
            [datos, "WOO", rows[0].id]
        )
    })
}
This creates a record with:
  • Product key (claveProductoP)
  • Platform identifier (woocomerce = “WOO”)
  • User who published (idUsuarioPP)

Activity Logging

All publication activities are logged to the audit trail:
function bitacora(user, datos){
    let cantidad = datos.length
    let date = new Date();
    let fecha = date.getFullYear() + '-' + date.getMonth() + '-' + date.getDay()
    
    dbconn.query('SELECT * FROM heroku_1a378f873641606.usuarios where correo=?', [user])
    .then(rows => {
        dbconn.query(
            'INSERT INTO `heroku_1a378f873641606`.`bitacora` (`idUsuarioB`,`fecha`,`modificacion`,`cantidad`) VALUES(?,?,?,?)',
            [rows[0].id, fecha, 'Publicación de productos', cantidad]
        )
    })
}

Error Handling

The integration includes error handling for API failures:
WooCommerce.post("products", data)
.then(response => {
    controlProducto(user, datos[i].claveProducto)
})
.catch(error => {
    res.status(400).json({msg: error})
})

Common Errors

Cause: Invalid consumer key or secretSolution: Verify your WooCommerce API credentials are correct and have Read/Write permissions.
Cause: Invalid product data formatSolution:
  • Ensure regular_price is a string
  • Verify category IDs exist in WooCommerce
  • Check all required fields are present
Cause: Incorrect API endpoint URLSolution: Verify the store URL is correct and includes the trailing slash.
Cause: SSL certificate issues with the WooCommerce storeSolution: Ensure your store has a valid SSL certificate. For development, you may need to configure SSL verification.

Testing the Integration

1

Prepare test product data

Create a test product in your database with all required WooCommerce fields:
INSERT INTO productossae 
(claveProducto, descripcionP, precio, typeWOO, shortDescriptionWOO, descriptionWoo, categoryWOO)
VALUES 
('TEST001', 'Test Product', 99.99, 'simple', 'Test features', 'Full test description', 'Electronics');
2

Make API request

Send a POST request to the upload products endpoint:
curl -X POST http://localhost:8080/api/products/upload \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "user: your-email@example.com" \
  -d '[{
    "claveProducto": "TEST001",
    "descripcionP": "Test Product",
    "precio": 99.99,
    "typeWOO": "simple",
    "shortDescriptionWOO": "Test features",
    "descriptionWoo": "Full test description",
    "categoryWOO": "Electronics"
  }]'
3

Verify in WooCommerce

  1. Log in to your WordPress admin
  2. Navigate to Products → All Products
  3. Look for your test product
  4. Verify all fields were populated correctly
4

Check tracking tables

Verify the product was logged in the database:
SELECT * FROM productos_publicados WHERE claveProductoP = 'TEST001';
SELECT * FROM bitacora ORDER BY idBitacora DESC LIMIT 1;

Best Practices

  • Batch Publishing: Publish products in reasonable batch sizes (50-100 at a time)
  • Image Management: Store product images on a CDN and reference their URLs
  • Category Mapping: Maintain a mapping table between internal categories and WooCommerce category IDs
  • Error Logging: Implement comprehensive error logging for failed publications
  • Rate Limiting: Be mindful of WooCommerce API rate limits (typically 60 requests per minute)
  • Data Validation: Validate product data before sending to WooCommerce

API Version

The integration uses WooCommerce REST API v3 (wc/v3), which is compatible with:
  • WooCommerce 3.5+
  • WordPress 4.4+
Always keep your WooCommerce and WordPress installations up to date for security and compatibility.

Next Steps

Build docs developers (and LLMs) love