Documentos Electronicos - Hacienda AY-023

Guia completa del procesamiento de documentos electronicos con el Ministerio de Hacienda de Costa Rica

Menú Ayuda

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:

TipoCodigoNombre XMLUso
01FEFacturaElectronicaVenta a cliente con cedula identificada
02NDNotaDebitoElectronicaCargo adicional sobre factura existente
03NCNotaCreditoElectronicaDevolucion o correccion de factura
04TETiqueteElectronicoVenta a cliente generico (sin cedula)
05ConfMensajeReceptorConfirmacion de aceptacion o rechazo de compra
08FECFacturaElectronicaCompraCompra a proveedor en regimen simplificado
09FEEFacturaElectronicaExportacionVenta a cliente en el extranjero
Namespace XSD v4.4: Todos los documentos usan el namespace 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 Estado 1
Firmar Estado 2
Enviar Estado 3
Localizar Estado 4/5
Email Notificar
1

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.

2

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.

3

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.

4

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).

5

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

EstadoNombreDescripcionCampo actualizado
0PendienteSin procesar-
1GeneradoXML creado, sin firmarxml_factura, clave
2FirmadoXML firmado con certificado .p12xml_firmado
3EnviadoSubido al API de Haciendajson_respuesta_post
4AceptadoHacienda aprobo el documentoxml_respuesta, mensaje_respuesta
5RechazadoHacienda rechazo el documentoxml_respuesta, mensaje_respuesta
6RevisionXML incompleto, atencion manual-

Estructura de la Clave (50 digitos)

Cada documento tiene una clave unica de 50 digitos que lo identifica ante Hacienda:

506 170426 003101234567 00100001010000012345 1 99999999
SegmentoPosicionLargoDescripcion
5061-33Codigo de pais Costa Rica
DDMMYY4-96Fecha del documento
Cedula10-2112Cedula del emisor (relleno ceros izquierda)
Consecutivo22-4120Numero consecutivo completo
Situacion4211 = Situacion normal
Seguridad43-508Codigo de seguridad (fijo 99999999)

Estructura del Consecutivo (20 digitos)

El consecutivo identifica la sucursal, terminal, tipo y numero secuencial:

001 00001 01 0000012345
SegmentoPosicionLargoDescripcion
Punto de venta1-33Codigo de punto de venta (ej: 001)
Terminal4-74Terminal o sucursal (ej: 0001)
Tipo8-92Tipo de documento (01, 02, 03, 04, 05, 08, 09)
Secuencial10-2011Numero secuencial (autoincremental)
Para extraer el tipo de documento del consecutivo: 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:

DatoFuenteCampos clave
EmisorParametrosEmpresaNombre (54), Cedula (66), Tipo ID (67), Ubicacion (68), Telefono (73), Email (106), Direccion (130)
Cabeceravista_venta_madreFecha, ClienteCodigo, MonedaCodigo, MonedaTipoCambio, FormaPagoCodigo
Receptorvista_clienteNombre, Cedula, TipoIdentificacion, Telefonos, EmailFactura, Plazo
Lineasvista_venta_hija + vista_articuloCABYS, CodigoTarifaIva, TarifaIva, IvaMonto, IvaDevuelto, NaturalezaCodigo
Medios pagoDocumentoDetallePagoMedioPagoCodigo, Monto (convertido a CRC si USD)

Estructura XML de una Factura

El XML sigue esta estructura principal:

<FacturaElectronica xmlns="...v4.4/facturaElectronica"> <Clave>50 digitos</Clave> <CodigoActividadEmisor>000000</CodigoActividadEmisor> <NumeroConsecutivo>20 digitos</NumeroConsecutivo> <FechaEmision>2026-04-17T10:30:00</FechaEmision> <Emisor>...</Emisor> <Receptor>...</Receptor> <CondicionVenta>01</CondicionVenta> <DetalleServicio> <LineaDetalle>...</LineaDetalle> </DetalleServicio> <ResumenFactura>...</ResumenFactura> <InformacionReferencia>...</InformacionReferencia> <!-- Solo NC/ND --> </FacturaElectronica>

Diferencias por tipo de documento

