Facturas
Emisión y gestión de facturas a clientes. Soporta NCF (B-series) para cumplir con DGII, y formato e-CF (E-series) si tienes el addon Emisor e-CF activo.
Dónde aparece en el menú
- Modo Local y Cloud sin Contabilidad: Facturas vive en el grupo Comercial (antes "Finanzas") junto a Servicios, Cotizaciones y Contratos.
- Cloud con addon Contabilidad activo: Facturas se muestra dentro del addon Contabilidad, sub-sección Cobros y Pagos, junto a Gastos, CxC, CxP y Retenciones. Es la misma vista — solo cambia desde dónde se accede.
Cómo usarlo
- Nueva factura — selecciona cliente (de Contactos), agrega líneas desde el Catálogo (servicios, productos o bundles) y aplica ITBIS si corresponde.
- Cotización → Factura — desde una cotización aprobada, un click crea la factura con todas las líneas copiadas.
- Marcar como pagada — cambia el estado a Paid. Una vez pagada, la factura se bloquea (no se puede editar ni eliminar). Para corregir, usa Nota de Crédito.
- Descargar PDF — formato DGII-compatible con tu logo y colores (cloud).
- Ordenar la lista — haz clic en el encabezado de una columna (Número, Cliente, Fecha de emisión, Vencimiento, Importe o Estado) para ordenar; un segundo clic invierte el orden (▲/▼) y un tercero lo quita. Por defecto se muestra de la factura más reciente a la más antigua.
- Paginación — la lista muestra 25 facturas por página. Puedes cambiar a 50, 100 o 200 con el selector, y moverte con Anterior/Siguiente. Al buscar, filtrar o cambiar de pestaña vuelves a la primera página.
- Buscar y filtrar — el buscador cubre número, NCF/e-NCF, cliente y negocio. La búsqueda, el filtro de estado, la pestaña y la página se conservan aunque edites o cambies el estado de una factura.
Los totales de las tarjetas de arriba se calculan sobre todas tus facturas, no sobre la página que estás viendo: no cambian al paginar ni al filtrar.
Crear factura sin trato previo (Factura Directa)
Si solo necesitas facturar a un cliente sin pasar por el Pipeline de ventas, usa el botón Nueva Factura en el encabezado de la pantalla (o el atajo Ctrl+Shift+F).
- Se abre un selector de contacto con typeahead. Consumidor Final aparece arriba como opción rápida si no necesitas identificar al cliente (B02). También puedes buscar por nombre, empresa, RNC o email — el sistema limita la lista a 50 resultados; refiná la búsqueda si tu tenant tiene más contactos.
- ¿No existe el contacto? Despliega Crear contacto nuevo dentro del mismo modal: nombre, apellido y opcionalmente un identificador (el sistema detecta si es RNC de 9 dígitos o cédula de 11). El contacto se persiste y queda seleccionado en un solo paso.
- Al confirmar, se abre el formulario de factura tradicional con el cliente prefillado. La factura postea a Mayor como cualquier otra: el sistema crea un deal sintético atrás-bambalinas (marcado como
is_synthetic=truey excluido del Pipeline / KPIs de conversión) para preservar el contrato relacionalinvoice.dealId. El snapshot DGII (RNC, NCF, tipo de identificación) se toma del contacto + factura — nunca del deal — así que 606/607 y el XML e-CF siguen siendo consistentes.
¿Qué pasa si el tenant es nuevo y aún no tiene Consumidor Final?
El picker muestra un banner rojo y te ofrece crear tu primer contacto. Al completarlo, el singleton de Consumidor Final se inicializa automáticamente para que la próxima factura directa lo encuentre arriba sin que tengas que hacer nada más.
Campos importantes
- NCF B-series — selecciona el tipo (B01 Crédito Fiscal, B02 Consumo, B03 Nota Débito, B04 Nota Crédito, B11–B17) al crear la factura. El sistema asigna automáticamente el siguiente número del rango activo configurado en Configuración → Secuencias NCF. Una vez asignado, el NCF es inmutable: al editar la factura lo verás en solo lectura.
- Dónde aparece el comprobante — el NCF (o el e-NCF, si la factura es electrónica) es el número que identifica el documento ante la DGII, y se muestra en todas partes: el listado, el PDF, el nombre del archivo descargado, el asunto del correo, el mensaje de WhatsApp y la referencia de las notas de crédito. El número interno del CRM (
INV-2026-002) aparece debajo, en pequeño, y sirve solo para conciliar dentro de la aplicación — no tiene valor fiscal. - e-CF — para facturación electrónica (E31, E32, E33, E34, E44, E45) se usa el addon Emisor e-CF. Ver "Enviar a DGII" abajo.
- Forma de Pago (DGII) — código 01–08 (01 Efectivo, 02 Cheque/Transferencia, 03 Tarjeta, 04 Crédito, 05 Bono, 06 Permuta, 07 Nota de Crédito, 08 Otro). Si se deja en auto, se detecta del método de pago registrado; si no existe, se infiere de la condición de pago.
- ITBIS — 18% por defecto. Se aplica por línea según configuración del ítem.
- Cliente RNC — obligatorio para B01/E31.
- Estado — Draft, Sent, Paid, Cancelled. Solo Draft permite edición libre.
Líneas y catálogo
Cada línea referencia un ítem del Catálogo (catalogItemId). El nombre y precio se copian al momento de crear la línea, así cambios futuros en el catálogo no alteran facturas históricas.
Si vendes un bundle desde una factura core, hoy NO se descompone automáticamente en sus componentes (solo Commerce orders lo hace). Para inventario y reporting de servicios, vende bundles desde POS u Orders.
Enviar a DGII (e-CF)
Requiere modo cloud + addon Emisor e-CF activo + tipo e-CF asignado a la factura.
Antes de enviar, el sistema valida:
- RNC del comprador — obligatorio y bien formado (9 dígitos RNC o 11 cédula) para tipos 31, 33, 34, 41, 44 y 45. Para tipo 32 (Consumo) es opcional, pero si está presente debe ser válido. El 43 (Gastos Menores) no lleva comprador: el contacto de la factura no viaja en el XML. Los tipos 46 y 47 facturan a un contacto extranjero: se envía su identificador (pasaporte o Tax ID) y país en lugar del RNC; el 46 exige que el contacto lo tenga.
- Datos del emisor — RNC, razón social y dirección salen de la configuración del addon Emisor e-CF. Si falta alguno, el envío se detiene y te dice cuál.
- Secuencia e-NCF del tipo — debe existir un rango activo con fecha de vencimiento en Config e-CF → Secuencias. Sin él no se asigna número y no se envía nada.
- Totales — el XML se recalcula desde las líneas (líneas con ITBIS al 18% o 16%; sin ITBIS = exentas; en la 46 todo al 0%). Si el total resultante no coincide con el de la factura, se detiene y muestra ambos montos en vez de enviar una cifra distinta a la que ves.
- Moneda — por ahora solo se emite en DOP. Una factura en otra moneda se rechaza con aviso.
- ITBIS — se calcula con la tasa de la factura (
taxRate, 18% por defecto). Ya no está fija en 18% para futuras tasas o regímenes especiales. - Forma de pago — se envía a DGII como código 01–08. Orden de resolución: (1) valor explícito
formaPagoen la factura, (2) mapeo del método de pago registrado (Cash→01, Transfer/Check→02, Card→03, Credit→04, etc.), (3) por defecto según condición de pago (contado→01, crédito→04, mixto→08).
Si la validación falla, la factura no se envía y se muestra el error. Corrige el dato en el contacto o en la factura y reintenta.
Protección contra doble envío (idempotencia): si haces doble-click en "Enviar" o la conexión falla después de que DGII aceptó el documento, el sistema NO genera un segundo e-NCF. Una bandera en memoria bloquea el reintento mientras el primer envío está en vuelo, y un índice único en la base de datos por (tenant, invoiceId) bloquea el caso entre pestañas o sesiones. Si reintenta una factura ya procesada, se devuelve el resultado original (con la bandera idempotent: true).
Resiliencia de la conexión con DGII
El envío a DGII tiene varias capas de protección para que una red inestable o un pico de latencia en el fisco no te dejen facturas en limbo:
- Timeouts explícitos — autenticación 20s, envío 30s, consulta 15s. Si DGII no responde, la Edge Function corta y reintenta en vez de colgarse.
- Reintento automático con backoff — en errores transitorios (429 "Too Many Requests" o 5xx de DGII) el cliente reintenta hasta 3 veces con espera 2s → 4s → 8s. Si DGII devuelve un
Retry-After, se respeta. - Serialización por RNC — los envíos del mismo tenant se procesan de uno en uno con una pausa mínima de 500ms entre calls, para no disparar rate-limits del lado de DGII.
- Reconciliación automática — una tarea programada cada 15 minutos revisa cualquier documento que quedó en estado
submitted(DGII tardó más de 1 minuto en responder) y consulta su TrackId para actualizarlo sin intervención manual. Ya no depende del botón "Verificar Estatus". - Métricas de latencia — cada envío persiste
dgii_submit_ms(tiempo del POST),dgii_submit_retries(reintentos usados) y los timestampsdgii_first_poll_at/dgii_final_poll_at(ventana de polling). Queda historial para auditar "cuánto tardó DGII" factura por factura.
Aprobación comercial del comprador (ACECF)
Cuando un comprador recibe tu e-CF, puede enviarnos un ACECF (Aprobación o Rechazo comercial). Ese documento se recibe en el endpoint /fe/aprobacion, se valida criptográficamente y —nuevo en este release— se propaga automáticamente a la factura: los campos commercialStatus (accepted / rejected), commercialStatusAt y commercialStatusReason se actualizan solos. Ya no necesitas abrir la tabla de auditoría para saber si el comprador aceptó.
Enviar el e-CF al comprador por email
Después de que DGII acepta un documento, el modal de resultado ofrece el botón "Enviar al comprador". Se muestra solo si el contacto tiene un email registrado y el estado es accepted o conditional (nunca para rejected). Al hacer clic, se abre la vista PDF y se envía por email usando el SMTP del tenant.
Importar facturas históricas desde otro sistema
Botón Importar en la cabecera. Sirve para dar continuidad a la operación
cuando vienes de otro CRM: trae tu histórico de facturación para que sepas
quién te debe, cuánto y desde cuándo.
Carga primero las organizaciones (ver ayuda de Contactos). Las facturas van a
nombre de la organización y la referencian por su organization_external_id.
Descarga la plantilla de facturas desde el propio asistente. Lleva **una fila
por línea de factura**, repitiendo el external_id y el número en cada una:
| external_id | invoice_number | organization_external_id | issue_date | total | description | quantity | unit_price | line_total |
|---|---|---|---|---|---|---|---|---|
| VT-INV-42 | FAC-0042 | VT-ORG-1 | 2023-05-14 | 12500.00 | Soporte mensual | 1 | 8000.00 | 8000.00 |
| VT-INV-42 | FAC-0042 | VT-ORG-1 | 2023-05-14 | Horas adicionales | 3 | 1500.00 | 4500.00 |
Antes de escribir nada, el asistente simula la importación y te muestra tres
totales: Total facturado, Cobrado y Por cobrar. Son los números que
debes comparar contra tu sistema anterior. Si no cuadran, corriges el archivo y
vuelves a intentar — no se ha tocado nada todavía.
Las filas con problemas no entran y se listan con su motivo, agrupadas por
categoría. Puedes descargar el reporte de excepciones en CSV, corregir el
archivo y reimportar: las facturas que ya entraron se actualizan, no se
duplican. Ninguna validación ajusta un importe por su cuenta — si las líneas no
suman el total de la cabecera, esa factura se rechaza y te dice la diferencia
exacta.
Columnas que tu sistema tiene y este no: nómbralas custom.lo_que_sea en el
archivo. El asistente las detecta y te deja vincularlas a un campo personalizado
existente o crearlo ahí mismo, sin salir de la importación.
Qué NO hace la importación (a propósito)
- No emite comprobantes fiscales. Esas facturas ya las declaró tu sistema
anterior. El NCF original se conserva en legacy_ncf y se ve, pero el
documento no entra al 606/607 ni se envía a la DGII.
- No genera asientos contables. Tus ingresos históricos ya están en tu
contabilidad anterior; volver a contabilizarlos los duplicaría. Por eso el
histórico no aparece en el Mayor, solo en Facturas y Cuentas por Cobrar.
- No crea negocios en el Embudo. Una factura de hace dos años no es una
venta cerrada de este mes, y contarla distorsionaría tus indicadores.
Puedes ver una factura importada, registrarle pagos y editarla con
normalidad, aunque no tenga un negocio asociado (las migradas nunca lo tienen).
Al editarla verás el NCF original en solo lectura: un documento histórico no
recibe un comprobante nuevo, porque ya lo declaró tu sistema anterior.
Guía completa del proceso: ayuda de Importar desde otro sistema.
Permisos
- invoices:view — listar facturas (filtrado por scope: propias o todas).
- invoices:create / edit — crear y modificar (no aplica a Paid).
- invoices:delete — enviar a papelera y restaurar desde ella.
- Las facturas Paid son inmutables para todos los roles. Usa Nota de Crédito (E34) para correcciones.
Inmutabilidad — cuándo una factura se bloquea
Una factura se vuelve inmutable en dos casos:
- Pagada (estado
Paid) — no se puede editar, eliminar ni cambiar de estado. Solo queda emitir una Nota de Crédito E34 para corregir. - Firmada en DGII (
encfasignado odgiiTrackIdrecibido) — aunque la factura aún no esté pagada, si ya fue enviada a DGII, editar montos, líneas o RNC del comprador desincronizaría el XML firmado con el registro en el CRM. DGII considera eso un fraude fiscal.
Qué queda bloqueado cuando una factura está firmada en DGII:
- Edición del form (amount, items, cliente) → redirige al PDF de solo lectura.
- Envío a la papelera → bloqueado; usa Nota de Crédito E34.
- Cambio de estado a Borrador → bloqueado (no puedes "des-enviar" un e-CF); Paid y Overdue sí son válidos.
- Cambio del RNC del contacto asociado → bloqueado si el contacto tiene al menos una factura firmada (cualquier edición afectaría la firma histórica).
Eliminar y Papelera
Para preservar auditoría, las facturas no se eliminan físicamente. El botón Eliminar marca la factura como eliminada (soft-delete) con fecha, usuario y razón opcional. El registro sale de listas, KPIs, CxC y reportes de Contabilidad — pero sigue en la base de datos y en los asientos emitidos antes del borrado.
- Facturas Paid NO se pueden eliminar (ni siquiera lógicamente). La única forma de anular/corregir una factura pagada es emitir una Nota de Crédito E34 referenciando el NCF original.
- Facturas enviadas a DGII tampoco se eliminan. Aunque no estén pagadas, al tener
encfodgiiTrackIdestán firmadas con el fisco: para corregirlas emite una Nota de Crédito E34. - Papelera — el botón en la esquina superior derecha del listado cambia a modo Papelera y muestra solo las eliminadas. Desde allí puedes Restaurar (vuelve al listado activo) o dejarla en papelera indefinidamente.
- Auditoría — cada soft-delete y restauración deja una entrada en el
activityLogde la factura (action: 'soft_deleted'/'restored', conuserIdytimestamp). - Los addons (Contabilidad, e-CF, reportes 606/607) nunca ven facturas eliminadas: la Contract API las filtra automáticamente.
Preguntas frecuentes
¿Por qué no puedo editar esta factura?
Porque está marcada como Paid. Crea una Nota de Crédito vinculada para anular o ajustar.
¿Cómo asigno un NCF automáticamente?
Selecciona el Tipo NCF B-series al crear la factura. El siguiente número del rango activo se asigna al guardar. Si no hay rango disponible, verás un error y la factura no se guarda — configura un rango en Configuración → Secuencias NCF y reintenta. Cada tenant maneja sus propios rangos.
¿Por qué solo veo B16 y B02 en el select de NCF para este cliente?
Porque el contacto está marcado como extranjero (Pasaporte o Tax ID extranjero) en su Tipo de Identificación. Los únicos NCF que la DGII permite para clientes sin RNC dominicano son:
- B16 — Comprobante de Exportación para ventas al exterior (factura formal a empresa/persona extranjera).
- B02 — Comprobante para Consumidor Final para ventas de bajo monto sin necesidad de identificar al comprador.
Si necesitas un B01 (Crédito Fiscal) para este cliente, primero edita el contacto y cambia su Tipo de Identificación a RNC (empresas dominicanas) o Cédula (personas físicas dominicanas) y completa el número correspondiente.
¿Y si el cliente no tiene Tipo de Identificación?
Entonces el sistema solo te ofrece B02 — Consumidor Final. Para desbloquear los demás NCF, abre el contacto y selecciona el Tipo de Identificación correcto. La lista de contactos muestra un banner ámbar contando cuántos faltan completar.
¿Cómo facturo en dólares (USD) a un cliente del exterior?
El selector de Moneda (DOP / USD / EUR) está siempre visible al crear la factura, sin necesidad de activar el e-CF. Para una factura de exportación comercial (sin comprobante fiscal dominicano) elige USD, deja el e-CF desactivado y el NCF en "Ninguno". El PDF y los totales se mostrarán en la moneda elegida.
Al elegir una moneda distinta de DOP aparece el campo Tasa de cambio (a DOP). Esa tasa es la que usa la contabilidad para convertir el asiento a pesos (los libros siempre están en DOP). Si dejas la tasa vacía, la factura se emite igual, pero su asiento contable queda en "borrador" en Asientos hasta que completes la tasa — así nunca se registra un monto en dólares como si fueran pesos. Si capturas la tasa, el asiento se contabiliza convertido a DOP automáticamente.
Esto aplica igual en el addon Emisor e-CF → Nueva Factura e-CF: al cambiar la moneda aparece el mismo campo de tasa, y si lo dejas vacío verás un aviso recordándote que el asiento quedará en borrador.
Nota: emitir un e-CF de Exportación (tipo 46) formal en moneda extranjera es una función distinta, aún en preparación. Consulta con tu contador si tu operación requiere el e-CF 46 o si basta una factura comercial en USD.
¿Puedo personalizar el diseño de mis facturas y cotizaciones con mi marca?
Sí. En Configuración → Diseño de Facturas (modo nube) puedes ajustar: logo, color primario y de acento, tipografía, plantilla (Moderna / Clásica / Minimal), texto de encabezado y de pie de página, y mostrar/ocultar los bloques de información de pago y de notas. Aplica tanto al PDF de factura como al de cotización.
Importante (cumplimiento DGII): en las facturas electrónicas, los campos fiscales obligatorios (e-NCF, RNC del emisor y comprador, QR, código de seguridad, desglose de ITBIS, totales, fecha de firma y la leyenda legal) siempre se muestran y la marca nunca los altera ni los puede ocultar. Si una factura firmada quedara sin algún dato obligatorio, verás un aviso ámbar en la vista previa. Las cotizaciones no son documentos fiscales, así que tienen libertad total de diseño.
Mi factura quedó como "borrador" en Asientos y dice que falta RNC ¿qué hago?
Sucede cuando emites una factura B01/B14/B15 (que requieren RNC) pero el contacto no tiene RNC capturado. Tienes dos caminos:
- Cliente local sin RNC en el sistema — abre el contacto, completa el RNC/Cédula y elige el Tipo de Identificación correspondiente. Después borra el draft del asiento y re-emite la factura.
- Cliente extranjero o consumidor final — cambia el Tipo de Identificación del contacto a Pasaporte/Tax ID extranjero (o déjalo sin identificar para consumidor final). El select de NCF se restringirá automáticamente a B16/B02. Re-emite la factura con la NCF correcta y el asiento postea limpio.
¿Qué pasa si se acaba el rango NCF?
La asignación falla con mensaje claro ("Sin rango NCF disponible para tipo XX"). No se crea una factura sin NCF. Agrega un nuevo rango autorizado por DGII en Configuración → Secuencias NCF y reintenta.
¿Las facturas se sincronizan a Contabilidad?
Sí, si tienes el addon Contabilidad activo — genera asientos automáticos al marcar como Paid.
¿Cómo elimino una factura?
Usa el icono de papelera en el listado: la factura se mueve a la Papelera (soft-delete, reversible) con auditoría. No se borra del archivo físico. Las facturas pagadas NO se pueden eliminar — usa Nota de Crédito E34.
¿Puedo recuperar una factura borrada por error?
Sí. Abre la Papelera (botón arriba a la derecha en Facturas), localiza la factura y presiona Restaurar.
¿Por qué veía facturas duplicadas de mis contratos de servicio?
Era un bug ya corregido (v1.8.15). Las facturas recurrentes de Service Contracts usan desde ahora un id determinístico por (contrato, período) + un índice único en la base de datos, así que un refresh o un cierre de pestaña en medio de la generación ya no puede crear facturas duplicadas. Si ves duplicados viejos, envíalos a la Papelera.
Enviar por WhatsApp
Requiere modo cloud + addon WhatsApp activo + contacto con teléfono válido (formato DR 809/829/849-XXX-XXXX o E.164 internacional).
Cuando abres la vista previa de una factura (botón Descargar PDF), aparece un botón verde WhatsApp al lado de Enviar Email. Al hacer click se abre un modal con:
- Tarjeta del destinatario — avatar con iniciales del contacto, nombre, teléfono normalizado y un badge de estado:
- 🟢 Opt-in granted con fecha si el contacto consintió formalmente recibir mensajes (campo
whatsappOptInAt). - 🟡 Sin opt-in registrado — la captura de opt-in todavía es manual; llega en Oleada B junto con Settings → Compliance. Es seguro enviar plantillas categoría utility (factura, e-CF aprobado, recibos) sin opt-in explícito; las plantillas marketing sí lo requieren por Ley 172-13.
- 🔴 Teléfono inválido — el botón Enviar se desactiva. Edita el contacto y agrega un teléfono en formato 809-XXX-XXXX.
- Selector de plantilla — en Fase 1 solo
factura_emitidaestá activa. Las opcionesecf_aprobadoy "Mensaje libre" aparecen como deshabilitadas porque dependen de: - Catálogo de templates sincronizado con Meta (Oleada B/C).
- Ventana de servicio 24h activa (requiere mensaje entrante reciente del cliente; tracking en Oleada B).
- Vista previa con burbuja verde estilo WhatsApp mostrando el mensaje exacto que recibirá el cliente. El body del template aprobado es:
Hola {{1}} 👋 Hemos emitido tu factura electrónica número {{2}} por un monto total de RD${{3}}. La fecha de vencimiento para el pago es el {{4}}. Gracias por tu preferencia, cualquier consulta estamos a tu orden.
SimplifyCRM · Responde STOP para baja
- {{1}} Nombre del contacto
- {{2}} Número de factura (
encfsi es e-CF, de lo contrarioinvoiceNumber) - {{3}} Total formateado
- {{4}} Fecha de vencimiento (locale es-DO)
- El link a ConsultaTimbre (QR URL) aparece solo en la vista previa del CRM como referencia visual al operador. NO va en el mensaje real porque las plantillas utility de Meta no permiten URLs libres en el body. Para enviarlo al cliente en futuras versiones se agregará como botón URL (Oleada B).
- Fila de costo — muestra "$0.0113 estimado" como referencia. El cálculo real basado en categoría de template + ventana 24h llega en Oleada C tras el Tech Provider Program de Meta.
Cómo funciona el envío
- El frontend llama al Edge Function
whatsapp-sendcontype=template, nombrefactura_emitida, idiomaesy los 4 parámetros. - El Edge Function busca el
phone_number_idactivo enwhatsapp_accounts(Fase 1 single-tenant; multi-tenant llega en Fase 3 con Embedded Signup). - POST a Meta Graph API v25.0 con el token System User long-lived.
- Meta responde con
wa_message_id, que se persiste enwhatsapp_messagescondirection='outbound'yto_phonecapturando el destinatario (para tracking bidireccional en Inbox / Customer 360). - El activity log del contacto y de la factura registran el envío con timestamp.
Limitaciones actuales (Fase 1, single-tenant)
- Solo Khaostozen como tenant emisor (Path A: Cloud API directo, sin Coexistence Mode todavía).
- App de Meta en Development Mode — los webhooks entrantes del cliente no llegan hasta que se complete App Review. Para probar bidireccional, agrega el número del recipient como Tester en Meta App Settings.
- Plantilla
factura_emitidadebe estar Aprobada en Meta WhatsApp Manager antes del primer envío. Si está pendiente o rechazada, el modal devuelve "Template name does not exist". - Solo plantilla
factura_emitida. Las demás (ecf_aprobado,pago_recibido,cotizacion_lista,recordatorio_t3) se habilitan progresivamente con el template selector dinámico (Oleada B).
Errores comunes
- "WhatsApp solo está disponible en modo Cloud" — el addon es cloud-only. Activa modo cloud en Settings.
- "El contacto no tiene un teléfono válido" — edita el contacto y agrega el campo teléfono. Acepta formato local DR (809-XXX-XXXX) o E.164 internacional (10-15 dígitos).
- "Template name does not exist" — la plantilla
factura_emitidano está aprobada en Meta. Verifica en WhatsApp Manager → Message templates. - "No active WhatsApp account configured" — falta el row en
whatsapp_accountsconconnection_status='active'. Revisa Settings → WhatsApp del addon. - Error 502 Graph API unreachable — Meta tuvo un fallo temporal. Reintenta. Si persiste, verifica que el
WHATSAPP_SYSTEM_USER_TOKENno haya expirado (vida útil 60 días, renueva en BM → System Users).