Firmar XML
Referencia tecnica del endpoint Firmar XML.
Descripcion
Recibe un XML base sin firma, lo numera, firma y registra como CFE emitido. Es el equivalente cloud de POST /sign-cfe del módulo local: el contrato de request y response es compatible, por lo que la integración puede intercambiarse entre módulo local y API REST cambiando solo el host y la autenticación.
El proceso incluye:
- Validación de empresa, comercio y terminal
- Numeración con el CAE vigente
- Firma digital del XML
- Registro del CFE en el sistema
- Devolución inmediata de serie, número, CAE y XML firmado
Endpoint
- Metodo:
POST - Path:
/api/v1/comprobante/firmarXml
Autenticación
- JWT:
Authorization: Bearer <token>— elidEmpresase resuelve de la sesión o del body. - API Key:
Authorization: ApiKey <key>— elidEmpresase deriva automáticamente de la clave; no es necesario enviarlo en el body.
Campos de request
| Campo | Obligatoriedad | Descripción |
|---|---|---|
tipo_cfe | obligatorio | Tipo de comprobante (ej. 101, 111) |
uuid | recomendado | Identificador externo estable del comprobante |
xml | obligatorio | XML base sin firma ni numeración |
cod_comercio | condicional | Código de comercio; obligatorio si la empresa tiene más de un punto de emisión |
cod_terminal | condicional | Código de terminal; obligatorio si la empresa tiene más de un punto de emisión |
adenda | opcional | Texto adicional asociado al comprobante |
idEmpresa | condicional | Solo necesario con JWT; con API Key se ignora |
Los campos tipo_cfe, cod_comercio y cod_terminal aceptan tanto snake_case como camelCase (tipoCfe, codComercio, codTerminal) por compatibilidad.
Campos de response
Todos los campos están presentes tanto en éxito como en error. Los campos de folio y firma vienen null cuando CodigoRespuesta no es "00".
| Campo | Cuándo tiene valor | Descripción |
|---|---|---|
Uuid | siempre | UUID recibido en el request |
TipoCfe | siempre | Tipo de comprobante procesado |
Serie | éxito | Serie asignada |
Numero | éxito | Número asignado |
CodigoRespuesta | siempre | Código funcional del resultado |
MensajeRespuesta | siempre | Descripción del resultado |
CodigoTerminal | siempre | Terminal utilizada |
CodigoComercio | siempre | Comercio utilizado |
NumeroInicialCae | éxito | Inicio del rango CAE usado |
NumeroFinalCae | éxito | Fin del rango CAE usado |
VencimientoCae | éxito | Vencimiento del CAE en formato AAAAMMDD (ej. 20280101) |
NroConstanciaCae | éxito | Número de constancia del CAE |
CfeFirmado | éxito | XML final con firma digital |
DatosCodigoQr | éxito | URL o datos para generar el QR fiscal |
CodigoSeguridad | éxito | Código de seguridad fiscal |
FechaFirmaCfe | éxito | Fecha y hora de la firma |
ImagenQr | siempre | Siempre null en esta implementación |
Codigos de respuesta
| CodigoRespuesta | HTTP | Significado |
|---|---|---|
00 | 200 | Éxito. Serie y Numero vienen informados |
01 | 403 | Petición denegada (permisos insuficientes) |
03 | 422 | Comercio inválido o deshabilitado |
12 | 422 | Requerimiento inválido (campo faltante o incorrecto) |
31 | 422 | Rechazo de validación del XML |
89 | 422 | Terminal inválida o deshabilitada |
96 | 500 | Error interno (firma, persistencia o rango) |
Criterio de emisión exitosa: HTTP 200 + CodigoRespuesta = "00" + Serie y Numero no nulos. Cualquier otro resultado indica que el comprobante no fue emitido.
Escenarios de error típicos
XML con totales incorrectos
CodigoRespuesta:"31"MensajeRespuesta: incluye los motivos del rechazo del validador
Campo obligatorio faltante
CodigoRespuesta:"12"MensajeRespuesta: indica el campo ausente (ej."Se requiere xml","Se requiere tipo_cfe")
cod_comercio o cod_terminal no configurados en la empresa
- Comercio inexistente →
CodigoRespuesta:"03" - Terminal inexistente →
CodigoRespuesta:"89"
Sin permisos
CodigoRespuesta:"01"- HTTP
403
Interoperabilidad con el módulo local
Este endpoint comparte el mismo contrato que POST /sign-cfe del módulo local Tauri, con estas diferencias:
| Aspecto | Módulo local (/sign-cfe) | API REST (/comprobante/firmarXml) |
|---|---|---|
| Autenticación | Sin auth (localhost) | JWT o API Key |
idEmpresa | Derivado del perfil local | Del body (JWT) o de la API Key |
emails, impresora, send_now | Funcionales | Aceptados, ignorados |
| Nombres de campos request | snake_case | snake_case o camelCase |
| Nombres de campos response | snake_case | PascalCase |
VencimientoCae | Con guiones (2028-01-01) | Sin guiones (20280101) |