Documentación ACIv2 API
API de integración para facturación electrónica con múltiples plataformas
Acerca de esta API
ACIv2 es una API basada en Firebase Functions que proporciona integración con múltiples plataformas de gestión empresarial para la emisión de facturas electrónicas en Panamá.
Plataformas Soportadas
QuickBooks
Sistema de contabilidad y gestión empresarial
Zoho
Suite de gestión empresarial
Xero
Software de contabilidad en la nube
Shopify
Plataforma de comercio electrónico
WooCommerce
Plugin de tienda para WordPress
Dentalink
Sistema de gestión dental
Características Principales
- Autenticación mediante JWT o Basic Auth
- Procesamiento asíncrono de webhooks con sistema de colas (Redis + Bee-Queue)
- Integración con PAC (Proveedor Autorizado de Certificación) para facturación electrónica
- Validación automática de RUC, DV y datos fiscales
- Sincronización bidireccional de facturas y clientes
- Sistema de reintentos y recuperación de errores
Base URL
https://us-central1-zoho-books-edocs-integracion.cloudfunctions.net/aciv2
Arquitectura del Sistema
Infraestructura y componentes técnicos de ACIv2
Stack Tecnológico
Plataforma Backend
- Firebase Functions: Serverless computing en Google Cloud Platform
- Node.js 20+: Runtime de ejecución
- Express.js: Framework web para endpoints REST
- Firestore: Base de datos NoSQL para persistencia
Sistema de Colas
Redis + Bee-Queue
Procesamiento asíncrono de facturas y eventos de webhooks con reintentos automáticos
Autenticación
JWT + Firebase Auth
Tokens RS256 firmados con clave privada, validación contra Firebase Authentication
Integraciones
6 Plataformas
APIs oficiales de QuickBooks, Zoho, Xero, Shopify, WooCommerce, Dentalink
Facturación
PAC Panamá
Integración con Proveedores Autorizados: Docucenter, Alanube, Digifact
Arquitectura de Componentes
aciv2/
├── app/ # Lógica de negocio por plataforma
│ ├── quickbooks/ # Módulos QuickBooks (Invoice, Contact, Item)
│ ├── zoho/ # Módulos Zoho Books/CRM
│ ├── xero/ # Módulos Xero Accounting
│ ├── shopify/ # Módulos Shopify
│ ├── woocommerce/ # Módulos WooCommerce
│ └── dentalink/ # Módulos Dentalink
├── router/ # Endpoints HTTP por plataforma
├── jobs/ # Procesadores de colas y tareas programadas
│ ├── queue.js # Configuración Redis + Bee-Queue
│ └── processors.js # Procesadores centralizados
├── config/ # Configuración y claves
│ └── jwt-key.json # Clave privada RS256
├── email/ # Sistema de envío de comprobantes
├── template/ # Plantillas PDF/XML
└── doc/ # Documentación técnica
Sistema de Colas (Redis + Bee-Queue)
Procesamiento Asíncrono
ACIv2 utiliza un sistema robusto de colas para operaciones críticas:
Colas Disponibles
zohoInvoiceQueue
Procesa emisión de facturas de Zoho al PAC con reintentos automáticos.
- Endpoint: POST /queue/invoices/:invoice_id
- Reintentos: Automáticos con backoff exponencial
- Timeout: 5 minutos por intento
- Validaciones críticas: Prevención de CUFE duplicado y lock de 10 minutos entre emisiones
Política de Reintentos: Los clientes pueden reintentar emisión inmediatamente sin restricciones de intentos. El PAC aplica sus propias validaciones.
zohoCreditNoteQueue
Procesa emisión de notas de crédito de Zoho.
- Reintentos: Automáticos sin límite artificial
- Manejo de errores: Jobs fallidos almacenados en Redis
- Validaciones críticas: Prevención de CUFE duplicado y lock de 10 minutos entre emisiones
Política de Reintentos: Similar a facturas, reintentos inmediatos permitidos sin restricciones de tiempo.
quickbooksInvoiceQueue
Procesa eventos de webhooks de QuickBooks en segundo plano.
- Triggered por: POST /quickbooks/event_processor
- Procesamiento: Facturas creadas/actualizadas automáticamente
- Reintentos inteligentes: Hasta 8 intentos con delays adaptativos
Características del Sistema de Colas
- Respuesta inmediata al cliente (< 200ms)
- Procesamiento real en segundo plano (hasta 9 minutos)
- Reintentos automáticos con backoff exponencial
- Jobs fallidos almacenados para análisis
- Monitoreo de estado de colas via Redis
Validaciones Críticas en Emisión Zoho
Validaciones Activas:
- CUFE Duplicado: Bloquea emisión si el documento ya tiene CUFE asignado
- Lock de 10 minutos: Previene emisiones simultáneas del mismo documento
- Sin límite de intentos: Los clientes pueden reintentar inmediatamente para corregir errores de validación
Nota: El contador de intentos se mantiene solo con fines estadísticos en el panel de gestión.
Sistema de Prevención de Duplicados
Validación Pre-Creación
ACIv2 incluye un sistema robusto de prevención de facturas y pagos duplicados.
Validaciones Automáticas
// Prevención de Facturas Duplicadas
- Verifica DocNumber existente en QuickBooks
- Compara datos de factura (cliente, monto, fecha)
- Detecta similitudes >95% para alertar
- Bloquea creación si CUFE ya existe
// Prevención de Pagos Huérfanos
- Valida que pago tenga líneas de aplicación
- Verifica que facturas relacionadas existan
- Detecta pagos sin aplicar (orphan payments)
- Sugiere vinculación o eliminación
// Auditoría Completa
- Todos los intentos registrados en Firestore
- Logs estructurados por operación
- Métricas de salud del sistema (0-100)
Jobs de Mantenimiento
Reconciliación de Pagos Huérfanos
// Ejecutar manualmente
node jobs/reconcile_orphans_job.js
// Programar con cron (diario 2 AM)
0 2 * * * cd /path/to/aciv2 && node jobs/reconcile_orphans_job.js
Funcionalidades:
- Escanea todos los pagos en QuickBooks
- Identifica pagos sin líneas de aplicación
- Clasifica: eliminar ($0) vs vincular (>$0)
- Genera reporte con acciones recomendadas
Mantenimiento de Webhooks
Sistema Automático de Mantenimiento
Limpieza periódica de configuraciones obsoletas y consolidación de duplicados.
Periodicidad Recomendada
- Diario: Reporte de estado y monitoreo
- Semanal: Consolidación de duplicados
- Mensual: Limpieza de configuraciones >90 días
- Trimestral: Mantenimiento completo con análisis profundo
Comandos de Mantenimiento
// Reporte de configuraciones
GET /quickbooks/maintenance/webhook_configs?action=report
// Limpieza de obsoletos (>90 días)
GET /quickbooks/maintenance/webhook_configs?action=cleanup&days=90
// Consolidación de duplicados
GET /quickbooks/maintenance/webhook_configs?action=consolidate
// Mantenimiento completo (dry run)
POST /quickbooks/maintenance/webhook_configs/full
{
"days": 90,
"dryRun": true
}
Dependencias Principales
{
"firebase-admin": "^12.3.1",
"firebase-functions": "^6.3.2",
"express": "^4.18.1",
"redis": "^4.7.0",
"bee-queue": "^1.7.1",
"intuit-oauth": "^4.0.0",
"node-quickbooks": "^2.0.43",
"@shopify/shopify-api": "^10.0.0",
"@woocommerce/woocommerce-rest-api": "^1.0.1",
"axios": "^1.11.0",
"jsonwebtoken": "^9.0.1",
"puppeteer": "^21.7.0",
"nodemailer": "^6.9.9"
}
Configuración de Despliegue
// Firebase Functions Config
{
"region": "us-central1",
"runtime": "nodejs20",
"timeout": 540, // 9 minutos
"memory": "1GB",
"minInstances": 0,
"maxInstances": 100
}
// Variables de Entorno Requeridas
API_KEY=firebase_api_key
REDIS_HOST=redis_host
REDIS_PORT=6379
JWT_SECRET_KEY=path/to/jwt-key.json
Monitoreo y Logs
Dashboard de Salud
Sistema integrado para monitorear la salud general de la API.
// Ejecutar dashboard
node test/health_check_dashboard.js
// Salida ejemplo:
SCORE DE SALUD DEL SISTEMA: 85/100
Estado: BUENO ⚠️
Facturas creadas: 45
Duplicados bloqueados: 0 ✅
Pagos creados: 42
Huérfanos bloqueados: 2 ⚠️
Recomendaciones:
- Revisar 2 pagos sin líneas de aplicación
- Sistema operando normalmente
Logs Estructurados
Todos los componentes generan logs con el siguiente formato:
[PLATAFORMA] [realm_id/org_id] Mensaje descriptivo
[QUICKBOOKS] [123456] Procesando factura 789 - Intento 1/8
[ZOHO] [org_456] Job 12345 completado exitosamente
[WEBHOOK] webhook_abc123: 3 eventos procesados
Autenticación
La API soporta dos métodos de autenticación:
1. Basic Authentication
Utiliza el header Authorization con credenciales codificadas en Base64:
Authorization: Basic base64(email:password)
Importante
Las credenciales se validan contra Firebase Authentication. En el primer acceso, se genera y almacena un token de sesión en Firestore.
2. JWT Token
Utiliza un token JWT firmado con RS256:
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
También se puede enviar como parámetro de query:
GET /endpoint?token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
Ejemplo de Autenticación con cURL
curl -X GET "https://[base-url]/quickbooks/invoices" \
-H "Authorization: Basic $(echo -n 'user@example.com:password' | base64)"
QuickBooks API
Endpoints para integración con QuickBooks Online.
Autorización
Obtiene la URL de autorización de QuickBooks OAuth2.
Respuesta
{
"authUri": "https://appcenter.intuit.com/connect/oauth2?...",
"state": "random-state-string"
}
Establece los tokens de acceso después de la autorización OAuth2.
Body
{
"code": "authorization_code",
"realmId": "realm_id",
"state": "state_string"
}
Revoca el refresh token de una conexión.
Parámetros
sid- ID de la conexión
Configuración de Clientes
Campos Requeridos para Facturación Electrónica
Para la facturación electrónica panameña, es necesario configurar correctamente los datos RUC/DV en los clientes de QuickBooks. El sistema ACIv2 extrae automáticamente esta información de campos específicos.
Campos Utilizados por ACIv2
1. PrimaryTaxIdentifier (Campo Principal)
Ubicación en QuickBooks: Customer → Tax Info → Business ID No.
Este es el campo oficial de QuickBooks para identificación tributaria. Tiene prioridad 1 en la extracción de datos.
2. AlternatePhone.FreeFormNumber (Campo Alternativo)
Ubicación en QuickBooks: Customer → Phone → Other Phone
Campo de fallback con prioridad 2. Se usa si PrimaryTaxIdentifier está vacío o no tiene formato válido.
Tipos de Receptor
| Código | Tipo Receptor | Descripción | Uso |
|---|---|---|---|
| 01 | Contribuyente | Cliente con RUC válido | Empresas o personas registradas en DGI |
| 02 | Consumidor Final | Sin RUC o cliente genérico | Personas sin registro tributario |
| 03 | Gobierno | Entidades gubernamentales | Instituciones públicas de Panamá |
| 04 | Extranjero | Identificación no panameña | Pasaporte o ID extranjera |
Tipos de Contribuyente
| Código | Tipo | Ejemplo RUC | Formato en QB |
|---|---|---|---|
| 1 | Persona Natural | 9-734-1672 | XXXX9-734-1672 DV:56 |
| 2 | Persona Jurídica | 1825706-1-709732 | XXXX:1825706-1-709732 DV:90 |
Nota: El prefijo XXXX (sin dos puntos) indica Persona Natural. El prefijo XXXX: (con dos puntos) indica Persona Jurídica.
Formatos Soportados en PrimaryTaxIdentifier
1. Persona Natural - Formato Estándar
XXXX9-734-1672 DV:56
XXXX8-123-4567 DV:12
XXXX1-234-5678 DV:34
Patrón: XXXX[provincia]-[tomo]-[asiento] DV:[dv]
- Provincia: 1-13 o E/N/PE (1 o 2 caracteres)
- DV puede escribirse con o sin dos puntos:
DV:56oDV56
2. Persona Natural - Con Prefijos Especiales (NT, AV, PI, etc.)
XXXX13-NT-2-727784 DV:49
XXXX8-AV-1-123456 DV:34
XXXX7-PI-3-654321 DV:78
Patrón 4 segmentos: XXXX[provincia]-[prefijo]-[grupo]-[numero] DV:[dv]
XXXX13-NT-727784 DV:49
XXXX8-AV-123456 DV:34
Patrón 3 segmentos: XXXX[provincia]-[prefijo]-[numero] DV:[dv]
3. Persona Natural - Con Provincias Especiales
XXXE-1234-12345 DV:23
XXXPE-5678-91011 DV:45
XXXN-9876-54321 DV:67
Provincias especiales:
E- Extranjero naturalizadoPE- Provincia especialN- Provincia N
4. Persona Jurídica (Empresa)
XXXX:1825706-1-709732 DV:90
XXXX:1234567-1-123456 DV:45
XXXX:9876543-2-654321 DV:78
Importante: El prefijo XXXX: (con dos puntos) es obligatorio para Persona Jurídica.
Patrón: XXXX:[numero]-[digito]-[correlativo] DV:[dv]
5. Extranjero con Pasaporte
XXXXPORTE:XYZABC123
XXXXPORTE:ABC123XYZ
XXXXPORTE:N1234567890
Patrón: XXXXPORTE:[numero_pasaporte]
Tipo Receptor automático: 04 - Extranjero
6. Formato con TIPO y TIPO_RECEPTOR Explícitos (Opcional)
XXXX9-734-1672 DV:56 TIPO:1 TIPO_RECEPTOR:01
XXXX:1825706-1-709732 DV:90 TIPO:2 TIPO_RECEPTOR:01
XXXX13-NT-2-727784 DV:49 TIPO:1 TIPO_RECEPTOR:03
Estos campos son opcionales y permiten especificar explícitamente:
TIPO:1- Persona NaturalTIPO:2- Persona JurídicaTIPO_RECEPTOR:01- ContribuyenteTIPO_RECEPTOR:02- Consumidor FinalTIPO_RECEPTOR:03- GobiernoTIPO_RECEPTOR:04- Extranjero
Formatos Soportados en AlternatePhone (Fallback)
Si PrimaryTaxIdentifier está vacío, el sistema intentará extraer RUC/DV del campo AlternatePhone.FreeFormNumber (Other Phone).
Formatos Aceptados
// Formato estándar
9-734-1672 56
1825706-1-709732 DV90
8-123-4567 12
// Con DV explícito
9-734-1672 DV:56
1825706-1-709732 DV:90
// Cualquier formato con guiones
123-45-67890 12
E-1234-12345 23
PE-5678-91011 45
Nota: En AlternatePhone no se distingue automáticamente entre Natural/Jurídica. El sistema analiza el RUC para determinarlo.
Ejemplos de Configuración
Ejemplo 1: Cliente Persona Natural
DisplayName: "JEAN CARLOS NARVAEZ"
GivenName: "Jean Carlos"
FamilyName: "Narvaez"
PrimaryTaxIdentifier: "XXXX9-734-1672 DV:56"
Resultado:
- RUC: 9-734-1672
- DV: 56
- TIPO: 1 (Persona Natural)
- TIPO_RECEPTOR: 01 (Contribuyente)
Ejemplo 2: Cliente Persona Jurídica (Empresa)
DisplayName: "EMPRESA XYZ S.A."
CompanyName: "EMPRESA XYZ S.A."
PrimaryTaxIdentifier: "XXXX:1825706-1-709732 DV:90"
Resultado:
- RUC: 1825706-1-709732
- DV: 90
- TIPO: 2 (Persona Jurídica)
- TIPO_RECEPTOR: 01 (Contribuyente)
Ejemplo 3: Cliente con Prefijo Especial NT
DisplayName: "GERALDINE JIMENEZ"
GivenName: "GERALDINE"
MiddleName: "DAILETH MANZANILLA"
FamilyName: "JIMENEZ"
PrimaryTaxIdentifier: "XXXX13-NT-2-727784 DV:49"
Resultado:
- RUC: 13-NT-2-727784
- DV: 49
- TIPO: 1 (Persona Natural)
- TIPO_RECEPTOR: 01 (Contribuyente)
Ejemplo 4: Cliente Extranjero con Pasaporte
DisplayName: "JOHN DOE"
GivenName: "John"
FamilyName: "Doe"
PrimaryTaxIdentifier: "XXXXPORTE:N1234567890"
Resultado:
- PASAPORTE: N1234567890
- RUC: null
- DV: null
- TIPO: null
- TIPO_RECEPTOR: 04 (Extranjero)
Ejemplo 5: Cliente sin RUC (Consumidor Final)
DisplayName: "CLIENTE GENERICO"
PrimaryTaxIdentifier: ""
AlternatePhone: null
Resultado:
- RUC: null
- DV: null
- TIPO: null
- TIPO_RECEPTOR: 02 (Consumidor Final)
Ejemplo 6: Usando AlternatePhone como Fallback
DisplayName: "MARIA GONZALEZ"
PrimaryTaxIdentifier: "" // Vacío
AlternatePhone.FreeFormNumber: "8-456-7890 45"
Resultado:
- RUC: 8-456-7890
- DV: 45
- TIPO: 1 (Persona Natural)
- TIPO_RECEPTOR: 01 (Contribuyente)
- Source: AlternatePhone_Short
Notas Importantes
- Campo Obligatorio en QB:
DisplayNamedebe ser único en QuickBooks - Prioridad de Extracción: PrimaryTaxIdentifier (1°) → AlternatePhone (2°) → Consumidor Final
- Prefijo XXXX: Con dos puntos = Jurídica, sin dos puntos = Natural
- DV Flexible: Puede escribirse como
DV:56oDV56 - Case Insensitive: Los patrones no distinguen mayúsculas/minúsculas
- Validación Automática: El sistema valida la estructura del RUC y determina el tipo automáticamente
- Gobierno (Tipo 03): Debe especificarse explícitamente con
TIPO_RECEPTOR:03
Facturas
Obtiene una lista de facturas de QuickBooks.
Query Parameters
limit- Límite de resultados (default: 100)offset- Offset para paginaciónstartDate- Fecha de inicio (ISO 8601)endDate- Fecha de fin (ISO 8601)
Headers Requeridos
Authorization- Token JWT con orgId
Obtiene facturas con autenticación básica (para uso interno).
Query Parameters
id- ID de factura específicadocNumber- Número de documento
Obtiene una factura específica por su ID.
Parámetros
invoice_sid- ID de la factura
Obtiene detalles completos de una factura con minor version específica.
Query Parameters
minorversion- Versión de la API de QuickBooks (default: 75)
Emite una factura al PAC (Proveedor Autorizado de Certificación).
Body
{
"invoiceId": "123",
"organization": "org_id"
}
Este endpoint procesa la factura y envía al PAC panameño para obtener el CUFE.
Emite una nota de crédito al PAC.
Webhooks
Procesa eventos de webhooks de QuickBooks (create, update, delete).
Body
{
"eventNotifications": [{
"realmId": "realm_id",
"dataChangeEvent": {
"entities": [{
"name": "Invoice",
"id": "123",
"operation": "Create"
}]
}
}]
}
Procesamiento Asíncrono
Este endpoint responde inmediatamente con código 200 y procesa los eventos en segundo plano utilizando sistema de colas.
Health check para verificar el estado del procesador de eventos.
Obtiene la configuración de procesamiento de webhooks para una organización.
Actualiza la configuración de procesamiento de webhooks.
Body
{
"realmId": "realm_id",
"organizationId": "org_id",
"docucenterEnabled": true,
"reason": "Motivo del cambio"
}
Mantenimiento
Operaciones de mantenimiento para configuraciones de webhooks.
Query Parameters
action- Tipo de operación: report | cleanup | consolidatedays- Días de antigüedad para cleanup (default: 90)
Ejecuta mantenimiento completo (reporte, consolidación y limpieza).
Body
{
"days": 90,
"dryRun": true
}
Diagnóstico de mappings entre QuickBooks y Docucenter.
Limpia mappings obsoletos.
Body
{
"dryRun": true
}
Administración
Endpoints para gestión avanzada de clientes, facturas y sincronización con QuickBooks.
Endpoints Especializados
Estos endpoints están diseñados para operaciones administrativas y correcciones de datos. Usan reintentos automáticos y manejo robusto de errores.
Gestión de Clientes
Zoho API
Endpoints para integración con Zoho Books y Zoho CRM.
Autorización
Obtiene la URL de autorización de Zoho OAuth2.
Parámetros
sid- ID de la conexión
Genera access token y refresh token desde código de autorización.
Revoca el refresh token de Zoho.
Facturas
Obtiene lista de facturas de Zoho Books.
Query Parameters
page- Número de páginaper_page- Facturaspor páginastatus- Estado: sent | draft | paid | void
Obtiene una factura específica por su número.
Emite facturas de Zoho al PAC.
Body
{
"invoices": ["invoice_id_1", "invoice_id_2"]
}
Emite una factura específica al PAC (síncrono).
Parámetros
invoice_id- ID de la factura en Zoho
Respuesta
{
"success": true,
"message": "FE01234567890...",
"automaticallyRedirect": "No"
}
Emite una factura usando sistema de colas (asíncrono recomendado).
Parámetros
invoice_id- ID de la factura en Zoho
Respuesta
{
"success": true,
"message": "Trabajo de emisión de factura en progreso.",
"jobId": "12345",
"invoiceId": "invoice_123",
"automaticallyRedirect": "No"
}
Sistema de Colas
Este endpoint usa Redis y Bee-Queue para procesamiento asíncrono. La factura se procesa en segundo plano con reintentos automáticos.
Obtiene facturas electrónicas emitidas (shipments).
Query Parameters
page- Número de páginaper_page- Resultados por página
Obtiene lista de notas de crédito de Zoho.
Notas de Crédito
Obtiene una nota de crédito específica.
Emite notas de crédito al PAC.
Campos Personalizados para Zoho Books
Configuración Requerida en Zoho Books
Para la facturación electrónica panameña, es necesario configurar campos personalizados específicos en Zoho Books. Estos campos almacenan la información requerida por la DGI de Panamá.
Campos Personalizados para Facturas
Configurar en: Personalización de campos de facturas → https://books.zoho.com/app#/settings/preferences/invoices/customfields
Campos Obligatorios
| Campo / API name | Tipo | Valores |
|---|---|---|
Tipo de documentocf_tipo_de_documento |
Menú desplegable (Obligatorio: Sí) |
1-Factura de Operación Interna 2-Factura de Importación 3-Factura de Exportación 4-Nota de Crédito 5-Nota de Débito 6-Nota de Crédito Genérica 7-Nota de Débito Genérica 8-Factura de Zona Franca 9-Reembolso |
Punto de Facturacióncf_punto_de_facturacio_n |
Menú desplegable (Obligatorio: Sí) |
001-Nombre personalizado 1 002-Nombre personalizado 2 003-Nombre personalizado 3 (Formato: 3 dígitos + nombre) |
Naturaleza de la Operacióncf_naturaleza_de_la_operacio_n |
Menú desplegable (Obligatorio: Sí) |
1-Venta 2-Exportación 10-Transferencia 11-Devolución 12-Consignación 13-Remesa 14-Entrega gratuita 20-Compra 21-Importación |
Tipo de la operacióncf_tipo_de_la_operacio_n |
Menú desplegable (Obligatorio: Sí) |
1-Salida o venta 2-Entrada o compra |
Tipo de transacción de ventacf_tipo_de_transaccio_n_de_ven |
Menú desplegable (Obligatorio: Sí) |
1-Venta de Giro del negocio 2-Venta Activo Fijo 3-Venta de Bienes Raíces 4-Prestación de Servicio |
Emisorcf_emisor |
Lookup (Módulo: Usuarios) (Obligatorio: Sí) |
Usuario del sistema que emite |
Forma de pagocf_forma_de_pago |
Menú desplegable (Obligatorio: Sí) |
01-Crédito 02-Efectivo 03-Tarjeta Crédito 04-Tarjeta Débito 05-Tarjeta Fidelización 06-Vale 07-Tarjeta de Regalo 08-Transf./Depósito Bancario 09-Cheque 10-Punto de Pago 99-Otro |
Tiempo de pagocf_tiempo_de_pago |
Menú desplegable (Obligatorio: Sí) |
1-Inmediato 2-Plazo 3-Mixto |
CUFEcf_cufe |
Cuadro de texto (varias líneas) (Obligatorio: Sí) |
Generado por el PAC al emitir |
Campos Opcionales
cf_informaci_n_de_inter_s- Cuadro de texto (Información de interés del emisor)cf_estado_factura- Cuadro de texto (Estado de la factura)cf_n_mero_secuencial- Número (Número secuencial interno)cf_condiciones_de_entrega- Texto (Condiciones de entrega)
Campos para Exportación
cf_moneda_de_la_operaci_n_de_e- Moneda de la operacióncf_descripci_n_de_moneda_de_la- Descripción de la monedacf_tipo_de_cambio_a_la_fecha_d- Tipo de cambiocf_monto_en_la_moneda_extranje- Monto en moneda extranjera (Decimal)cf_puerto_de_embarque_de_la_me- Puerto de embarque
Campos de Retención
cf_c_digo_de_retenci_n_a_aplic- Código de retención (Menú desplegable):- 01-Pago por servicio profesional al estado 100%
- 02-Pago por venta bienes/servicios al estado 50%
- 03-Pago a no domiciliado 100%
- 04-Pago por compra bienes/servicios 50%
- 07-Pago a comercio TC/TD 50%
- 08-Otros (disminución)
Campos Personalizados para Notas de Crédito
Configurar en: Personalización de campos de Nota de crédito → https://books.zoho.com/app#/settings/preferences/creditnotes/customfields
| Campo / API name | Tipo | Valores |
|---|---|---|
Tipo de documentocf_tipo_de_documento |
Menú desplegable (Obligatorio: Sí) |
4-Nota de Crédito Referente a una o varias FE 6-Nota de Crédito Genérica |
CUFEcf_cufe |
Cuadro de texto (varias líneas) (Obligatorio: Sí) |
Generado por el PAC al emitir |
Campos Personalizados para Artículos/Items
Configurar en: Personalización de campos de artículos → https://books.zoho.com/app#/settings/preferences/items/customfields
| Campo / API name | Tipo | Descripción |
|---|---|---|
Número secuencialcf_nu_mero_secuencial |
Número (Opcional) | Mostrar en transacciones: Sí |
Código internocf_co_digo_interno |
Texto (Opcional) | Código interno del ítem |
Código del Ítem Abreviadocf_co_digo_del_i_tem_abreviado |
Texto (Opcional) | Código abreviado |
Código del Ítemcf_co_digo_del_i_tem |
Texto (Opcional) | Código completo del ítem |
Código GTINcf_co_digo_gtin_del_i_tem |
Número (Opcional) | Código GTIN/EAN del producto |
Fecha de fabricacióncf_fecha_de_fabricacio_n |
Fecha (Opcional) | Fecha de fabricación del producto |
Fecha de caducidadcf_fecha_de_caducidad |
Fecha (Opcional) | Fecha de caducidad del producto |
Campos Personalizados para Usuarios/Clientes
Configurar en: Personalización de campos de usuarios → https://books.zoho.com/app#/settings/preferences/users/customfields
| Campo / API name | Tipo | Valores |
|---|---|---|
Tipo de Contribuyentecf_tipo_de_contribuyente |
Menú desplegable | 1-Natural 2-Jurídico |
RUCcf_ruc |
Texto | Número de RUC del usuario |
Dígito Verificadorcf_di_gito_verificador |
Número | DV del RUC |
Teléfonocf_tele_fono |
Texto | Número telefónico |
Código PDCcf_co_digo_de_provincia_distrito_y_corregimiento |
Texto | Código completo (Provincia-Distrito-Corregimiento) |
Provinciacf_provincia |
Menú desplegable | BOCAS DEL TORO COCLE COLON CHIRIQUI DARIEN HERRERA LOS SANTOS PANAMA VERAGUAS PANAMA OESTE |
Distritocf_distrito |
Texto | Nombre del distrito |
Corregimientocf_corregimiento |
Texto | Nombre del corregimiento |
Coordenadas geográficascf_coordenadas_geogr_ficas |
Texto | Lat,Long del emisor |
Campos Personalizados para Contactos (Clientes)
Configurar en: Personalización de campos de clientes → https://books.zoho.com/app#/settings/preferences/contacts
| Campo / API name | Tipo | Valores |
|---|---|---|
Tipo de receptorcf_tipo_de_receptor |
Menú desplegable | 1-Contribuyente 2-Consumidor final 3-Gobierno 4-Extranjero |
Tipo de Contribuyentecf_tipo_de_contribuyente |
Menú desplegable | 1-Natural 2-Jurídico |
Configuración de Impuestos
Configurar en: Tasas de impuestos → https://books.zoho.com/app#/settings/taxes/taxrates
Tasas de ITBMS (Panamá)
| Nombre del Impuesto | Tarifa (%) |
|---|---|
| 1: 7% | 7 |
| 2: 10% | 10 |
| 3: 15% | 15 |
Integración con Scripts Deluge (Opcional)
Botones Personalizados en Zoho
Zoho Books permite crear botones personalizados usando Deluge Script para automatizar la emisión de facturas y notas de crédito directamente desde la interfaz web.
Script para timbrar Factura (Deluge)
Ubicación: Preferencias → Facturas → Botones Personalizados
custom_field = invoice.get("custom_field_hash");
if(custom_field != null && custom_field.get("cf_cufe") != null && custom_field.get("cf_cufe") != "CUFE")
{
return {"code":2830,"message":"Ya existe Factura autorizada: " + custom_field.get("cf_cufe")};
}
else
{
invoiceId = invoice.get("invoice_id");
Base64Encoded = zoho.encryption.base64Encode("email:password");
AuthorizationBasic = " Basic " + Base64Encoded;
headers = Map();
headers.put("Accept","application/json");
headers.put("Content-Type","application/json");
headers.put("Authorization",AuthorizationBasic);
requestMap = Map();
requestMap.put("organization_id","your_org_id");
setInvoice = postUrl("https://us-central1-zoho-books-edocs-integracion.cloudfunctions.net/aciv2/invoices/" + invoiceId,requestMap,headers);
if(setInvoice.get("success") == false)
{
return {"code":2830,"message":setInvoice.get("message")};
}
else
{
return setInvoice;
}
}
Script para timbrar Nota de Crédito (Deluge)
Ubicación: Preferencias → Notas de Crédito → Botones Personalizados
custom_field = creditnote.get("custom_field_hash");
if(custom_field != null && custom_field.get("cf_cufe") != null && custom_field.get("cf_cufe") != "CUFE")
{
return {"code":2830,"message":"Ya existe Nota de crédito autorizada: " + custom_field.get("cf_cufe")};
}
else
{
creditnoteId = creditnote.get("creditnote_id");
Base64Encoded = zoho.encryption.base64Encode("email:password");
AuthorizationBasic = " Basic " + Base64Encoded;
headers = Map();
headers.put("Accept","application/json");
headers.put("Content-Type","application/json");
headers.put("Authorization",AuthorizationBasic);
requestMap = Map();
requestMap.put("organization_id","your_org_id");
setCreditNote = postUrl("https://us-central1-zoho-books-edocs-integracion.cloudfunctions.net/aciv2/credit_notes/" + creditnoteId,requestMap,headers);
if(setCreditNote.get("success") == false)
{
return {"code":2830,"message":setCreditNote.get("message")};
}
else
{
return setCreditNote;
}
}
Notas Importantes
- Reemplazar
email:passwordcon las credenciales de autenticación Basic Auth - Reemplazar
your_org_idcon el ID de organización del sistema - Reemplazar
[proyecto]con el ID del proyecto Firebase - Los scripts validan que no exista CUFE previo para evitar duplicados
Xero API
Endpoints para integración con Xero Accounting.
Autorización
Obtiene la URL de autorización de Xero OAuth2.
Establece los tokens de acceso de Xero.
Revoca el refresh token.
Facturas
Obtiene facturas de Xero.
Obtiene una nota de crédito específica.
Obtiene una factura específica por su ID.
Emite facturas de Xero al PAC.
Emite una factura específica por su ID.
Parámetros
invoice_id- ID de la factura en Xero
Respuesta
{
"success": true,
"message": "FE01234567890..."
}
Obtiene facturas con autenticación básica (para uso interno).
Obtiene nota de crédito con autenticación básica.
Exportación de Datos
Exporta JSON de factura para pruebas y debugging.
Query Parameters
invoice_sid- ID de la factura
Respuesta
{
"path": "https://storage.googleapis.com/.../12345.txt"
}
Exporta JSON de nota de crédito.
Query Parameters
invoice_sid- ID de la nota de crédito
Exporta JSON de factura emitida (shipment).
Query Parameters
invoice_sid- ID de la factura emitida
Emite notas de crédito al PAC.
Shopify API
Endpoints para integración con Shopify.
Autorización
Obtiene la URL de autorización de Shopify.
Body
{
"shop": "tienda.myshopify.com",
"scopes": "read_orders,write_orders"
}
Establece el access token de Shopify.
Actualiza la configuración del cliente Shopify.
Revoca el token de acceso.
Órdenes
Obtiene órdenes de Shopify para facturación.
Query Parameters
status- Estado de la ordenlimit- Límite de resultadossince_id- ID mínimo para paginación
Lista de órdenes sin procesamiento adicional.
Obtiene una orden específica.
Obtiene reembolsos de una orden (para notas de crédito).
Emisión de Facturas
Procesa emisión de factura desde webhook de Shopify (automático).
Parámetros
sid- ID de la organización
Respuesta
{
"success": true,
"error": false,
"message": "Orden emitida correctamente",
"data": {...},
"timestamp": "2026-02-12T10:30:00.000Z"
}
Este endpoint se usa típicamente como receptor de webhooks de Shopify y retorna siempre código 200 con el estado en el body.
Emite factura manualmente (invocación directa).
Parámetros
sid- ID de la organización
Body
{
"order_id": "123456789",
"force": false
}
Emite nota de crédito manualmente desde un reembolso.
Webhooks
Lista los webhooks registrados en Shopify.
Registra un webhook en Shopify para notificaciones automáticas.
Body
{
"topic": "orders/create",
"address": "https://your-api.com/shopify/orders/to_emit/:sid",
"format": "json"
}
Elimina un webhook registrado.
Body
{
"webhook_id": "123456789"
}
Facturas Emitidas
Obtiene facturas electrónicas emitidas (shipments).
Query Parameters
page- Número de páginaper_page- Resultados por página
Exporta JSON de factura emitida para debugging.
Query Parameters
invoice_sid- ID de la factura emitida
WooCommerce API
Endpoints para integración con WooCommerce.
WooCommerce utiliza autenticación mediante Consumer Key y Consumer Secret de la API REST de WooCommerce.
Configuración
Configura las credenciales de API de WooCommerce.
Parámetros
sid- ID de la conexión
Body
{
"url": "https://tienda.com",
"consumerKey": "ck_xxxxxxxxxxxxxxxxxxxxx",
"consumerSecret": "cs_xxxxxxxxxxxxxxxxxxxxx"
}
Órdenes
Obtiene lista de órdenes de WooCommerce para facturación.
Query Parameters
status- Estado de órdenes: completed | processing | pendingpage- Número de páginaper_page- Órdenes por páginaafter- Fecha de inicio (ISO 8601)before- Fecha de fin (ISO 8601)
Respuesta
{
"code": 0,
"message": "success",
"data": [...],
"page_context": {
"page": 1,
"per_page": 10,
"has_more_page": false
}
}
Emite una factura específica al PAC.
Parámetros
invoice_id- ID de la orden en WooCommerce
Respuesta
{
"success": true,
"message": "FE01234567890...",
"automaticallyRedirect": "No"
}
Procesa emisión de factura desde webhook de WooCommerce.
Parámetros
sid- ID de la aplicación WooCommerce
Este endpoint se usa típicamente como receptor de webhooks de WooCommerce.
Webhooks
Registra un webhook en WooCommerce para notificaciones automáticas.
Body
{
"topic": "order.created",
"delivery_url": "https://your-api.com/woo/invoices/to_emit/:sid"
}
Elimina un webhook registrado.
Body
{
"webhook_id": "123"
}
Envíos
Obtiene información de envíos asociados a órdenes.
Exportación
Exporta PDF de factura emitida por su CUFE.
Parámetros
cufe- Código Único de Factura Electrónica
Redirige automáticamente a la URL del PDF según el PAC (Docucenter, Alanube, etc.)
Exporta XML de la factura electrónica.
Genera carta de representación gráfica en PDF.
Genera cinta de auditoría en PDF.
Dentalink API
Endpoints para integración con Dentalink (sistema de gestión dental).
Dentalink integra tratamientos dentales, pagos y pacientes para emisión de facturas electrónicas del sector salud.
Pacientes
Busca pacientes en Dentalink.
Query Parameters
q- Término de búsqueda (nombre, RUC, etc.)
Respuesta
{
"patients": [{
"id": "123",
"name": "Juan Pérez",
"ruc": "8-123-456",
"email": "juan@example.com"
}]
}
Obtiene los pagos de un paciente específico.
Parámetros
sid- ID del paciente en Dentalink
Obtiene los tratamientos de un paciente.
Parámetros
sid- ID del paciente
Respuesta
{
"treatments": [{
"id": "456",
"name": "Ortodoncia",
"status": "active",
"amount": 1500.00
}]
}
Facturas
Obtiene detalles de una factura/tratamiento por su ID relativo.
Parámetros
relative_id- ID relativo del tratamiento
Query Parameters
organization_id- ID de la organizaciónpayment_id- IDs de pagos (separados por coma)treatment_id- IDs de tratamientos (separados por coma)treatment_detail_id- IDs de detalles (separados por coma)
Obtiene los pagos asociados a una factura/tratamiento.
Query Parameters
organization_id- ID de la organización
Emite factura electrónica desde datos de Dentalink al PAC.
Body
{
"patient_id": "123",
"treatment_ids": ["456", "789"],
"payment_ids": ["101", "102"]
}
Respuesta
{
"success": true,
"cufe": "FE01234567890...",
"transactionId": "abc123"
}
Exportación
Exporta JSON de factura para pruebas y debugging.
Query Parameters
invoice_sid- ID de la factura
Respuesta
{
"path": "https://storage.googleapis.com/.../invoice.txt"
}
Utilidades y Catálogos
Endpoints para gestión de catálogos, configuraciones y datos auxiliares.
Organizaciones
Obtiene la organización asociada al token JWT.
Headers Requeridos
Authorization- Token JWT con orgId
Respuesta
{
"id": "org_123",
"name": "Mi Organización",
"ruc": "8-123-456",
"connections": [...]
}
Obtiene organizaciones asociadas a un SID específico.
Query Parameters
module- Módulo (quickbooks, zoho, xero, etc.)
Obtiene conexiones asociadas a una organización.
Guarda configuración de organización incluyendo logo.
Body (multipart/form-data)
organization_id: org_123
mostrarTituloExportable: true
logo: [file]
Aplicaciones
Lista todas las conexiones de aplicaciones por tipo.
Parámetros
application- quickbooks | zoho | xero | shopify | woocommerce | dentalink
Ubicaciones y Geografía
Obtiene catálogo de ubicaciones fiscales de Panamá.
Crea una nueva ubicación en el catálogo.
Obtiene catálogo de países para facturación internacional.
Crea o actualiza un país en el catálogo.
Obtiene un país específico por su ID.
Obtiene un país por su código ISO (ej: PA, US, ES).
Catálogos Fiscales
Obtiene catálogo de unidades de medida fiscales.
Obtiene catálogo de condiciones de entrega (Incoterms).
Obtiene catálogo de monedas para facturación multi-moneda.
Crea o actualiza una moneda en el catálogo.
Exportación de Archivos
Exporta el XML de una factura electrónica por su CUFE.
Parámetros
cufe- Código Único de Factura Electrónica
Descarga directa de archivo XML.
Redirige al PDF de la factura electrónica según el PAC.
Parámetros
cufe- Código Único de Factura Electrónica
Redirige automáticamente según el PAC: Docucenter, Alanube, Digifact, etc.
Envía comprobante de factura por email al cliente.
Body
{
"organization_id": "org_123"
}
Usuario
Obtiene información del usuario autenticado desde el token JWT.
Respuesta
{
"userId": "user_123",
"email": "usuario@example.com",
"admin": false
}
Búsqueda de usuario por email (solo para administradores).
Query Parameters
email- Email del usuario a buscar
Mejores Prácticas
Códigos de Respuesta y Errores
Códigos HTTP
La API utiliza códigos de estado HTTP estándar para indicar éxito o fallo de las peticiones.
| Código | Significado | Descripción |
|---|---|---|
200 |
OK | Petición exitosa |
201 |
Created | Recurso creado exitosamente |
400 |
Bad Request | Parámetros inválidos o faltantes |
401 |
Unauthorized | Autenticación inválida o token expirado |
404 |
Not Found | Recurso no encontrado |
422 |
Unprocessable Entity | Error de validación o procesamiento |
500 |
Internal Server Error | Error interno del servidor |
Formato de Errores
Los errores se devuelven en formato JSON con la siguiente estructura:
{
"error": {
"message": "Descripción del error",
"code": "ERROR_CODE",
"details": {
"field": "campo_con_error",
"reason": "explicación específica"
}
}
}
Errores Comunes
Token Expirado
{
"error": {
"message": "Token has expired",
"code": "TOKEN_EXPIRED"
}
}
Solución: Renovar el access token usando el refresh token correspondiente.
RUC Inválido
{
"error": {
"message": "RUC inválido detectado (0-0-0)",
"code": "INVALID_RUC"
}
}
Solución: Verificar que el cliente tenga un RUC válido en la plataforma de origen.
Factura Ya Emitida
{
"skipped": true,
"reason": "already_emitted",
"cufe": "FE01234567890...",
"message": "Factura ya fue emitida al PAC"
}
Solución: La factura ya tiene CUFE, no se puede reemitir. Este no es un error, es un estado informativo.
Rate Limit
Si se excede el límite de peticiones, se recibirá un error 429. El sistema implementa reintentos automáticos con backoff exponencial.
Respuestas Exitosas
Factura Emitida
{
"success": true,
"cufe": "FE0123456789012345678901234567890123456789012345",
"transactionId": "abc123def456",
"docNumber": "001-001-00001234",
"pdfUrl": "https://api.pac.com/pdf/...",
"xmlUrl": "https://api.pac.com/xml/..."
}
Lista de Facturas
{
"code": 0,
"message": "success",
"data": [
{
"id": "123",
"docNumber": "001-001-00001234",
"customer": {...},
"total": 150.00,
"cufe": "FE01234567..."
}
],
"page_context": {
"page": 1,
"per_page": 10,
"has_more_page": true
}
}
Reintentos y Recuperación
Sistema de Reintentos
La API implementa reintentos automáticos para operaciones críticas:
- Facturas: Hasta 8 intentos con backoff exponencial
- Webhooks: Hasta 5 intentos con delays incrementales
- Tokens: Renovación automática en errores 401
- Rate Limits: Espera inteligente según tipo de error
Workflows Comunes
1. Configuración Inicial de Integración
// Paso 1: Obtener URL de autorización
GET /quickbooks/authorization_url
// o para Zoho
GET /authorization_url/:sid
// Paso 2: Usuario autoriza en plataforma
// (redirigir al authUri recibido)
// Paso 3: Establecer tokens
POST /quickbooks/authorization_url/token_set
{
"code": "authorization_code",
"realmId": "realm_id"
}
// Paso 4: Verificar conexión
GET /quickbooks/invoices?limit=1
2. Emisión de Factura (Recomendado)
Usar Sistema de Colas para Mayor Confiabilidad
Para Zoho, se recomienda usar el endpoint con cola:
// QuickBooks (procesamiento asíncrono automático vía webhook)
// Las facturas se procesan automáticamente cuando llegan webhooks
// Zoho (usar cola para asíncrono)
POST /queue/invoices/:invoice_id
{
"organization_id": "org_123"
}
// Respuesta inmediata con job ID
{
"success": true,
"jobId": "12345",
"message": "Trabajo de emisión de factura en progreso."
}
// Shopify/WooCommerce (webhook automático)
// Configurar webhook que apunte a:
POST /shopify/orders/to_emit/:sid
POST /woo/invoices/to_emit/:sid
3. Verificación de Factura Emitida
// Obtener factura con CUFE
GET /quickbooks/invoice/:invoice_id/details?minorversion=75
// Verificar en PrivateNote
{
"Invoice": {
"Id": "123",
"DocNumber": "001-001-00001234",
"PrivateNote": "CUFE: FE01234567890..."
}
}
// Si no tiene CUFE, emitir
POST /quickbooks/to_emit
{
"invoiceId": "123",
"organization": "org_id"
}
Manejo de Webhooks
QuickBooks Webhooks
// Configurar endpoint en QuickBooks Developer Dashboard:
URL: https://your-api.com/quickbooks/event_processor
// Payload recibido:
{
"eventNotifications": [{
"realmId": "123456789",
"dataChangeEvent": {
"entities": [{
"name": "Invoice",
"id": "456",
"operation": "Create"
}]
}
}]
}
// Respuesta inmediata (< 3 segundos)
{
"success": true,
"webhookId": "webhook_abc123",
"processing": "En progreso en segundo plano"
}
Shopify/WooCommerce Webhooks
// Registrar webhook
POST /shopify/orders/post_webhooks
{
"topic": "orders/create",
"address": "https://your-api.com/shopify/orders/to_emit/:sid"
}
// Listar webhooks activos
GET /shopify/orders/post_webhooks/:sid
// Eliminar webhook
POST /shopify/orders/post_webhooks/:sid/remove
{
"webhook_id": "123456789"
}
Optimizaciones y Consideraciones
Rate Limits
- QuickBooks: 500 peticiones/minuto por realmId
- Zoho: 200 peticiones/minuto
- Xero: 60 peticiones/minuto
- Shopify: 2 peticiones/segundo por tienda
La API implementa reintentos automáticos con backoff exponencial.
Validaciones Automáticas
La API realiza las siguientes validaciones antes de emitir:
- RUC válido (no 0-0-0 ni valores placeholder)
- Verificación de CUFE existente (evita duplicados)
- Tax codes válidos (ITBMS0, ITBMS7, ITBMS10, ITBMS15)
- Datos de cliente completos
- Tipo de receptor (nacional 01-02-03 o extranjero 04)
Debugging y Troubleshooting
Exportar JSON para Debugging
// QuickBooks
GET /quickbooks/export_json?id=:invoice_id
// Zoho/Xero/Shopify/WooCommerce/Dentalink
GET /xero/export_json/:org_sid?invoice_sid=:id
GET /shopify/shipments/export_json/:org_sid?invoice_sid=:id
GET /woo/export_json/:app_id
GET /dentalink/shipments/export_json/:org_sid?invoice_sid=:id
// Respuesta
{
"path": "https://storage.googleapis.com/.../invoice.txt"
}
Verificar Configuración de Webhooks
// QuickBooks - Health check
GET /quickbooks/webhook_health
// QuickBooks - Configuración por organización
GET /quickbooks/webhook_processing_config/:realm_id/:organization_id
// QuickBooks - Actualizar configuración
POST /quickbooks/webhook_processing_config
{
"realmId": "123",
"organizationId": "org_456",
"docucenterEnabled": true,
"reason": "Habilitar procesamiento automático"
}
Mantenimiento de Mappings
// Diagnóstico de mappings
GET /quickbooks/mappings/diagnostic/:connection_id
// Limpieza de mappings obsoletos (dry run)
POST /quickbooks/mappings/cleanup/:connection_id
{
"dryRun": true
}
// Ejecutar limpieza real
POST /quickbooks/mappings/cleanup/:connection_id
{
"dryRun": false
}
Seguridad y Autenticación
Protección de Credenciales
- Nunca exponer tokens en logs o respuestas de error
- Usar HTTPS para todas las peticiones
- Rotar refresh tokens periódicamente
- Implementar validación de signatures en webhooks (cuando disponible)
- Almacenar tokens encriptados en Firestore
Renovación Automática de Tokens
La API maneja automáticamente la renovación de tokens:
- Detecta errores 401 y renueva el access token
- Usa refresh token para obtener nuevo access token
- Reintentos automáticos después de renovación
- Actualiza tokens en Firestore para persistencia
Monitoreo y Logs
Logs Estructurados
Los logs de la API incluyen:
// Formato de log típico
[QUICKBOOKS] [realm_id] Procesando factura 123 - Intento 1/8
[QUICKBOOKS] [realm_id] RUC: 8-123-456, DV: 78, TIPO: 01
[QUICKBOOKS] [realm_id] Factura 123 procesada exitosamente
[QUICKBOOKS] [realm_id] CUFE: FE01234567890...
// Logs de webhook
WEBHOOK webhook_abc123: Iniciando procesamiento
WEBHOOK webhook_abc123: 3 eventos recibidos
WEBHOOK webhook_abc123: Procesamiento exitoso - 3/3 procesados
Eventos en Cola
// Ver eventos pausados
GET /quickbooks/paused_webhook_events/:realm_id?organization_id=:org_id
// Reprocesar eventos pausados
POST /quickbooks/reprocess_paused_events/:realm_id
{
"eventIds": ["event_1", "event_2"]
}
Arquitectura y Escalabilidad
Sistema de Colas (Redis + Bee-Queue)
Para operaciones de larga duración:
- Zoho Invoices: Cola dedicada con procesador centralizado
- Zoho Credit Notes: Cola separada para notas de crédito
- QuickBooks Webhooks: Procesamiento en segundo plano
- Reintentos: Hasta 3 intentos por job con backoff exponencial
- Failed Jobs: Almacenados en Redis para análisis
Firebase Functions
- Region: us-central1
- Timeout: 540 segundos (9 minutos)
- Memory: 1GB
- Runtime: Node.js 20+