API de Integraciones de Terceros
Introducción
La API de Integraciones de Terceros de NinoxNet permite que aplicaciones externas se conecten de forma segura a nuestra plataforma mediante comunicación en la nube. Esta integración habilita el acceso al inventario web y la gestión de órdenes de venta.
Capacidades principales
- 🏪 Consulta de stock en tiempo real - Acceso completo al inventario web
- 📦 Gestión de órdenes - Creación de preventas y pedidos de venta
- 🔄 Sincronización automática - Actualización continua de datos
- 📊 Curvas de stock - Consulta detallada por variantes (talles/colores)
Configuración inicial
1. Solicitar integración
Contacta con nuestro equipo de ventas para iniciar el proceso de habilitación de tu integración.
2. Obtener credenciales
Una vez aprobada la integración, recibirás un token de autenticación único para tu aplicación:
Ejemplo: 14ed5133cbc8a215355c805c59c9805db7492753
Mantén tu token seguro y nunca lo expongas en código cliente. Úsalo únicamente en comunicaciones servidor-a-servidor.
Autenticación
Todas las requests deben incluir el token en el header de autorización:
- HTTP Headers
- cURL
X-NX-TOKEN: 14ed5133cbc8a215355c805c59c9805db7492753
Content-Type: application/json
curl -H "X-NX-TOKEN: tu_token_aqui" \
-H "Content-Type: application/json" \
https://api.ninox.com.ar/integraciones/Terceros/GetData
Todos los ejemplos de código están definidos en TypeScript para mayor claridad en los tipos de datos.
Endpoints disponibles
📊 Consulta de inventario
Los endpoints de consulta de datos tienen un límite de 10 minutos entre consultas consecutivas. Si realizas una nueva consulta antes de que transcurra este tiempo, el sistema responderá con error 403 Forbidden
.
Obtener stock básico
Retorna la lista completa de artículos con información básica de stock.
https://api.ninox.com.ar/integraciones/Terceros/GetData
Response:
Articulo[]
Limitaciones:
- ⏱️ Intervalo mínimo entre consultas: 10 minutos
- ❌ Error si se consulta antes:
403 Forbidden
Obtener stock con curvas
Retorna artículos con información detallada de variantes (talles/colores) en formato plano para facilitar el procesamiento.
https://api.ninox.com.ar/integraciones/Terceros/GetDataCurva
Response:
ArticuloConCurva[]
Limitaciones:
- ⏱️ Intervalo mínimo entre consultas: 10 minutos
- ❌ Error si se consulta antes:
403 Forbidden
� Webhooks
NinoxNet puede enviar notificaciones automáticas a tu aplicación cuando ocurren cambios en los datos, eliminando la necesidad de consultas periódicas.
- Cambios en artículos: Notificaciones cuando se actualizan propiedades, stock o precios
- Artículos desactivados: Notificación cuando un artículo se desactiva de la integración
Para más información, consulta la documentación de webhooks.
Crear pedido
Crea un nuevo pedido en el sistema. Según la configuración de tu integración, esto generará un Pedido de venta o una Preventa que reserva stock.
https://api.ninox.com.ar/integraciones/Terceros/Pedido
Request body:
PedidoTerceros
Response:
PedidoResultado
El sistema validará que el total
del pedido sea igual a: subtotal + envio + recargo - descuento
Cancelar pedido
Cancela un pedido existente utilizando su ID de factura.
https://api.ninox.com.ar/integraciones/Terceros/Pedido/cancelar
Query parameters:
facturaid
(number): ID de la factura a cancelar
Response:
NxResultado
Esquemas de datos
🏷️ Modelos de artículos
Los artículos en Ninox pueden tener diferentes tipos de variantes según su configuración:
TipoTalleColor
export enum TipoTalleColor {
NINGUNO = 0, // Artículo sin variantes
TALLES = 1, // Solo variantes de talle
COLORES = 2, // Solo variantes de color
TALLES_COLORES = 3 // Variantes de talle y color
}
Articulo (Estructura compleja)
Modelo principal con arrays anidados para variantes y etiquetas:
export interface Articulo {
articuloId: number;
codigo: string;
descripcion: string;
descripcionWeb: string;
nombre: string; // Generado automáticamente según código y descripción
talleColor: TipoTalleColor;
// Precios por nivel
precio1: number;
precio2: number;
precio3: number;
precio4: number;
precio5: number;
stockTotal: number;
// Arrays relacionados
curva: ArticuloCurva[];
tags: ArticuloTag[];
}
ArticuloCurva
Representa las variantes de stock por talle/color:
export interface ArticuloCurva {
articuloId: number;
colorId?: number;
talleId?: number;
colorNombre: string;
colorCodigo: string;
talleNombre: string;
talleCodigo: string;
unidades: number; // Stock disponible para esta variante
}
ArticuloConCurva (Estructura plana)
Modelo optimizado donde cada variante es un registro independiente, ideal para procesamiento masivo:
export interface ArticuloConCurva {
// Información básica del artículo
articuloId: number;
codigo: string;
descripcion: string;
descripcionWeb: string;
nombre: string;
talleColor: TipoTalleColor;
// Precios
precio1: number;
precio2: number;
precio3: number;
precio4: number;
precio5: number;
// Información de variante específica
colorId?: number;
talleId?: number;
colorNombre: string;
colorCodigo: string;
colorHex: string; // Código hexadecimal del color
talleNombre: string;
talleCodigo: string;
// Stock y clasificaciones
unidades: number;
etiquetasIds: string; // IDs separados por coma
etiquetasNombres: string; // Nombres separados por coma
categoriasIds: string; // IDs separados por coma
categoriasNombres: string; // Nombres separados por coma
// Estado del artículo
eliminado: boolean; // Indica si el artículo fue desactivado de la integración
}
🏪 Sistema de etiquetas y categorías
TipoTag
export enum TipoTag {
TODAS = -1,
TAG = 0, // Etiqueta libre
CATEGORIA, // Categoría de producto
MARCA, // Marca del producto
TEMPORADA // Temporada/colección
}
ArticuloTag
export interface ArticuloTag {
articuloId: number;
articuloTagId: number;
tipo: TipoTag;
tagId: number;
tagNombre: string;
padreId?: number; // Para categorías jerárquicas
destacada: boolean; // Si es una etiqueta destacada
}
En Ninox, tanto las etiquetas como las categorías se manejan mediante el sistema de Tags
, diferenciándose por el campo tipo
.
🛒 Modelos de pedidos
CondicionIva
Condiciones fiscales según AFIP:
enum CondicionIva {
SIN_CATEGORIA = 0,
CONSUMIDOR_FINAL = 1,
RESPONSABLE_INSCRIPTO = 2,
MONOTRIBUTO = 3,
EXENTO = 4,
RESPONSABLE_NO_INSCRIPTO = 5,
}
PedidoTerceros
Estructura principal para crear un pedido:
export interface PedidoTerceros {
ordenId: number; // ID único de tu sistema
numero: number; // Número de orden
detalle: string; // Descripción del pedido
// Direcciones
direccionEnvio: DireccionTerceros;
direccionFacturacion: DireccionTerceros;
// Productos y usuario
productos: ArticuloTerceros[];
usuario: UsuarioTerceros;
// Cálculos financieros
subtotal: number;
descuento: number;
envio: number;
recargo: number;
total: number; // Debe ser: subtotal + envio + recargo - descuento
}
DireccionTerceros
export interface DireccionTerceros {
provincia: string;
localidad: string;
direccion: string;
codigoPostal: string;
}
UsuarioTerceros
Información del cliente que realiza el pedido:
export interface UsuarioTerceros {
nombre: string;
email: string;
dni: string; // Documento Nacional de Identidad
cuit: string; // CUIT/CUIL (opcional según condición)
telefono: string;
condicion: CondicionIva;
}
ArticuloTerceros
Items del pedido:
export interface ArticuloTerceros {
articuloId: number;
precio: number; // Precio unitario
talleId?: number; // ID del talle (opcional)
colorId?: number; // ID del color (opcional)
cantidad: number; // Cantidad solicitada
}
Dependiendo de la configuración de tu integración, un PedidoTerceros
puede resultar en:
- Pedido de venta: Venta inmediata con facturación
- Preventa: Reserva de stock sin facturar
📋 Modelos de respuesta
PedidoResultado
Respuesta al crear un pedido exitosamente:
export interface PedidoResultado {
facturaId: number; // Si es 0, el pedido no se realizó
numero: number; // Número de factura generada
pVNumero: number; // Número de preventa (si aplica)
sref: string; // Referencia del sistema
estado: number; // Estado actual del pedido
// Metadatos adicionales
datos: { [key: string]: string };
// Facturación electrónica
electronica: boolean;
cae: string; // Código de Autorización Electrónico
caevencimiento: string; // Fecha de vencimiento del CAE
resultado: string; // Resultado de la operación
observaciones: string; // Observaciones adicionales
errorFE: string; // Error de facturación electrónica (si hay)
saldo?: number; // Saldo pendiente (opcional)
errores: boolean; // Indica si hubo errores
}
NxResultado
Respuesta estándar del sistema para operaciones generales:
export enum NxTipoResultado {
ERROR = 0, // Operación fallida
OK = 1, // Operación exitosa
VALIDACION = 2 // Error de validación
}
export class NxResultado {
tipo: NxTipoResultado;
id: number; // ID relacionado a la operación
data: object; // Datos adicionales de respuesta
valores: string[]; // Valores retornados
mensajes: string[]; // Mensajes informativos
errores: string[]; // Lista de errores (si los hay)
}
Códigos de error comunes
Código | Descripción | Solución |
---|---|---|
401 | Token inválido o expirado | Verificar el token en el header X-NX-TOKEN |
403 | Consulta muy frecuente | Esperar al menos 10 minutos entre consultas de datos |
400 | Datos de request inválidos | Revisar el formato del payload según los esquemas |
422 | Error de validación | Verificar que el total del pedido sea correcto |
404 | Recurso no encontrado | Verificar que el articuloId o facturaId exista |
500 | Error interno del servidor | Contactar soporte técnico |
Ejemplo de integración
- JavaScript/Node.js
- Python
const axios = require('axios');
const ninoxApi = axios.create({
baseURL: 'https://api.ninox.com.ar/integraciones/Terceros',
headers: {
'X-NX-TOKEN': 'tu_token_aqui',
'Content-Type': 'application/json'
}
});
// Obtener stock
async function obtenerStock() {
try {
const response = await ninoxApi.get('/GetData');
return response.data;
} catch (error) {
if (error.response?.status === 403) {
console.error('Error: Consultas muy frecuentes. Esperar 10 minutos entre consultas.');
throw new Error('Rate limit exceeded. Wait 10 minutes between queries.');
}
console.error('Error al obtener stock:', error.response?.data);
throw error;
}
}
// Crear pedido
async function crearPedido(pedido) {
try {
const response = await ninoxApi.post('/Pedido', pedido);
return response.data;
} catch (error) {
console.error('Error al crear pedido:', error.response?.data);
throw error;
}
}
import requests
import json
class NinoxAPI:
def __init__(self, token):
self.base_url = 'https://api.ninox.com.ar/integraciones/Terceros'
self.headers = {
'X-NX-TOKEN': token,
'Content-Type': 'application/json'
}
def obtener_stock(self):
"""Obtiene el stock disponible"""
try:
response = requests.get(f'{self.base_url}/GetData', headers=self.headers)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
if response.status_code == 403:
raise Exception("Consultas muy frecuentes. Esperar 10 minutos entre consultas.")
raise e
def crear_pedido(self, pedido):
"""Crea un nuevo pedido"""
response = requests.post(
f'{self.base_url}/Pedido',
headers=self.headers,
json=pedido
)
response.raise_for_status()
return response.json()
# Uso
api = NinoxAPI('tu_token_aqui')
stock = api.obtener_stock()
¿Necesitas ayuda con la integración? Contacta a nuestro equipo de soporte técnico.