Descripcion General
FactuPOS genera, firma y envia documentos electronicos al Ministerio de Hacienda de Costa Rica, cumpliendo con la normativa de facturacion electronica v4.4. El sistema procesa ventas (facturas, tiquetes, notas de credito/debito, exportaciones), compras y confirmaciones de aceptacion/rechazo.
Todo el flujo se gestiona a traves de la tabla fac_bitacora en la base de datos facturacostarica, donde cada documento avanza por etapas hasta recibir respuesta de Hacienda.
Tipos de Documento
El sistema soporta los siguientes tipos de documento electronico:
| Tipo | Codigo | Nombre XML | Uso |
|---|---|---|---|
| 01 | FE | FacturaElectronica | Venta a cliente con cedula identificada |
| 02 | ND | NotaDebitoElectronica | Cargo adicional sobre factura existente |
| 03 | NC | NotaCreditoElectronica | Devolucion o correccion de factura |
| 04 | TE | TiqueteElectronico | Venta a cliente generico (sin cedula) |
| 05 | Conf | MensajeReceptor | Confirmacion de aceptacion o rechazo de compra |
| 08 | FEC | FacturaElectronicaCompra | Compra a proveedor en regimen simplificado |
| 09 | FEE | FacturaElectronicaExportacion | Venta a cliente en el extranjero |
https://cdn.comprobanteselectronicos.go.cr/xml-schemas/v4.4/ seguido del nombre del tipo en minuscula (ej: facturaElectronica).Flujo de Procesamiento
Cada documento electronico pasa por 5 etapas secuenciales. Desde el panel administrativo se controla cada paso:
Generar XML
Se crea el XML completo del documento con todos los datos: emisor, receptor, lineas de detalle, resumen de totales, impuestos y medios de pago. El XML se inserta en fac_bitacora.xml_factura con Estado 1.
Firmar
Se aplica la firma digital usando el certificado .p12 de la empresa. El XML firmado se guarda en fac_bitacora.xml_firmado con Estado 2.
Enviar a Hacienda
Se conecta al API del Ministerio de Hacienda via OAuth, obtiene un token y sube el XML firmado. La respuesta se guarda en json_respuesta_post con Estado 3.
Localizar respuesta
Se consulta al API usando la clave de 50 digitos. Hacienda responde con aceptacion (Estado 4) o rechazo (Estado 5). Si falta XML firmado o respuesta, queda en Estado 6 (revision manual).
Notificacion por email
Documentos aceptados o rechazados se encolan en dbcontrol.cola_correos para enviar XML y PDF al cliente/proveedor, copia al emisor (parametro 74), agente de ventas (parametro 318) y correo de respaldo (parametro 149).
Estados del Documento
| Estado | Nombre | Descripcion | Campo actualizado |
|---|---|---|---|
| 0 | Pendiente | Sin procesar | - |
| 1 | Generado | XML creado, sin firmar | xml_factura, clave |
| 2 | Firmado | XML firmado con certificado .p12 | xml_firmado |
| 3 | Enviado | Subido al API de Hacienda | json_respuesta_post |
| 4 | Aceptado | Hacienda aprobo el documento | xml_respuesta, mensaje_respuesta |
| 5 | Rechazado | Hacienda rechazo el documento | xml_respuesta, mensaje_respuesta |
| 6 | Revision | XML incompleto, atencion manual | - |
Estructura de la Clave (50 digitos)
Cada documento tiene una clave unica de 50 digitos que lo identifica ante Hacienda:
| Segmento | Posicion | Largo | Descripcion |
|---|---|---|---|
| 506 | 1-3 | 3 | Codigo de pais Costa Rica |
| DDMMYY | 4-9 | 6 | Fecha del documento |
| Cedula | 10-21 | 12 | Cedula del emisor (relleno ceros izquierda) |
| Consecutivo | 22-41 | 20 | Numero consecutivo completo |
| Situacion | 42 | 1 | 1 = Situacion normal |
| Seguridad | 43-50 | 8 | Codigo de seguridad (fijo 99999999) |
Estructura del Consecutivo (20 digitos)
El consecutivo identifica la sucursal, terminal, tipo y numero secuencial:
| Segmento | Posicion | Largo | Descripcion |
|---|---|---|---|
| Punto de venta | 1-3 | 3 | Codigo de punto de venta (ej: 001) |
| Terminal | 4-7 | 4 | Terminal o sucursal (ej: 0001) |
| Tipo | 8-9 | 2 | Tipo de documento (01, 02, 03, 04, 05, 08, 09) |
| Secuencial | 10-20 | 11 | Numero secuencial (autoincremental) |
substr($consecutivo, 7, 2) — posiciones 8 y 9 (base 1) o 7-8 (base 0).Generacion XML - Ventas (01, 02, 03, 04, 09)
La funcion _generarXmlVenta() construye el XML para todos los tipos de venta. Los datos provienen de:
| Dato | Fuente | Campos clave |
|---|---|---|
| Emisor | ParametrosEmpresa | Nombre (54), Cedula (66), Tipo ID (67), Ubicacion (68), Telefono (73), Email (106), Direccion (130) |
| Cabecera | vista_venta_madre | Fecha, ClienteCodigo, MonedaCodigo, MonedaTipoCambio, FormaPagoCodigo |
| Receptor | vista_cliente | Nombre, Cedula, TipoIdentificacion, Telefonos, EmailFactura, Plazo |
| Lineas | vista_venta_hija + vista_articulo | CABYS, CodigoTarifaIva, TarifaIva, IvaMonto, IvaDevuelto, NaturalezaCodigo |
| Medios pago | DocumentoDetallePago | MedioPagoCodigo, Monto (convertido a CRC si USD) |
Estructura XML de una Factura
El XML sigue esta estructura principal:
Diferencias por tipo de documento
| Elemento | 01 FE | 04 Tiquete | 09 Export | 02/03 NC/ND |
|---|---|---|---|---|
| Receptor obligatorio | Si | No | Si | Si |
| BaseImponible | Si | Si | No | Si |
| FactorCalculoIVA | Si | Si | No | Si |
| MontoExportacion | No | No | Si | No |
| ImpuestoAsumido | Si | Si | No | Si |
| InformacionReferencia | No | No | No | Si (requerido) |
Linea de Detalle
Cada linea del documento contiene: codigo CABYS, codigo comercial, cantidad, unidad de medida, detalle, precios e impuestos.
Codigos de Tarifa IVA
| Codigo | Tarifa | Descripcion |
|---|---|---|
| 01 | 0% | Tarifa 0% |
| 02 | 1% | Tarifa reducida |
| 03 | 2% | Tarifa reducida |
| 04 | 4% | Tarifa reducida bienes |
| 05 | 0% | Transitorio 0% |
| 06 | 4% | Transitorio 4% |
| 07 | 8% | Transitorio 8% |
| 08 | 13% | Tarifa general |
| 10 | - | Exento |
Bloque de Exoneracion
Si el cliente tiene exoneracion activa (tabla ClienteExoneracion), cada linea con ArticuloIvaExonerado > 0 incluye el bloque:
El IVA neto de cada linea se calcula como: Impuesto - IvaAsumido - IvaExonerado.
Generacion XML - Compras (Tipo 08)
La funcion _generarXmlCompra() genera el XML de FacturaElectronicaCompra para proveedores en regimen simplificado.
| Dato | Fuente |
|---|---|
| Emisor | CompraMadre + Proveedor (nombre, cedula, tipo identificacion) |
| Receptor | ParametrosEmpresa (la empresa que emite la FEC) |
| Lineas | VistaLineaDetalleCompra |
Siempre incluye bloque InformacionReferencia:
Notas de Credito y Debito - Referencia
Las NC (tipo 03) y ND (tipo 02) requieren obligatoriamente el bloque InformacionReferencia que apunta a la factura original.
Busqueda de la clave original (3 niveles)
Parametro referencia
Usa el campo referencia pasado al API. Busca la clave en XmlDocumentos por consecutivo + cedula empresa (parametro 66).
DocReferencia de VentaMadre
Si no se paso referencia, busca el campo DocReferencia de la venta.
Referencia de VentaMadre
Ultimo recurso: usa el campo Referencia si tiene 20+ caracteres (longitud de un consecutivo).
Tipos de referencia NC/ND
| Codigo | Descripcion |
|---|---|
| 01 | Anula documento de referencia |
| 02 | Corrige monto del documento |
| 03 | Corrige texto del documento |
| 04 | Referencia a otro documento |
| 05 | Sustituye comprobante provisional |
| 99 | Otros |
CedulaEmisor (param 66) para evitar colisiones cuando un mismo consecutivo existe como venta propia y como compra recibida de otro proveedor.Confirmaciones (MensajeReceptor - Tipo 05)
Cuando se recibe una compra electronica, el sistema genera un MensajeReceptor para confirmar la aceptacion o rechazo ante Hacienda.
Formato del consecutivo de confirmacion
<?xml version="1.0" encoding="UTF-8"?> porque causa error de parsing en Hacienda.Z (UTC), se respeta tal cual. NO se agrega -06:00 encima. Si no tiene timezone, se agrega -06:00 (Costa Rica).Procesamiento Post-Respuesta
Una vez que Hacienda responde (estado 4 o 5), el sistema ejecuta acciones segun el tipo:
Ventas aceptadas (tipos 01, 02, 03, 04, 09)
- Inserta el XML firmado y respuesta en
XmlDocumentos - Actualiza
CodRespuesta = '4'en XmlDocumentos - Encola email al cliente (si no es generico SN)
- Copia al emisor (param 74), agente (param 318), respaldo (param 149)
- Elimina registro de
fac_bitacora
Ventas rechazadas
- Mismo flujo pero con
CodRespuesta = '5' - El email incluye el motivo del rechazo de Hacienda
- Auto-nula (2026-04-20): Tras marcar
VentaMadre.Estado = 5, el sistema ejecuta automáticamente el runnerejecutarRechazadaANula()— mismo flujo que el trigger de VE-030 al abrir una factura rechazada. Borra rastro (cierre de caja, CxC, inventario, ContaDiario), encola email "RECHAZADA A NULA", imprime ESC/POS y deja el documento enEstado = 3(Nula). Idempotente: si ya está en 3, omite. - Notificación a cola 301 (2026-04-20): Envía un ticket corto a la cola de impresión
301vía WebSocket con encabezado "DOCUMENTO RECHAZADO POR HACIENDA" + tipo / número / fecha / cliente / motivo. Esto alerta al usuario del rechazo sin depender de que alguien abra VE-030 manualmente. Requiere cliente Python FactuPOS_Print con la cola 301 registrada.
Confirmaciones aceptadas (tipo 05)
- Inserta confirmacion tipo 05 en
XmlDocumentos - Actualiza
CodRespuesta = '4'en el documento original - Actualiza
CompraMadre.CompraMadreEstado = '1'(Aceptada) - Encola email al proveedor con confirmacion
Confirmaciones rechazadas (tipo 05)
- Inserta con
CodRespuesta = '5' - Actualiza
CompraMadre.CompraMadreEstado = '5'(Rechazada) - Email de notificacion con motivo del rechazo en rojo
Condicion y Medio de Pago
Condicion de venta
| Codigo | Descripcion | Regla |
|---|---|---|
| 01 | Contado | FormaPagoCodigo != '02' |
| 02 | Credito | FormaPagoCodigo = '02'. MedioPago fallback = 99 (Otros) |
Medios de pago
| Codigo | Descripcion |
|---|---|
| 01 | Efectivo |
| 02 | Tarjeta |
| 03 | Cheque |
| 04 | Transferencia / deposito bancario |
| 05 | Recaudado por terceros |
| 99 | Otros |
Tipos de Identificacion
| Codigo | Tipo | Digitos |
|---|---|---|
| 01 | Cedula fisica | 9 |
| 02 | Cedula juridica | 10 |
| 03 | DIMEX | 11-12 |
| 04 | NITE | 10 |
| 05 | Extranjero (exportacion) | Variable |
Resumen de Factura
El bloque ResumenFactura acumula los totales del documento:
| Campo XML | Descripcion |
|---|---|
| TotalServGravados | Total servicios con IVA |
| TotalServExentos | Total servicios sin IVA |
| TotalServExonerado | Total servicios exonerados |
| TotalMercanciasGravadas | Total mercancias con IVA |
| TotalMercanciasExentas | Total mercancias sin IVA |
| TotalMercExonerada | Total mercancias exoneradas |
| TotalGravado | Suma de todos los gravados |
| TotalExento | Suma de todos los exentos |
| TotalExonerado | Suma de todos los exonerados |
| TotalVenta | Gravado + Exento + Exonerado |
| TotalDescuentos | Suma de descuentos |
| TotalVentaNeta | TotalVenta - TotalDescuentos |
| TotalImpuesto | Suma de IVA de todas las lineas |
| TotalComprobante | VentaNeta + Impuesto |
TotalComprobante se redondea a entero (ej: 89224.41 se convierte en 89224.00). Util para empresas que lo requieren.Parametros de Empresa Relevantes
| Param | Descripcion | Uso en FE |
|---|---|---|
| 54 | Nombre empresa | Emisor.Nombre |
| 66 | Cedula empresa | Emisor.Identificacion.Numero |
| 67 | Tipo identificacion | Emisor.Identificacion.Tipo |
| 68 | Ubicacion (prov,canton,dist) | Emisor.Ubicacion |
| 73 | Telefono | Emisor.Telefono |
| 74 | Enviar copia al emisor | Email: 1 = Si |
| 106 | Email empresa | Emisor.CorreoElectronico + remitente emails |
| 125 | FE activa | Determina si se genera XML |
| 130 | Direccion | Emisor.Ubicacion.OtrasSenas |
| 149 | Email respaldo | Copia adicional del documento |
| 180 | Actividad economica | CodigoActividadEmisor (fallback) |
| 189 | Version FE | Actualmente 4.4 |
| 190 | Redondeo TotalComprobante | 1 = Redondear a entero |
| 249 | Moneda nacional | CodigoMoneda (ej: CRC) |
| 250 | Codigo pais | 506 (Costa Rica) |
| 318 | Copia al agente de ventas | Email: 1 = Si |
Tablas y Vistas Involucradas
Base de datos: facturacostarica
| Tabla | Uso |
|---|---|
fac_bitacora | Cola de procesamiento. Cada documento pasa por aqui hasta completar su ciclo |
fac_compania | Relacion empresa-certificado. Se busca por cedula |
Base de datos de la empresa
| Tabla / Vista | Uso |
|---|---|
XmlDocumentos | Almacena XMLs firmados y respuestas de Hacienda. CodRespuesta: 1=Pendiente, 4=Aceptado, 5=Rechazado |
VentaMadre | Cabecera de ventas (fecha, cliente, moneda, forma pago) |
vista_venta_hija | Lineas de detalle de ventas con info de articulos |
vista_cliente | Datos del receptor (nombre, cedula, email, direccion) |
CompraMadre | Cabecera de compras. Estado: 1=Aceptada, 5=Rechazada |
DocumentoDetallePago | Medios de pago del documento |
ParametrosEmpresa | Configuracion de la empresa (cedula, nombre, email, etc.) |
ClienteExoneracion | Exoneraciones activas del cliente (tipo, documento, porcentaje) |
Base de datos: dbcontrol
| Tabla | Uso |
|---|---|
cola_correos | Cola de emails pendientes de envio (XML + PDF al cliente) |
dbnegocio | Directorio de empresas (servidor, BD, cedula) |
Archivos del Sistema
Generacion de XML
| Archivo | Funcion |
|---|---|
api/hacienda/generar/generar.php | API principal POST (documento, referencia, proveedor_codigo) |
api/hacienda/generar/xml_builder.php | Constructor XML: _generarXmlVenta() y _generarXmlCompra() |
api/hacienda/generar/funciones.php | Funciones compartidas (clave, fecha, consecutivo, referencia) |
Procesamiento de respuestas
| Archivo | Funcion |
|---|---|
api/hacienda/procesar_documento.php | Orquestador: valida y distribuye segun tipo y estado |
api/hacienda/factura_venta_aceptada.php | Procesa ventas aceptadas (tipos 1,2,3,4,9) |
api/hacienda/factura_venta_rechazada.php | Procesa ventas rechazadas |
api/hacienda/factura_compra_aceptada.php | Procesa compras aceptadas (tipo 8) |
api/hacienda/factura_compra_rechazada.php | Procesa compras rechazadas |
api/hacienda/confirmacion_aceptada.php | Confirmaciones aceptadas (tipo 5) |
api/hacienda/confirmacion_rechazada.php | Confirmaciones rechazadas (tipo 5) |
Emails
| Archivo | Funcion |
|---|---|
api/hacienda/procesar_cola_correo.php | Procesa cola de correos pendientes |
api/hacienda/reenviar_confirmacion.php | Reenvia email de confirmacion al proveedor |
api/compras/reenviar_compra.php | Reenvia email de compra |
api/ventas/venta_documento_enviar_email.php | Reenvia email de venta |
Backup de XMLs
Los XMLs se respaldan automaticamente en disco para recuperacion:
/mnt/backupxml/{servidor}/{base_datos}/{anio-mes}/
Nomenclatura: FA_COMPRA_{XML|MSG}_{tipo}_{consecutivo}.txt
Errores Comunes de Hacienda
| Error | Causa | Solucion |
|---|---|---|
cvc-datatype-valid: dateTime |
Fecha con formato invalido (ej: Z-06:00 duplica timezone) |
Verificar que la fecha tenga solo un indicador de zona: Z o -06:00, nunca ambos |
| Receptor requerido | FE tipo 01 enviada sin bloque Receptor (cliente generico SN) | Tipo 01 requiere Receptor. Usar Tiquete (04) para cliente sin cedula |
| InformacionReferencia requerido | NC o ND enviada sin bloque de referencia | Verificar que exista la clave de la factura original en XmlDocumentos |
| Tarifa no es decimal | Se envia 13 en vez de 13.00 |
Formatear Tarifa y TarifaExonerada con 2 decimales |
| CorreoElectronico emisor vacio | Parametro 106 no configurado | Configurar email de empresa en Parametros |
| Clave de referencia incorrecta | Consecutivo existente como venta y como compra de otro proveedor | La busqueda ahora filtra por CedulaEmisor (param 66) |
Permisos del módulo
Los permisos controlan el acceso al módulo de documentos de Hacienda (HA-001). Se asignan al grupo de usuarios desde el módulo de Seguridad (SE-001).
| Código | Nombre | Qué autoriza | Dónde aplica |
|---|---|---|---|
660 |
Hacienda — Documentos Procesados | Acceso al módulo de documentos procesados (HA-001): ver listado, filtrar, exportar XMLs y PDFs, verificar estado en Hacienda. Sin este permiso, el módulo no aparece en el menú. | HA-001, documentos_procesados |
017 |
Administración — Certificado Digital | Permite cargar o reemplazar el certificado .p12 de firma digital en Datos de la Empresa. Requerido para el proceso de firma de XMLs. | datos_empresa, FE |
Parámetros de empresa
Los parámetros son valores globales por empresa que afectan el comportamiento del módulo de Hacienda. Se configuran desde Configuración → Parámetros (CF-004) y en Datos de la Empresa → Facturación Electrónica.
| Código | Nombre | Qué controla | Valores |
|---|---|---|---|
125 |
Facturación Electrónica activa | Habilita el envío de documentos a Hacienda. Si está en 0, el módulo registra documentos pero no los firma ni envía. | 1 = activo / 0 = inactivo |
66 |
Cédula jurídica de la empresa | Identifica al emisor en todos los XMLs enviados a Hacienda. Debe coincidir exactamente con la cédula registrada en el ATV. | Cédula (ej: 3-101-123456) |
62 |
Nombre de la empresa | Aparece como nombre del emisor en los PDFs de facturas electrónicas y en los XMLs generados. | Texto libre |
180 |
Ambiente Hacienda | Define si los documentos se envían al ambiente de pruebas (stag) o producción de Hacienda. Crítico: un valor incorrecto puede enviar facturas reales al sandbox. | stag = pruebas / prod = producción |
Interfaz del módulo (actualizada 2026-05-12)
La pantalla de Documentos Procesados (HA-001) usa el estándar visual FLAT de FactuPOS — barra de título azul marino #0047AB, encabezados de tabla gris oscuro con texto blanco, letra de datos a 16 px, esquinas suaves y alto contraste. Los cambios visibles para el usuario son:
Ver XML → ahora abre una página de detalle (HA-002)
El botón Ver XML (ícono </> en la columna de acciones) y el doble clic sobre una fila ya no abren una ventana emergente pequeña: ahora abren una página completa en una pestaña nueva con todo el detalle del documento, más grande y cómoda de leer. En esa página hay tres pestañas:
- Detalle — datos del documento: consecutivo, tipo, fecha, estado, total, emisor, receptor, mensaje de Hacienda y clave de 50 dígitos. Si es una confirmación (tipo 05), también muestra los datos del documento original confirmado.
- XML Firmado — el XML enviado a Hacienda, con sangría y letra grande (16 px). Botón Descargar XML para guardarlo como archivo
.xml. - XML Respuesta — el XML de respuesta de Hacienda (aceptación o rechazo). También se puede descargar.
Desde esa página: Descargar XML guarda el XML de la pestaña activa, Imprimir XML abre el diálogo de impresión del navegador con solo el contenido, y Volver cierra la pestaña. Atajos: Esc cierra, ← / → cambian de pestaña.
Estado como punto de color
La columna "Estado" con badge de texto se reemplazó por un punto de color al inicio de cada fila (más compacto y fácil de escanear). Los colores son:
| Color | Estado | Códigos Hacienda |
|---|---|---|
| Verde | Aceptado | 1, 4 |
| Ámbar | Pendiente | - |
| Rojo | Rechazado | 2, 5 |
La leyenda de colores se muestra permanentemente en la cinta de totales (abajo), junto al contador de documentos y los totales monetarios.
Filtros con auto-envío
Al cambiar cualquier filtro (Desde, Hasta, Grupo, Tipo, Estado, Consec, Buscar) el listado se recarga automáticamente — ya no es necesario tocar el botón "Refrescar". El botón Refrescar queda como respaldo manual.
- Selects y checkboxes: envían al instante del cambio.
- Campos de texto: envían con retardo de 350 ms tras dejar de escribir, o al presionar Enter.
- Fechas (Flatpickr): envían al elegir una fecha del calendario.
Formato de fechas
Los campos "Desde" y "Hasta" ahora muestran siempre DD/MM/YYYY (formato Costa Rica) independientemente del idioma del navegador. El sistema guarda internamente YYYY-MM-DD para la consulta SQL.
Botón Imprimir → reporte paginado (Paged.js)
Los botones separados "PDF" y "Ver" se unificaron en un único botón Imprimir. Al presionarlo:
- Abre una nueva pestaña con una vista paginada estilo revista (hojas tamaño carta apaisadas).
- La primera página lleva logo y datos de la empresa; el resto tiene encabezado compacto.
- Cada hoja numera automáticamente (
Pág. X / Y). - Desde esa vista el usuario decide imprimir en papel o guardar como PDF usando Ctrl+P del navegador.
Los colores del reporte impreso también siguen el estándar Banking Bold (encabezados en azul corporativo).
Botón Salir
El botón Salir ahora solo cierra la pestaña — no cierra la sesión. Si la pestaña no puede cerrarse (porque el navegador no lo permite), redirige al Menú Principal. Para cerrar sesión completamente, use el botón Logout del encabezado general del sistema.
Detección automática de móvil
Cuando se abre el módulo desde un teléfono o tablet (detección por User-Agent), el sistema redirige a una versión móvil optimizada (archivo documentos_procesados_movil.php) si existe. Si no hay versión móvil, se muestra el escritorio. Para forzar la vista de escritorio desde un móvil, añadir ?desktop=1 a la URL.
Impuesto de Servicio en el XML (cargo 10% restaurantes) — 2026-05-15
Las facturas y tiquetes generados desde SAC Táctil (módulo restaurante) cuando aplican el cargo de servicio del 10% ahora incluyen correctamente el bloque <OtrosCargos> en el XML enviado a Hacienda v4.4.
Qué cambió
Antes de este fix, el TotalImpuestoServicio quedaba guardado en VentaMadre pero no se reflejaba en el XML. Resultado: el TotalComprobante del XML era menor que el de la factura física por la diferencia del 10% — Hacienda recibía un monto incoherente con lo que veía el cliente.
Estructura correcta del XML (v4.4)
El bloque <OtrosCargos> se emite al nivel del documento, entre </DetalleServicio> y <ResumenFactura>. Dentro de <ResumenFactura> aparece solo el total agregado:
</DetalleServicio>
<OtrosCargos>
<TipoDocumentoOC>06</TipoDocumentoOC> <!-- 06 = Servicio o propina legal -->
<Detalle>Impuesto de Servicio</Detalle>
<PorcentajeOC>10.00</PorcentajeOC>
<MontoCargo>523.58</MontoCargo>
</OtrosCargos>
<ResumenFactura>
...
<TotalImpuesto>680.65</TotalImpuesto>
<TotalImpAsumEmisorFabrica>0.00</TotalImpAsumEmisorFabrica>
<TotalOtrosCargos>523.58</TotalOtrosCargos> <!-- suma de todos los OtrosCargos -->
<MedioPago>...</MedioPago>
<TotalComprobante>6440.00</TotalComprobante> <!-- incluye servicio -->
</ResumenFactura>
Validaciones del esquema Hacienda v4.4
- El bloque
OtrosCargosNO va dentro deResumenFactura. Si se coloca ahí, Hacienda rechaza con:Invalid content was found starting with element 'OtrosCargos'. One of '{TotalIVADevuelto, TotalOtrosCargos, MedioPago, TotalComprobante}' is expected. - El elemento se llama
<PorcentajeOC>(con "OC" al final), NO<Porcentaje>. Si se usa el nombre legacy, Hacienda rechaza con:Invalid content was found starting with element 'Porcentaje'. One of '{PorcentajeOC, MontoCargo}' is expected. - TotalComprobante debe sumar el cargo de servicio:
TotalVentaNeta + TotalImpuesto + TotalOtrosCargos − TotalIVADevuelto.
Códigos TipoDocumentoOC válidos
Para SAC restaurante se usa 06. Otros códigos válidos en v4.4: 01–05 = costos de envío/seguro/otros; 06 = Servicio o propina legal; 07–13 = aportes a planes/contribuciones; 99 = otros cargos.
Cálculo del porcentaje
El sistema calcula automáticamente el porcentaje del servicio sobre la base imponible (suma de ArticuloVentaSubTotal3 de las líneas, equivalente al total antes de IVA y servicio). Para el típico 10% sobre 5,235.77 → cargo de 523.58 → porcentaje calculado: 10.00%.
Si tengo una factura SAC vieja rechazada por este bug
- Entrar al módulo Documentos Hacienda (panel admin).
- Buscar el documento por consecutivo o clave.
- Botón Generar XML — esto borra el registro viejo de
fac_bitacoray arma un XML nuevo con el cargo de servicio. - Firmar y Enviar de nuevo a Hacienda.
Si el documento ya fue aceptado por Hacienda con el monto incorrecto (sin el servicio en el XML), no se puede regenerar — hay que emitir una Nota de Crédito que la anule y emitir una factura nueva con el cargo correcto.
Archivo modificado
/api/hacienda/generar/xml_builder.php función _generarXmlVenta() — para tipos 01 (FE), 02 (ND), 03 (NC), 04 (TE), 09 (Export).