Elemento01 FE04 Tiquete09 Export02/03 NC/ND
Receptor obligatorioSiNoSiSi
BaseImponibleSiSiNoSi
FactorCalculoIVASiSiNoSi
MontoExportacionNoNoSiNo
ImpuestoAsumidoSiSiNoSi
InformacionReferenciaNoNoNoSi (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

CodigoTarifaDescripcion
010%Tarifa 0%
021%Tarifa reducida
032%Tarifa reducida
044%Tarifa reducida bienes
050%Transitorio 0%
064%Transitorio 4%
078%Transitorio 8%
0813%Tarifa general
10-Exento

Bloque de Exoneracion

Si el cliente tiene exoneracion activa (tabla ClienteExoneracion), cada linea con ArticuloIvaExonerado > 0 incluye el bloque:

<Exoneracion> <TipoDocumentoEX1>01</TipoDocumentoEX1> <NumeroDocumento>AL-000000</NumeroDocumento> <NombreInstitucion>Ministerio de Hacienda</NombreInstitucion> <FechaEmisionEX>2026-01-01T00:00:00</FechaEmisionEX> <TarifaExonerada>13.00</TarifaExonerada> <MontoExoneracion>130.00</MontoExoneracion> </Exoneracion>

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.

DatoFuente
EmisorCompraMadre + Proveedor (nombre, cedula, tipo identificacion)
ReceptorParametrosEmpresa (la empresa que emite la FEC)
LineasVistaLineaDetalleCompra

Siempre incluye bloque InformacionReferencia:

<InformacionReferencia> <TipoDocIR>14</TipoDocIR> <Numero>{consecutivo}</Numero> <FechaEmisionIR>{fecha}</FechaEmisionIR> <Codigo>04</Codigo> <Razon>FACTURA COMPRA REGIMEN ESPECIAL</Razon> </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)

1

Parametro referencia

Usa el campo referencia pasado al API. Busca la clave en XmlDocumentos por consecutivo + cedula empresa (parametro 66).

2

DocReferencia de VentaMadre

Si no se paso referencia, busca el campo DocReferencia de la venta.

3

Referencia de VentaMadre

Ultimo recurso: usa el campo Referencia si tiene 20+ caracteres (longitud de un consecutivo).

Tipos de referencia NC/ND

CodigoDescripcion
01Anula documento de referencia
02Corrige monto del documento
03Corrige texto del documento
04Referencia a otro documento
05Sustituye comprobante provisional
99Otros
Filtro por cedula emisor: La busqueda de la clave original siempre filtra por 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.

<MensajeReceptor xmlns="...v4.4/mensajeReceptor"> <Clave>{clave del documento original}</Clave> <NumeroCedulaEmisor>{cedula proveedor}</NumeroCedulaEmisor> <FechaEmisionDoc>{fecha ISO8601 con timezone}</FechaEmisionDoc> <Mensaje>1</Mensaje> <!-- 1=Aceptado, 2=Aceptacion parcial, 3=Rechazado --> <DetalleMensaje>Proveedor a Empresa</DetalleMensaje> <MontoTotalImpuesto>130.00000</MontoTotalImpuesto> <TotalFactura>1130.00000</TotalFactura> <NumeroCedulaReceptor>{cedula empresa}</NumeroCedulaReceptor> <NumeroConsecutivoReceptor>{consecutivo confirmacion}</NumeroConsecutivoReceptor> </MensajeReceptor>

Formato del consecutivo de confirmacion

001 02 0001 05 0000001103
No incluir declaracion XML: El MensajeReceptor NO debe llevar <?xml version="1.0" encoding="UTF-8"?> porque causa error de parsing en Hacienda.
FechaEmisionDoc: Si la fecha del proveedor viene con 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 runner ejecutarRechazadaANula() — 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 en Estado = 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 301 ví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
Cliente generico (SN): Si el ClienteID es generico (SN, sn, 0, vacio), NO se envia email al cliente. Solo se envia al emisor, agente y respaldo.

Condicion y Medio de Pago

Condicion de venta

CodigoDescripcionRegla
01ContadoFormaPagoCodigo != '02'
02CreditoFormaPagoCodigo = '02'. MedioPago fallback = 99 (Otros)

Medios de pago

CodigoDescripcion
01Efectivo
02Tarjeta
03Cheque
04Transferencia / deposito bancario
05Recaudado por terceros
99Otros
Moneda: Si el documento es en USD, los montos de MedioPago se dividen entre el TipoCambio para reportarlos en CRC.

Tipos de Identificacion

CodigoTipoDigitos
01Cedula fisica9
02Cedula juridica10
03DIMEX11-12
04NITE10
05Extranjero (exportacion)Variable

Resumen de Factura

El bloque ResumenFactura acumula los totales del documento:

Campo XMLDescripcion
TotalServGravadosTotal servicios con IVA
TotalServExentosTotal servicios sin IVA
TotalServExoneradoTotal servicios exonerados
TotalMercanciasGravadasTotal mercancias con IVA
TotalMercanciasExentasTotal mercancias sin IVA
TotalMercExoneradaTotal mercancias exoneradas
TotalGravadoSuma de todos los gravados
TotalExentoSuma de todos los exentos
TotalExoneradoSuma de todos los exonerados
TotalVentaGravado + Exento + Exonerado
TotalDescuentosSuma de descuentos
TotalVentaNetaTotalVenta - TotalDescuentos
TotalImpuestoSuma de IVA de todas las lineas
TotalComprobanteVentaNeta + Impuesto
Parametro 190 - Redondeo: Si el parametro 190 = 1, el TotalComprobante se redondea a entero (ej: 89224.41 se convierte en 89224.00). Util para empresas que lo requieren.

