Vender a través de Tiendanube es una de las decisiones comerciales más frecuentes para marcas y empresas en América Latina. Cuando una tienda procesa 15 pedidos por día, la carga manual es tolerable: un operador entra a la web de ARCA (ex-AFIP), copia el nombre del cliente, el DNI, los productos, genera el comprobante, descarga el PDF, lo adjunta a mano en un correo y luego descuenta el stock en una planilla de Excel o en el sistema de gestión del local.
Sin embargo, cuando el volumen escala a 100, 500 o 2.000 pedidos diarios durante eventos como el CyberMonday o el Hot Sale, ese esquema artesanal colapsa de forma estrepitosa:
- Desfasaje administrativo: Demoras de 48 a 72 horas para emitir facturas legales.
- Quiebres de stock (over-selling): El local a la calle vende la última unidad de un producto mientras un comprador online la adquiere al mismo segundo en Tiendanube.
- Rechazos fiscales: Datos de facturación mal tipeados por el usuario en el checkout que bloquean la contabilidad mensual.
La solución definitiva consiste en construir un conector desacoplado basado en Webhooks que enlace Tiendanube, el Web Service de ARCA y el ERP o sistema de inventario en tiempo real. A continuación detallamos la arquitectura técnica, los eventos de la API, el manejo de cancelaciones y por qué un conector a medida supera a las aplicaciones genéricas enlatadas.
El flujo de datos automatizado de punta a punta
Para lograr una operación sin fricción humana, el conector debe actuar como un orquestador transaccional entre los tres sistemas:
[ Comprador en Tiendanube ]
│
│ 1. Paga su orden con Mercado Pago / Ualá / Tarjeta
▼
[ Tiendanube API ]
│
│ 2. Dispara Webhook: order/paid (Firma HMAC SHA-256)
▼
[ Tu Conector Backend / API Gateway ]
│
├── 3. Valida firma criptográfica y encola en Redis (BullMQ)
│
├── 4. Normaliza datos fiscales:
│ - Valida CUIT/DNI con algoritmo Módulo 11
│ - Consulta condición IVA en ARCA (¿RI o Consumidor Final?)
│
├── 5. Emite Factura Electrónica en ARCA (WSFE):
│ - Solicita CAE, número de comprobante y vencimiento
│
├── 6. Genera PDF oficial con QR reglamentario
│
├── 7. Envío omnicanal:
│ - Adjunta factura a la orden en Tiendanube
│ - Envía PDF por WhatsApp Business Cloud API / Email
│
└── 8. Descuenta Stock en ERP Central:
- Actualiza inventario físico
- Si queda en 0, actualiza variantes en Tiendanube
Paso 1: Configuración del Webhook en Tiendanube (order/paid)
La API de Tiendanube permite registrar Webhooks para ser notificado de forma inmediata ante cambios de estado en las órdenes.
¿Por qué order/paid y no order/created?
Si configurás el webhook en order/created, el sistema intentará facturar órdenes que el cliente todavía no pagó (por ejemplo, pagos en efectivo mediante Rapipago o Pago Fácil que nunca se abonan, o tarjetas rechazadas por fondos insuficientes). La regla de oro contable es facturar exclusivamente ante confirmación de fondos.
Validación de seguridad con firma HMAC SHA-256
Cualquiera puede enviar una petición POST a la URL de tu servidor haciéndose pasar por Tiendanube. Para garantizar la autenticidad, Tiendanube envía el encabezado HTTP X-LinkedStore-HMAC-SHA256, que contiene el hash del payload firmado con el client_secret de tu aplicación.
Código en Node.js (Express / TypeScript) para validar el Webhook:
import express, { Request, Response } from "express";
import crypto from "crypto";
import { Queue } from "bullmq";
const app = express();
// Guardar el buffer crudo para la verificación criptográfica
app.use(express.json({
verify: (req: any, res, buf) => {
req.rawBody = buf;
}
}));
const orderQueue = new Queue("tiendanube-orders", {
connection: { host: "127.0.0.1", port: 6379 }
});
const TIENDANUBE_CLIENT_SECRET = process.env.TIENDANUBE_CLIENT_SECRET || "tu_client_secret";
app.post("/webhooks/tiendanube/order-paid", async (req: any, res: Response) => {
const hmacHeader = req.headers["x-linkedstore-hmac-sha256"] as string;
if (!hmacHeader) {
return res.status(401).send("Encabezado de firma ausente");
}
// 1. Calcular el HMAC SHA-256 localmente
const generatedHmac = crypto
.createHmac("sha256", TIENDANUBE_CLIENT_SECRET)
.update(req.rawBody)
.digest("hex");
// 2. Comparación en tiempo constante para evitar ataques de temporización
const isValid = crypto.timingSafeEqual(
Buffer.from(generatedHmac, "utf8"),
Buffer.from(hmacHeader, "utf8")
);
if (!isValid) {
return res.status(403).send("Firma HMAC inválida");
}
// 3. Responder 200 OK de inmediato a Tiendanube
res.status(200).send("OK");
const orderData = req.body;
// 4. Encolar la orden para procesamiento fiscal y de stock asíncrono
await orderQueue.add("process-order", {
orderId: orderData.id,
storeId: orderData.store_id,
customer: orderData.customer,
products: orderData.products,
total: orderData.total,
shippingCost: orderData.shipping_cost_customer,
billingAddress: orderData.billing_address
});
});
Paso 2: Normalización tributaria y resolución de Factura A vs Factura B
En el checkout de una tienda online, los usuarios suelen ingresar datos con inconsistencias: CUITs con guiones, espacios, DNI cargado en el campo de CUIT o nombres de fantasía.
El worker encargado de procesar la orden debe seguir este algoritmo:
export interface FiscalRecipient {
docTipo: number; // 80: CUIT, 96: DNI, 99: Sin identificar
docNro: number;
cbteTipo: number; // 1: Factura A, 6: Factura B
}
export function resolveFiscalCondition(customer: any, billingAddress: any, orderTotal: number): FiscalRecipient {
const rawDoc = (billingAddress?.id_number || customer?.identification || "").replace(/\D/g, "");
// Si tiene 11 dígitos y pasa la validación de Módulo 11 de CUIT argentino
if (rawDoc.length === 11 && isValidCuit(rawDoc)) {
// Si la empresa emisora es Responsable Inscripto y el cliente es RI -> Factura A
return {
docTipo: 80, // CUIT
docNro: Number(rawDoc),
cbteTipo: 1 // Factura A
};
}
// Si tiene 7 u 8 dígitos, es un DNI (Consumidor Final) -> Factura B
if (rawDoc.length >= 7 && rawDoc.length <= 8) {
return {
docTipo: 96, // DNI
docNro: Number(rawDoc),
cbteTipo: 6 // Factura B
};
}
// Si no cargó documento y el monto supera el límite de comprobantes anónimos de ARCA
const LIMITE_ANONIMO_ARCA = 300000; // Ajustable por resolución de ARCA
if (orderTotal >= LIMITE_ANONIMO_ARCA) {
throw new Error(`La orden supera los $${LIMITE_ANONIMO_ARCA} y requiere DNI/CUIT obligatorio para emitir CAE`);
}
// Consumidor Final sin identificar
return {
docTipo: 99,
docNro: 0,
cbteTipo: 6
};
}
// Algoritmo de validación de CUIT por Módulo 11
function isValidCuit(cuit: string): boolean {
const digits = cuit.split("").map(Number);
const multipliers = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
const sum = multipliers.reduce((acc, mult, i) => acc + mult * digits[i], 0);
const mod = sum % 11;
const verifier = mod === 0 ? 0 : mod === 1 ? 9 : 11 - mod;
return verifier === digits[10];
}
Paso 3: Sincronización bidireccional de stock con el ERP
El talón de Aquiles de la omnicanalidad es vender dos veces el mismo producto. La arquitectura debe operar con inventario centralizado:
Cuando se vende en Tiendanube:
- Al procesarse el job
process-order, el backend ejecuta una transacción SQL en el ERP que descuenta el stock de las variantes correspondientes:UPDATE stock_productos SET cantidad = cantidad - $1 WHERE sku = $2 AND deposito_id = $3 AND cantidad >= $1; - Si la actualización no afecta filas, significa que no había stock físico real: el conector lanza una alerta urgente y detiene la facturación para revisión comercial.
- Al procesarse el job
Cuando se vende en el local físico:
- El punto de venta (POS) del local descuenta stock en la base de datos central.
- Un trigger o evento de cambio invoca a la API de Tiendanube para sincronizar el stock disponible en la web:
import axios from "axios";
export async function updateTiendanubeStock(storeId: string, accessToken: string, productId: number, variantId: number, newStock: number) {
const url = `https://api.tiendanube.com/v1/${storeId}/products/${productId}/variants/${variantId}`;
await axios.put(
url,
{ stock: newStock },
{
headers: {
Authentication: `bearer ${accessToken}`,
"User-Agent": "MiEmpresaConector (contacto@miempresa.com)",
"Content-Type": "application/json"
}
}
);
}
Paso 4: Cancelaciones y Notas de Crédito automáticas
¿Qué ocurre si un cliente pide la cancelación de la compra o el pago fue revertido?
En un circuito manual, el operador suele devolver el dinero en la pasarela de pagos pero olvida emitir la Nota de Crédito en ARCA, provocando que la empresa tribute IVA e Ingresos Brutos sobre una venta inexistente.
El conector debe escuchar el evento order/cancelled de Tiendanube:
- Busca la orden en la base de datos interna.
- Si la orden posee un comprobante con CAE:
- Determina el tipo de comprobante de ajuste (si fue Factura B código 6, emite Nota de Crédito B código 8; si fue Factura A código 1, emite Nota de Crédito A código 3).
- Asocia el número de comprobante original y punto de venta en el array
CbtesAsocde ARCA. - Obtiene el CAE de la Nota de Crédito.
- Repone automáticamente las unidades físicas al stock del ERP en el depósito de devoluciones.
Por qué un conector a medida supera a los plugins genéricos
En la tienda de aplicaciones de Tiendanube existen plugins empaquetados que ofrecen facturación automática. Aunque pueden ser útiles para proyectos iniciales de bajo volumen, las empresas consolidadas rápidamente se topan con sus limitaciones estructurales:
| Requerimiento | Plugin Estándar / SaaS Enlatado | Conector a Medida (Deepyze) |
|---|---|---|
| Costo por factura | Comisiones variables o planes que suben con el volumen de ventas | Cero comisiones: infraestructura propia sin costo por transacción |
| Kits y Combos desarmables | Vende un "Combo 3 remeras" y no sabe qué descontar del inventario | Desglosa la receta del combo y descuenta cada SKU individual en el ERP |
| Múltiples depósitos | Descuenta de un único inventario genérico | Reglas avanzadas: despacho por cercanía geográfica o prioridad de sucursal |
| Percepciones de Ingresos Brutos | Rara vez calcula padrones locales (ARBA, AGIP, Rentas Córdoba) | Liquidación exacta según alícuotas del padrón fiscal provincial vigente |
| Envío omnicanal de comprobantes | Solo email básico de la tienda | Envío de PDF con QR por WhatsApp Business oficial y notificación al CRM |
Automatizá la operación de tu e-commerce con Deepyze
Operar un e-commerce exitoso implica que tus sistemas trabajen para vos, no que tu equipo humano pase las tardes tipeando facturas o respondiendo quejas por productos vendidos sin stock.
En Deepyze construimos puentes tecnológicos de alto rendimiento entre tiendas de comercio electrónico, sistemas tributarios y software de gestión:
- Desarrollamos conectores de alto volumen y APIs a medida con garantía de sincronización y conciliación total.
- Integramos tu facturación con ARCA mediante arquitecturas resilientes con colas de procesamiento en Redis y monitoreo continuo.
- Diseñamos paneles de control e inventario centralizado mediante desarrollo de software a medida.
- Potenciamos tu postventa mediante automatización con IA y agentes de WhatsApp corporativos.
Liberá el cuello de botella de tu negocio digital. Agendá una llamada técnica de 30 minutos con nuestro equipo para evaluar tu infraestructura o solicitá un presupuesto de desarrollo a medida.
Preguntas frecuentes
¿Qué evento de webhook de Tiendanube es el indicado para disparar la facturación automática con ARCA?+
El evento indicado es `order/paid` (orden pagada), no `order/created`. Una orden creada puede quedar pendiente de pago si el cliente eligió transferencia bancaria o cupones en efectivo (Pago Fácil/Rapipago) y finalmente abandonó la compra. Facturar en `order/paid` garantiza que solo se emita el comprobante fiscal y el CAE ante fondos confirmados por la pasarela de pagos.
¿Cómo se maneja la condición fiscal del comprador si no cargó su CUIT en el checkout de Tiendanube?+
Si el cliente no completó su CUIT/CUIL, el sistema lo clasifica como Consumidor Final emitiendo una Factura B (o Factura C si el emisor es Monotributista) con código de documento 99 (Sin Identificar) si el monto es inferior al tope legal de facturación anónima fijado por ARCA, o exigiendo DNI si supera dicho umbral. Si el cliente cargó un CUIT de 11 dígitos, un conector a medida consulta el padrón de ARCA (Constancia de Inscripción) en tiempo real para determinar si corresponde Factura A o Factura B.
¿Cómo sincronizar el stock del depósito físico con Tiendanube para evitar quiebres de stock?+
La arquitectura recomendada utiliza un ERP o base de datos central como única fuente de verdad. Cuando ocurre una venta física en el local, el ERP descuenta el stock y dispara una llamada a la API de Tiendanube (`PUT /products/{id}/variants/{variant_id}`) actualizando la cantidad disponible. Inversamente, cuando Tiendanube emite el webhook `order/paid`, el backend descuenta las unidades del depósito en el ERP en milisegundos, bloqueando la venta en ambos canales si el stock llega a cero.
¿Qué sucede cuando una orden pagada se cancela o se devuelve un producto?+
Cuando Tiendanube dispara el webhook `order/cancelled`, el conector automatizado consulta si la orden ya tiene un CAE asociado en la base de datos. Si existe factura emitida, el sistema invoca automáticamente a ARCA para emitir la correspondiente Nota de Crédito vinculada a la factura de origen, reingresa las unidades de stock al depósito del ERP y genera el comprobante de anulación contable sin requerir intervención manual.
¿Querés que esto funcione en tu empresa?
En Deepyze convertimos procesos manuales en sistemas que trabajan solos: automatización con IA, apps web y móviles, y software a medida. Contanos tu caso y en 24 hs tenés una propuesta concreta.
Sin compromiso · Respuesta en 24 hs · Equipo en tu mismo huso horario