DocumentaciónDocumentación
Talk2Sync Documentation
Manual de Usuario
APIs de Conexiones
  • English
  • Español
Talk2Sync Documentation
Manual de Usuario
APIs de Conexiones
  • English
  • Español
  • Portal de Guía de Usuario y Documentación de API
  • User-documentation

    • Manual de Usuario
    • Guide

      • Guía del Usuario: Introducción
      • Conceptos Fundamentales
    • Talk2sync

      • Botones de Conexión
      • Sistema de Códigos de Color
      • Alertas o errores de validación
      • Filtros de comandos
      • La información eliminada todavía aparece: cómo eliminarla
      • Eliminación de datos
    • Conexiones

      • Configuraciones de la conexión
    • Campos

      • Sincronización basada en tiempos
      • Gobierno de datos
      • Campos especiales y adicionales
    • Productos

      • Campos de productos
      • Equivalencias
      • Búsqueda de productos
      • Vincular / Desvincular Productos
    • Ventas

      • Campos
      • Equivalencias de órdenes
      • Búsqueda de órdenes de venta
      • Sin SKU (SKU faltante)
    • Reports

      • Exportación de Productos
      • Reporte de Ventas
    • Faq

      • Amazon

        • Requisitos de Código de Barras en Amazon
        • Discrepancias con el Catálogo de Amazon y Errores de ASIN
        • Requisitos del Fabricante en Amazon
        • Errores de Creación de Nuevos ASIN y Valores de Atributos Inválidos
        • Talk2sync, SKUs e Identificadores de Productos
        • Plantillas de Variación en Amazon
      • Mercadolibre

        • Tiendas Oficiales en Mercado Libre
        • Ubicaciones y Atributos Geográficos en Mercado Libre
        • Recogida en Tienda en Mercado Libre
        • Atributos Adicionales en Mercado Libre
        • Procesamiento de Imágenes y Sincronización en Mercado Libre
        • Error de Vendedor Inhabilitado para Publicar en Mercado Libre
      • Linio

        • Error de Marca No Registrada en Linio
        • Requisitos de Dimensiones Físicas y Peso en Linio
  • APIs para Conexiones

    • APIs de Conexiones
    • Quick-start

      • Introducción y Requisitos
      • Agregar Conexión
      • Configurar Conexión
      • Generar Claves
      • Prueba tu Integración
    • Webhooks

      • API de Webhooks
      • Catalog

        • Webhooks: Listar Productos
        • Webhooks: Listar Producto por ID
        • Webhooks: Agregar/Actualizar Producto
      • Sales

        • Webhooks: Listar Órdenes
        • Listar orden por ID
        • Agregar/Actualizar orden
    • Reverse-connections

      • Reverse Connections
      • Implementation-states

        • Implementación
        • Implementación de consulta: productos y órdenes
        • Implementación de almacenamiento: productos y órdenes
        • Sleep y timeouts
      • Protocol

        • Protocolo
        • Descripción general
        • Carga de productos
        • Carga de órdenes
        • Descarga de productos
        • Descarga de órdenes
      • Rest-calls

        • Llamadas REST
        • Fetching-changes

          • Llamadas REST para obtención de cambios
          • Consultar si está obteniendo cambios
          • Catalog

            • Enviar página de productos
            • Finalizar envíos de productos
          • Sales

            • Enviar página de órdenes
            • Finalizar envíos de órdenes
            • Finalizar todos los envíos
        • Pulling-changes

          • Llamadas REST para descarga de cambios
          • Consultar si está descargando cambios
          • Catalog

            • Obtener el siguiente producto
            • Obtener página de productos
            • Notificar almacenamiento exitoso del producto
            • Notificar error en el almacenamiento del producto
            • Finalizar descarga de productos
          • Sales

            • Obtener la siguiente orden
            • Obtener página de órdenes
            • Notificar almacenamiento exitoso de una orden
            • Notificar error en el almacenamiento de una orden
            • Finalizar descarga de órdenes
            • Finalizar transacción de descarga