Parametros de Empresa Relevantes

ParamDescripcionUso en FE
54Nombre empresaEmisor.Nombre
66Cedula empresaEmisor.Identificacion.Numero
67Tipo identificacionEmisor.Identificacion.Tipo
68Ubicacion (prov,canton,dist)Emisor.Ubicacion
73TelefonoEmisor.Telefono
74Enviar copia al emisorEmail: 1 = Si
106Email empresaEmisor.CorreoElectronico + remitente emails
125FE activaDetermina si se genera XML
130DireccionEmisor.Ubicacion.OtrasSenas
149Email respaldoCopia adicional del documento
180Actividad economicaCodigoActividadEmisor (fallback)
189Version FEActualmente 4.4
190Redondeo TotalComprobante1 = Redondear a entero
249Moneda nacionalCodigoMoneda (ej: CRC)
250Codigo pais506 (Costa Rica)
318Copia al agente de ventasEmail: 1 = Si

Tablas y Vistas Involucradas

Base de datos: facturacostarica

TablaUso
fac_bitacoraCola de procesamiento. Cada documento pasa por aqui hasta completar su ciclo
fac_companiaRelacion empresa-certificado. Se busca por cedula

Base de datos de la empresa

Tabla / VistaUso
XmlDocumentosAlmacena XMLs firmados y respuestas de Hacienda. CodRespuesta: 1=Pendiente, 4=Aceptado, 5=Rechazado
VentaMadreCabecera de ventas (fecha, cliente, moneda, forma pago)
vista_venta_hijaLineas de detalle de ventas con info de articulos
vista_clienteDatos del receptor (nombre, cedula, email, direccion)
CompraMadreCabecera de compras. Estado: 1=Aceptada, 5=Rechazada
DocumentoDetallePagoMedios de pago del documento
ParametrosEmpresaConfiguracion de la empresa (cedula, nombre, email, etc.)
ClienteExoneracionExoneraciones activas del cliente (tipo, documento, porcentaje)

Base de datos: dbcontrol

TablaUso
cola_correosCola de emails pendientes de envio (XML + PDF al cliente)
dbnegocioDirectorio de empresas (servidor, BD, cedula)

Archivos del Sistema

Generacion de XML

ArchivoFuncion
api/hacienda/generar/generar.phpAPI principal POST (documento, referencia, proveedor_codigo)
api/hacienda/generar/xml_builder.phpConstructor XML: _generarXmlVenta() y _generarXmlCompra()
api/hacienda/generar/funciones.phpFunciones compartidas (clave, fecha, consecutivo, referencia)

Procesamiento de respuestas

ArchivoFuncion
api/hacienda/procesar_documento.phpOrquestador: valida y distribuye segun tipo y estado
api/hacienda/factura_venta_aceptada.phpProcesa ventas aceptadas (tipos 1,2,3,4,9)
api/hacienda/factura_venta_rechazada.phpProcesa ventas rechazadas
api/hacienda/factura_compra_aceptada.phpProcesa compras aceptadas (tipo 8)
api/hacienda/factura_compra_rechazada.phpProcesa compras rechazadas
api/hacienda/confirmacion_aceptada.phpConfirmaciones aceptadas (tipo 5)
api/hacienda/confirmacion_rechazada.phpConfirmaciones rechazadas (tipo 5)

Emails

ArchivoFuncion
api/hacienda/procesar_cola_correo.phpProcesa cola de correos pendientes
api/hacienda/reenviar_confirmacion.phpReenvia email de confirmacion al proveedor
api/compras/reenviar_compra.phpReenvia email de compra
api/ventas/venta_documento_enviar_email.phpReenvia 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

Si un XML no se encuentra en la base de datos, el sistema busca automaticamente en el backup antes de reportar error.

Errores Comunes de Hacienda

ErrorCausaSolucion
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ódigoNombreQué autorizaDó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
Sin permiso 660: módulo no visible en menú El módulo Hacienda → Docs procesados y Hacienda → D104 solo aparecen en el menú para usuarios con permiso 660.

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ódigoNombreQué controlaValores
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:

ColorEstadoCódigos Hacienda
VerdeAceptado1, 4
ÁmbarPendiente-
RojoRechazado2, 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:

  1. Abre una nueva pestaña con una vista paginada estilo revista (hojas tamaño carta apaisadas).
  2. La primera página lleva logo y datos de la empresa; el resto tiene encabezado compacto.
  3. Cada hoja numera automáticamente (Pág. X / Y).
  4. 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 OtrosCargos NO va dentro de ResumenFactura. 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

  1. Entrar al módulo Documentos Hacienda (panel admin).
  2. Buscar el documento por consecutivo o clave.
  3. Botón Generar XML — esto borra el registro viejo de fac_bitacora y arma un XML nuevo con el cargo de servicio.
  4. 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).