Webhooks: Agregar/Actualizar Producto

Descripción General

El webhook Agregar/Actualizar Producto permite que Talk2sync cree nuevos productos o actualice los existentes en tu sistema. Talk2sync envía una solicitud POST con datos completos del producto que tu aplicación debe insertar o actualizar en tu base de datos.

Este endpoint implementa una operación upsert (insertar o actualizar) donde Talk2sync crea un producto nuevo o actualiza uno existente según el ID del producto.

Formato de Solicitud

Solicitud HTTP

POST https://www.example.com/your/endpoint/url?jobid=123&id=999999
T2SKey: {{API_KEY}}
Content-Type: application/json

{
  "_id": "999999",
  "sku": "999999",
  "last_updated": 1517360038797,
  "title": "EON618S JBL SUBWOOFER 18\" AMPLIFICADO",
  "url": "",
  "brand": "",
  "mpn": "",
  "model": "",
  "description": "JBL Premium Transducers",
  "variations": [
    {
      "availabilities": [
        {
          "tag": "default",
          "quantity": 50
        }
      ],
      "prices": [
        {
          "tag": "default",
          "currency": "USD",
          "number": 1060.51
        }
      ],
      "images": [
        {
          "url": "https://www.example.com/13080-thickbox_default/eon618s-jbl-subwoofer-18-amplificado-.jpg"
        }
      ],
      "videos": [
        {
          "url": ""
        }
      ],
      "barcode": "",
      "size": "",
      "color": "",
      "variationid": ""
    }
  ],
  "properties": [
    {
      "extraattributes": {
        "promociones": "",
        "status": "",
        "condicion_venta": "",
        "peso": "",
        "relacionados": "",
        "custom_01": "",
        "custom_02": "1",
        "custom_03": ""
      }
    }
  ]
}

Parámetros de Solicitud

ParámetroTipoDescripciónObligatorio
jobidintegerIdentificador único para este trabajo de sincronización (para seguimiento)✓ Sí
idstringID del producto a insertar/actualizar✓ Sí
T2SKeyheaderTu clave de seguridad✓ Sí

Cuerpo de Solicitud

El cuerpo de la solicitud contiene el objeto de producto completo con todos los detalles. Consulta Listar Productos para una referencia completa de campos.


Respuesta de Éxito

Si el producto se crea o actualiza exitosamente, devuelve una respuesta 200 OK con la siguiente estructura JSON:

{
  "success": true,
  "code": 200,
  "warnings": [],
  "product": {
    "_id": "100004777",
    "sku": "100004777",
    "last_updated": 1517360038797,
    "title": "EON618S JBL SUBWOOFER 18\" AMPLIFICADO",
    "url": "",
    "brand": "",
    "mpn": "",
    "model": "",
    "description": "JBL Premium Transducers",
    "variations": [
      {
        "availabilities": [
          {
            "tag": "default",
            "quantity": 50
          }
        ],
        "prices": [
          {
            "tag": "default",
            "currency": "USD",
            "number": 1060.51
          }
        ],
        "images": [
          {
            "url": "https://www.example.com/13080-thickbox_default/eon618s-jbl-subwoofer-18-amplificado-.jpg"
          }
        ],
        "videos": [
          {
            "url": ""
          }
        ],
        "barcode": "",
        "size": "",
        "variationid": ""
      }
    ],
    "properties": [
      {
        "extraattributes": {
          "promociones": "",
          "status": "",
          "condicion_venta": "",
          "peso": "",
          "relacionados": "",
          "custom_01": "",
          "custom_02": "1",
          "custom_03": ""
        }
      }
    ]
  }
}

Campos de Respuesta de Éxito

CampoTipoDescripción
successbooleanSiempre true para operaciones exitosas
codeintegerCódigo de estado HTTP (p.ej., 200)
warningsarrayArray de mensajes de advertencia (si hay)
productobjectEl objeto de producto creado/actualizado exitosamente

Ejemplo de Advertencias

Puedes incluir advertencias no críticas si ciertos campos fueron ajustados:

{
  "success": true,
  "code": 200,
  "warnings": [
    {
      "msg": "La URL de imagen era inválida y ha sido omitida"
    },
    {
      "msg": "El precio fue ajustado para coincidir con la moneda de tu tienda"
    }
  ],
  "product": { ... }
}

Respuesta de Error

Si la operación falla, devuelve una respuesta de error con información detallada sobre qué salió mal:

{
  "success": false,
  "code": 400,
  "error": "No se pudo crear/actualizar el producto",
  "reasons": [
    {
      "msg": "Precio cero inválido"
    },
    {
      "msg": "Título duplicado inválido"
    },
    {
      "msg": "Imágenes inválidas"
    }
  ],
  "warnings": []
}

Campos de Respuesta de Error

CampoTipoDescripción
successbooleanSiempre false para operaciones fallidas
codeintegerCódigo de estado HTTP (p.ej., 400, 500)
errorstringMensaje de error de alto nivel
reasonsarrayArray de razones de error específicas
warningsarrayCualquier advertencia que ocurrió antes del fallo

Escenarios de Error Comunes

Errores de Validación (400 Bad Request)

{
  "success": false,
  "code": 400,
  "error": "La validación falló",
  "reasons": [
    {
      "msg": "El título es obligatorio"
    },
    {
      "msg": "El precio debe ser mayor a cero"
    }
  ],
  "warnings": []
}

Errores de Base de Datos (500 Internal Server Error)

{
  "success": false,
  "code": 500,
  "error": "La operación de base de datos falló",
  "reasons": [
    {
      "msg": "No se pudo conectar a la base de datos"
    }
  ],
  "warnings": []
}

Error de Autenticación (401 Unauthorized)

{
  "success": false,
  "code": 401,
  "error": "No autorizado",
  "reasons": [
    {
      "msg": "Clave de API inválida o faltante"
    }
  ],
  "warnings": []
}

Ejemplo de Implementación (Node.js/Express)

app.post('/api/products', (req, res) => {
  const { jobid, id } = req.query;
  const apiKey = req.headers['t2skey'];
  const productData = req.body;

  // Validar clave de API
  if (apiKey !== process.env.TALK2SYNC_KEY) {
    return res.status(401).json({
      success: false,
      code: 401,
      error: 'No autorizado',
      reasons: [{ msg: 'Clave de API inválida o faltante' }],
      warnings: []
    });
  }

  try {
    // Validar datos del producto
    const validationErrors = validateProduct(productData);
    if (validationErrors.length > 0) {
      return res.status(400).json({
        success: false,
        code: 400,
        error: 'La validación falló',
        reasons: validationErrors.map(msg => ({ msg })),
        warnings: []
      });
    }

    // Realizar operación upsert
    const savedProduct = upsertProduct(id, productData);

    // Devolver respuesta de éxito
    res.json({
      success: true,
      code: 200,
      warnings: [],
      product: savedProduct
    });

  } catch (error) {
    console.error('Error al crear/actualizar producto:', error);
    res.status(500).json({
      success: false,
      code: 500,
      error: 'La operación de base de datos falló',
      reasons: [{ msg: error.message }],
      warnings: []
    });
  }
});

// Función de validación
function validateProduct(product) {
  const errors = [];

  // Verificar campos obligatorios
  if (!product.title || product.title.trim() === '') {
    errors.push('El título es obligatorio');
  }

  // Validar variaciones
  if (!product.variations || product.variations.length === 0) {
    errors.push('Se requiere al menos una variación');
  }

  // Validar precios
  product.variations?.forEach((variation, idx) => {
    variation.prices?.forEach((price, priceIdx) => {
      if (price.number <= 0) {
        errors.push(`Variación ${idx}: El precio ${priceIdx} debe ser mayor a cero`);
      }
    });
  });

  // Validar imágenes
  product.variations?.forEach((variation, idx) => {
    variation.images?.forEach((image, imgIdx) => {
      if (!isValidUrl(image.url)) {
        errors.push(`Variación ${idx}: La imagen ${imgIdx} tiene URL inválida`);
      }
    });
  });

  return errors;
}

function isValidUrl(string) {
  try {
    new URL(string);
    return true;
  } catch (_) {
    return false;
  }
}

// Función upsert
function upsertProduct(id, productData) {
  // Verificar si el producto existe
  const existingProduct = findProductById(id);

  if (existingProduct) {
    // Actualizar producto existente
    return updateProductInDatabase(id, productData);
  } else {
    // Insertar nuevo producto
    return insertProductInDatabase(productData);
  }
}

Códigos de Estado de Respuesta

EstadoSignificadoRespuestaAcción
200 OKProducto creado/actualizado exitosamenteRespuesta de éxito con productoTalk2sync registra la operación
400 Bad RequestError de validación en datos del productoRespuesta de error con razonesVerifica los errores de validación
401 UnauthorizedClave de API inválida o faltanteRespuesta de errorVerifica tu clave de seguridad
409 ConflictEl producto entra en conflicto con datos existentesRespuesta de error con razonesResuelve el conflicto
500 Internal Server ErrorError del servidorRespuesta de error con mensaje de errorRevisa los registros de tu servidor

Buenas Prácticas

✓ Haz:

  • Valida todos los campos obligatorios antes de inserción/actualización
  • Devuelve mensajes de error específicos en el array reasons
  • Incluye advertencias para problemas no críticos
  • Siempre valida la clave de API
  • Usa transacciones para operaciones de base de datos (si es compatible)
  • Actualiza el timestamp de last_updated a la hora actual
  • Registra todas las operaciones para depuración

✗ No hagas:

  • Aceptes datos de producto parciales (requiere objetos completos)
  • Omitas campos inválidos sin notificar
  • Devuelvas mensajes de error vagos
  • Modifiques datos que no fueron enviados por Talk2sync
  • Actualices productos que no pertenecen a la cuenta/tienda actual
  • Ignores errores de validación

Lógica de Upsert

La operación upsert debe funcionar de la siguiente manera:

SI el producto con ID existe en la base de datos
  ENTONCES actualiza todos los campos con datos nuevos
EN CASO CONTRARIO
  CREA un nuevo producto con datos proporcionados
FIN

Crear vs Actualizar

OperaciónCuándoAcción
CREATE (INSERT)El ID del producto no existeInsertar un nuevo registro de producto
UPDATEEl ID del producto ya existeReemplaza todos los campos con datos nuevos

Consistencia de Datos

  • Timestamps: Siempre usa el timestamp de last_updated de Talk2sync (no generes uno nuevo)
  • ID de Producto: El _id y el parámetro id deben coincidir
  • SKU: Almacena el SKU para referencia; debería coincidir con _id en la mayoría de casos
  • Relaciones: Borra cualquier variación/propiedad anterior antes de actualizar

Idempotencia

Esta operación es idempotente, lo que significa que llamarla múltiples veces con los mismos datos debe producir el mismo resultado:

  • Primera llamada: Crea/actualiza el producto
  • Segunda llamada (mismos datos): Devuelve la misma respuesta de éxito
  • Tercera llamada (mismos datos): Devuelve la misma respuesta de éxito

Esto asegura que si Talk2sync reintenta la operación, no se creen productos duplicados.


Límites de Tamaño de Solicitud/Respuesta

  • Tamaño máximo de solicitud: 10 MB por producto
  • La respuesta debe mantenerse bajo 5 MB
  • Procesa solicitudes dentro de 1 minuto de timeout

Webhooks Relacionados

  • Listar Productos
  • Listar Producto por ID

Documentación Relacionada

  • Quick Start: Generar Claves
  • Descripción General de Webhooks
Actualizado el: 28/08/26, 12:58 a.m.
Prev
Webhooks: Listar Producto por ID