Documentation
¶
Overview ¶
Package cfdi lee CFDI 3.3 y 4.0 (facturas electrónicas del SAT, México) y los normaliza a structs Go y a un JSON con esquema versionado.
Lectura tolerante: Parse solo falla (con un *Error de Clase estable) si el documento no es XML o si la raíz no es un Comprobante de los namespaces http://www.sat.gob.mx/cfd/3 o /cfd/4. Lo demás —encodings que mienten, atributos con formato raro, complementos desconocidos, falta de timbre— se lee como se pueda y se reporta en Comprobante.Advertencias con códigos estables (las constantes Adv*).
Montos: decimal.Decimal exacto, nunca float; en JSON van como string con el texto original del XML.
Leer no valida: eso es aparte y sobre los bytes o el Comprobante ya leído. CadenaOriginal y Verificar arman la cadena y verifican los sellos; ValidarEsquema valida contra los XSD del SAT (el CFDI, el timbre y los complementos que lista el README), ValidarReglas revisa las reglas aritméticas y de coherencia, y Validar junta las dos. Cada regla de Reglas cita su fundamento en la matriz de errores, el estándar o la guía de llenado del SAT (Regla.Citas). Nada consulta al SAT ni usa la red.
El CFDI de Retenciones e información de pagos (1.0 y 2.0) tiene su propia API: Detectar dice qué es un XML, ParseRetenciones lo lee (con su JSON y su SchemaRetenciones), CadenaOriginalRetenciones y VerificarRetenciones arman la cadena y verifican los sellos, y ValidarRetenciones lo valida contra los XSD. Parse sigue rechazando una Retenciones (no_es_comprobante).
c, err := cfdi.Parse(f)
if err != nil { ... } // no es un CFDI
for _, a := range c.Advertencias { ... }
b, _ := c.JSON() // {"schema_version":"1","cfdi":{...},"advertencias":[...]}
Index ¶
- Constants
- Variables
- func CadenaOriginal(xml []byte) (string, error)
- func CadenaOriginalRetenciones(xml []byte) (string, error)
- func CadenaOriginalTFD(xml []byte) (string, error)
- func ClaseDe(err error) string
- func EstadoDe(hs []Hallazgo) string
- func NoCertificado(c *x509.Certificate) string
- func RFCDelCertificado(c *x509.Certificate) string
- func TieneHallazgo(hs []Hallazgo, codigo string) bool
- type ACuentaTerceros
- type AccionesOTitulos
- type AcreditamientoIEPS
- type Advertencia
- type Aerolineas
- type AerolineasCargo
- type AerolineasOtrosCargos
- type AportacionesODepositos
- type Arrendamientoenfideicomiso
- type Autotransporte
- type AutotransporteFederal
- type BeneficiarioExtranjero
- type CFDIRegistroFiscal
- type CantidadTransporta
- type Carro
- type CartaPorte
- type CartaPorte10Arrendatario
- type CartaPorte10Destino
- type CartaPorte10FiguraTransporte
- type CartaPorte10Notificado
- type CartaPorte10Operador
- type CartaPorte10Origen
- type CartaPorte10Propietario
- type CartaPorteMercancia
- type CartaPorteMercancias
- type CertificadoDeDestruccion
- type CertificadoDestruccionInfoAduanera
- type CertificadoDestruccionVehiculo
- type CertificadosSAT
- type CfdiRelacionado
- type CfdiRelacionados
- type CfdiRetenRelacionados
- type ChequeosCertificado
- type CitaSAT
- type ComercioExterior
- type ComercioExteriorDestinatario
- type ComercioExteriorEmisor
- type ComercioExteriorMercancia
- type ComercioExteriorPropietario
- type ComercioExteriorReceptor
- type ComisionDelServicio
- type CompensacionSaldosAFavor
- type Comprobante
- func (c *Comprobante) AdvertenciaEn(rutaNodo, atributo string) (Advertencia, bool)
- func (c *Comprobante) AdvertenciasDe(rutaNodo string) []Advertencia
- func (c *Comprobante) Complementos() []string
- func (c *Comprobante) Documento(o OpcionesJSON) Documento
- func (c *Comprobante) JSON() ([]byte, error)
- func (c *Comprobante) JSONOpciones(o OpcionesJSON) ([]byte, error)
- func (c *Comprobante) TieneAdvertencia(codigo string) bool
- func (c *Comprobante) UUID() string
- type Concepto
- type ConceptoConsumoDeCombustibles
- type ConceptoEstadoDeCuentaCombustible
- type ConsumoDeCombustibles
- type ConsumoDeCombustiblesDeterminado
- type ContenedorFerroviario
- type ContenedorMaritimo
- type ContribucionGubernamental
- type CuentaPredial
- type DeduccOSalidas
- type Deduccion
- type Deducciones
- type DerechosDePaso
- type DescripcionesEspecificas
- type DetalleMercancia
- type DetallesDelServicio
- type DividOUtil
- type Dividendos
- type Divisas
- type DoctoRelacionado
- type DocumentacionAduanera
- type Documento
- type DocumentoRetenciones
- type Domicilio
- type Donatarias
- type ECBMovimiento
- type ECBMovimientoFiscal
- type ECBMovimientos
- type Emisor
- type EmisorRetenciones
- type EnajenaciondeAcciones
- type EntidadSNCF
- type Error
- type ErrorCadena
- type EstadoDeCuentaBancario
- type EstadoDeCuentaCombustible
- type Fecha
- type Fideicomisonoempresarial
- type GastosHidrocarburos
- type GastosHidrocarburosActividades
- type GastosHidrocarburosCentroCostos
- type GastosHidrocarburosDocumentoRelacionado
- type GastosHidrocarburosErogacion
- type GastosHidrocarburosPozos
- type GastosHidrocarburosSubActividades
- type GastosHidrocarburosTareas
- type GastosHidrocarburosYacimientos
- type GuiasIdentificacion
- type Hallazgo
- type HidroYPetro
- type HorasExtra
- type INE
- type INEContabilidad
- type INEEntidad
- type IdentificacionVehicular
- type ImpRetenidos
- type Impuesto
- type ImpuestoDR
- type ImpuestoP
- type ImpuestoTerceros
- type Impuestos
- type ImpuestosConcepto
- type ImpuestosDR
- type ImpuestosLocales
- type ImpuestosP
- type ImpuestosTerceros
- type ImpuestosTrasladadosdelServicio
- type Incapacidad
- type InformacionAduanera
- type InformacionAduaneraComplemento
- type InformacionGlobal
- type IngresosHidrocarburos
- type IngresosHidrocarburosDocumentoRelacionado
- type IngresosOEntradas
- type InstEducativas
- type Intereses
- type Intereseshipotecarios
- type JubilacionPensionRetiro
- type Leyenda
- type LeyendasFiscales
- type NoBeneficiarioExtranjero
- type Nomina
- type NominaEmisor
- type NominaReceptor
- type NotariosPublicos
- type NotariosPublicosDatosAdquiriente
- type NotariosPublicosDatosCopropietario
- type NotariosPublicosDatosEnajenante
- type NotariosPublicosDatosNotario
- type NotariosPublicosDatosOperacion
- type NotariosPublicosDatosPersona
- type NotariosPublicosDescInmueble
- type ObrasArteAntiguedades
- type Opciones
- type OpcionesJSON
- type Operacionesconderivados
- type OtroPago
- type PFintegranteCoordinado
- type Pago
- type PagoEnEspecie
- type Pagos
- type Pagosaextranjeros
- type ParcialesConstruccion
- type ParcialesConstruccionInmueble
- type Parte
- type ParteComplemento
- type PartesTransporte
- type Pedimentos
- type Percepcion
- type Percepciones
- type PeriodoRetenciones
- type Planesderetiro
- type PorCuentadeTerceros
- type Premios
- type Receptor
- type ReceptorExtranjeroRetenciones
- type ReceptorNacionalRetenciones
- type ReceptorRetenciones
- type RegimenAduaneroCCP
- type Regla
- type Remanente
- type Remolque
- type RemolqueCCP
- type RenovacionDecretoRenovVehicular
- type RenovacionDecretoSustitVehicular
- type RenovacionVehiculoNuevo
- type RenovacionVehiculoUsado
- type RenovacionySustitucionVehiculos
- type ResultadoChequeo
- type ResultadoSello
- type ResultadoValidacion
- type RetEfectFideicomiso
- type Retenciones
- func (rt *Retenciones) AdvertenciaEn(rutaNodo, atributo string) (Advertencia, bool)
- func (rt *Retenciones) Complementos() []string
- func (rt *Retenciones) Documento(o OpcionesJSON) DocumentoRetenciones
- func (rt *Retenciones) JSON() ([]byte, error)
- func (rt *Retenciones) JSONOpciones(o OpcionesJSON) ([]byte, error)
- func (rt *Retenciones) TieneAdvertencia(codigo string) bool
- func (rt *Retenciones) UUID() string
- type RetencionesLocales
- type SPEIBeneficiario
- type SPEIOrdenante
- type SPEITercero
- type SectorFinanciero
- type Seguros
- type SeparacionIndemnizacion
- type ServiciosPlataformasTecnologicas
- type SubContratacion
- type SubsidioAlEmpleo
- type TimbreFiscalDigital
- type TipoDocumento
- type TiposFigura
- type TotalesPagos
- type TotalesRetenciones
- type TransporteAereo
- type TransporteFerroviario
- type TransporteMaritimo
- type TrasladosLocales
- type TuristaPasajeroExtranjero
- type TuristaPasajeroExtranjeroDatosTransito
- type Ubicacion
- type UbicacionFiscal
- type ValesDeDespensa
- type ValesDeDespensaConcepto
- type Validacion
- type VehiculoUsado
- type VentaVehiculos
- type Verificacion
Examples ¶
Constants ¶
const ( // Codificación y forma del XML. AdvEncodingCorregido = "ENCODING_CORREGIDO" // los bytes no coinciden con el encoding declarado; se convirtieron AdvEncodingDesconocido = "ENCODING_DESCONOCIDO" // encoding declarado que no se reconoce; se leyó como UTF-8 o windows-1252 AdvCaracterInvalido = "CARACTER_INVALIDO" // caracteres de control prohibidos en XML 1.0; se quitaron AdvXMLNoEstricto = "XML_NO_ESTRICTO" // el XML solo se pudo leer en modo no estricto (entidades o & sueltos) AdvContenidoTrasRaiz = "CONTENIDO_TRAS_RAIZ" // texto o basura después del cierre de cfdi:Comprobante; se ignoró // Estructura. AdvVersionNoSoportada = "VERSION_NO_SOPORTADA" // Version que no es 3.0, 3.2, 3.3 ni 4.0 AdvVersionAntigua = "VERSION_ANTIGUA" // CFDI 3.0 o 3.2: lectura parcial, solo lo que coincide con 3.3 AdvVersionNamespace = "VERSION_NAMESPACE" // Version no corresponde al namespace (p. ej. 3.3 en cfd/4) AdvNamespaceInesperado = "NAMESPACE_INESPERADO" // nodo con el nombre esperado pero en otro namespace; se leyó AdvNodoFaltante = "NODO_FALTANTE" // falta un nodo requerido (Emisor, Receptor, Conceptos…) AdvNodoDuplicado = "NODO_DUPLICADO" // nodo que debe ser único aparece varias veces; se usa el primero AdvAtributoFaltante = "ATRIBUTO_FALTANTE" // falta un atributo requerido AdvSinTimbre = "SIN_TIMBRE" // no hay TimbreFiscalDigital AdvComplementoNoSoportado = "COMPLEMENTO_NO_SOPORTADO" AdvComplementoVersion = "COMPLEMENTO_VERSION" // versión de complemento desconocida o que no corresponde a su namespace // Valores. AdvDecimalInvalido = "DECIMAL_INVALIDO" // monto o cantidad que no es xs:decimal; el campo queda vacío AdvFechaInvalida = "FECHA_INVALIDA" // fecha ilegible; queda solo el texto original AdvFechaFormato = "FECHA_FORMATO" // fecha legible pero fuera del formato SAT (zona, fracción, sin hora…) AdvUUIDInvalido = "UUID_INVALIDO" // UUID que no tiene la forma 8-4-4-4-12 hexadecimal AdvExentoConImporte = "EXENTO_CON_IMPORTE" // traslado Exento con TasaOCuota o Importe; se conservan, pero no deberían venir )
Códigos de advertencia. Son parte de la API pública: no se renombran.
const ( MotivoXMLIlegible = "XML_ILEGIBLE" // XML que un procesador XSLT no leería igual (mal formado, encoding que miente, caracteres prohibidos) MotivoNoEsComprobante = "NO_ES_COMPROBANTE" // la raíz no es un Comprobante cfd/3 o cfd/4 MotivoVersionNoSoportada = "VERSION_NO_SOPORTADA" // versión del CFDI o del TFD sin hoja de cadena (p. ej. 3.0) MotivoComplementoSinCadena = "COMPLEMENTO_SIN_CADENA" // complemento que la librería no sabe llevar a la cadena MotivoSinTimbre = "SIN_TIMBRE" // no hay TimbreFiscalDigital )
Motivos por los que no se puede armar una cadena original. Son estables, como los códigos de advertencia, y son también motivos de un sello NO_VERIFICABLE (ver Verificar).
const ( ChequeoCumple = "cumple" // el documento y el certificado coinciden ChequeoNoCumple = "no_cumple" // no coinciden ChequeoNoVerificable = "no_verificable" // falta un dato para decidir )
Estados de un chequeo del certificado.
const ( MotivoCertificadoNoVigenteAun = "CERTIFICADO_NO_VIGENTE_AUN" // no cumple: la fecha es anterior a NotBefore MotivoCertificadoVencido = "CERTIFICADO_VENCIDO" // no cumple: la fecha es posterior a NotAfter MotivoVigenciaAmbigua = "VIGENCIA_AMBIGUA" // no verificable: la fecha sin zona cae a menos de la diferencia de husos del límite MotivoFechaIlegible = "FECHA_ILEGIBLE" // no verificable: no hay fecha o no se puede leer MotivoRFCCertificadoDistinto = "RFC_CERTIFICADO_DISTINTO" // no cumple: el RFC del certificado no es el del emisor MotivoCertificadoSinRFC = "CERTIFICADO_SIN_RFC" // no verificable: el certificado no trae x500UniqueIdentifier MotivoSinRFCEmisor = "SIN_RFC_EMISOR" // no verificable: el documento no trae el RFC del emisor MotivoSinNoCertificado = "SIN_NOCERTIFICADO" // no cumple: el documento no trae NoCertificado MotivoCertificadoDelSAT = "CERTIFICADO_DEL_SAT" // cumple: el titular del certificado es el SAT, que sella a nombre del emisor )
Motivos de los chequeos del certificado, además de MotivoSinCertificado, MotivoCertificadoIlegible y MotivoXMLIlegible (no verificable). Son estables.
const ( ClaseNoEsXML = "no_es_xml" // no hay un elemento raíz legible ClaseXMLMalFormado = "xml_mal_formado" // empieza como XML pero se rompe (truncado, etiquetas cruzadas) ClaseNoEsComprobante = "no_es_comprobante" // la raíz no es Comprobante de cfd/3 o cfd/4 ClaseNoEsRetenciones = "no_es_retenciones" // ParseRetenciones: la raíz no es Retenciones de retencionpago/1 o /2 ClaseLectura = "lectura" // falló la lectura del io.Reader )
Clases de error fatal. Son estables: el modo lote agrupa por ellas.
const ( EsquemaXMLIlegible = "ESQUEMA_XML_ILEGIBLE" // un procesador XML conforme no lo leería (mal formado, encoding que miente…) EsquemaNoSoportado = "ESQUEMA_NO_SOPORTADO" // aviso: raíz o complemento sin esquema en la librería; esa parte no se validó EsquemaElementoNoPermitido = "ESQUEMA_ELEMENTO_NO_PERMITIDO" // elemento que el esquema no admite en ese lugar EsquemaElementoFaltante = "ESQUEMA_ELEMENTO_FALTANTE" // falta un elemento requerido (minOccurs) EsquemaElementoExcedente = "ESQUEMA_ELEMENTO_EXCEDENTE" // un elemento se repite más de lo que permite maxOccurs EsquemaOrden = "ESQUEMA_ORDEN" // elemento fuera del orden de la secuencia EsquemaContenido = "ESQUEMA_CONTENIDO" // texto donde el esquema no admite texto EsquemaAtributoFaltante = "ESQUEMA_ATRIBUTO_FALTANTE" // falta un atributo requerido EsquemaAtributoNoPermitido = "ESQUEMA_ATRIBUTO_NO_PERMITIDO" // atributo que el esquema no declara EsquemaTipo = "ESQUEMA_TIPO" // valor que no es del tipo XSD (decimal, fecha, entero…) EsquemaPatron = "ESQUEMA_PATRON" // valor que no cumple el pattern EsquemaCatalogo = "ESQUEMA_CATALOGO" // valor fuera del catálogo (enumeration) EsquemaRango = "ESQUEMA_RANGO" // valor fuera de minInclusive/maxInclusive EsquemaDigitos = "ESQUEMA_DIGITOS" // más decimales (fractionDigits) o dígitos (totalDigits) de los permitidos EsquemaLongitud = "ESQUEMA_LONGITUD" // longitud fuera de length/minLength/maxLength EsquemaValorFijo = "ESQUEMA_VALOR_FIJO" // valor distinto del fixed del esquema )
Códigos de hallazgo de ValidarEsquema. Son parte de la API pública: no se renombran.
const ( NivelError = "error" NivelAdvertencia = "advertencia" NivelAviso = "aviso" )
Niveles de un Hallazgo.
const ( ValidacionValida = "valido" // sin errores ni avisos (puede traer advertencias) ValidacionInvalida = "invalido" // al menos un hallazgo de nivel error ValidacionIncompleta = "incompleto" // sin errores, pero con partes que no se pudieron validar (avisos) )
Estados de ResultadoValidacion.
const ( NSCFDI33 = "http://www.sat.gob.mx/cfd/3" NSCFDI40 = "http://www.sat.gob.mx/cfd/4" NSTimbre = "http://www.sat.gob.mx/TimbreFiscalDigital" NSPagos10 = "http://www.sat.gob.mx/Pagos" NSPagos20 = "http://www.sat.gob.mx/Pagos20" NSNomina11 = "http://www.sat.gob.mx/nomina" NSNomina12 = "http://www.sat.gob.mx/nomina12" NSImpLocal = "http://www.sat.gob.mx/implocal" NSCartaPorte10 = "http://www.sat.gob.mx/CartaPorte" NSCartaPorte20 = "http://www.sat.gob.mx/CartaPorte20" NSCartaPorte30 = "http://www.sat.gob.mx/CartaPorte30" NSCartaPorte31 = "http://www.sat.gob.mx/CartaPorte31" NSComercioExterior10 = "http://www.sat.gob.mx/ComercioExterior" NSComercioExterior11 = "http://www.sat.gob.mx/ComercioExterior11" NSComercioExterior20 = "http://www.sat.gob.mx/ComercioExterior20" NSDivisas = "http://www.sat.gob.mx/divisas" NSRegistroFiscal = "http://www.sat.gob.mx/registrofiscal" NSLeyendasFiscales = "http://www.sat.gob.mx/leyendasFiscales" NSEstadoDeCuentaCombustible11 = "http://www.sat.gob.mx/EstadoDeCuentaCombustible" NSEstadoDeCuentaCombustible12 = "http://www.sat.gob.mx/EstadoDeCuentaCombustible12" NSHidroYPetro = "http://www.sat.gob.mx/hidrocarburospetroliferos" NSTerceros = "http://www.sat.gob.mx/terceros" NSVentaVehiculos = "http://www.sat.gob.mx/ventavehiculos" NSAerolineas = "http://www.sat.gob.mx/aerolineas" NSDonatarias = "http://www.sat.gob.mx/donat" NSIEDU = "http://www.sat.gob.mx/iedu" NSINE = "http://www.sat.gob.mx/ine" NSValesDeDespensa = "http://www.sat.gob.mx/valesdedespensa" NSConsumoDeCombustibles10 = "http://www.sat.gob.mx/consumodecombustibles" NSConsumoDeCombustibles11 = "http://www.sat.gob.mx/ConsumoDeCombustibles11" NSPagoEnEspecie = "http://www.sat.gob.mx/pagoenespecie" NSNotariosPublicos = "http://www.sat.gob.mx/notariospublicos" NSServicioParcialConstruccion = "http://www.sat.gob.mx/servicioparcialconstruccion" NSVehiculoUsado = "http://www.sat.gob.mx/vehiculousado" NSTuristaPasajeroExtranjero = "http://www.sat.gob.mx/TuristaPasajeroExtranjero" NSAcreditamientoIEPS = "http://www.sat.gob.mx/acreditamiento" NSSPEI = "http://www.sat.gob.mx/spei" NSRenovacionVehiculos = "http://www.sat.gob.mx/renovacionysustitucionvehiculos" NSCertificadoDestruccion = "http://www.sat.gob.mx/certificadodestruccion" NSObrasArteAntiguedades = "http://www.sat.gob.mx/arteantiguedades" NSPFIC = "http://www.sat.gob.mx/pfic" NSGastosHidrocarburos = "http://www.sat.gob.mx/GastosHidrocarburos10" NSIngresosHidrocarburos = "http://www.sat.gob.mx/IngresosHidrocarburos10" NSEstadoDeCuentaBancario = "http://www.sat.gob.mx/ecb" NSEstadoDeCuentaCombustible10 = "http://www.sat.gob.mx/ecc" )
Namespaces del SAT que reconoce la librería.
const ( ReglaVersionNoSoportada = "REGLA_VERSION_NO_SOPORTADA" // aviso: versión sin reglas (3.2, 3.0…) ReglaImporteConcepto = "REGLA_IMPORTE_CONCEPTO" ReglaDescuentoConcepto = "REGLA_DESCUENTO_CONCEPTO" ReglaImporteImpuesto = "REGLA_IMPORTE_IMPUESTO" ReglaExentoConImporte = "REGLA_EXENTO_CON_IMPORTE" ReglaTasaSinImporte = "REGLA_TASA_SIN_IMPORTE" ReglaRetencionExenta = "REGLA_RETENCION_EXENTA" ReglaObjetoImp = "REGLA_OBJETO_IMP" ReglaSubTotal = "REGLA_SUBTOTAL" ReglaDescuento = "REGLA_DESCUENTO" ReglaDescuentoMayor = "REGLA_DESCUENTO_MAYOR_SUBTOTAL" ReglaTotal = "REGLA_TOTAL" ReglaTotalTraslados = "REGLA_TOTAL_TRASLADOS" ReglaTotalRetenciones = "REGLA_TOTAL_RETENCIONES" ReglaImpuestosSinTotal = "REGLA_IMPUESTOS_SIN_TOTAL" ReglaTrasladoSuma = "REGLA_TRASLADO_SUMA" ReglaTrasladoFaltante = "REGLA_TRASLADO_FALTANTE" ReglaTrasladoSobrante = "REGLA_TRASLADO_SOBRANTE" ReglaRetencionSuma = "REGLA_RETENCION_SUMA" ReglaRetencionFaltante = "REGLA_RETENCION_FALTANTE" ReglaRetencionSobrante = "REGLA_RETENCION_SOBRANTE" ReglaImpLocalTotales = "REGLA_IMPLOCAL_TOTALES" ReglaDecimalesMoneda = "REGLA_DECIMALES_MONEDA" ReglaDecimalesImpuesto = "REGLA_DECIMALES_IMPUESTO" ReglaDecimalesImpuesto33 = "REGLA_DECIMALES_IMPUESTO_33" ReglaTipoCambioMXN = "REGLA_TIPOCAMBIO_MXN" ReglaTipoCambioXXX = "REGLA_TIPOCAMBIO_XXX" ReglaTipoCambioRequerido = "REGLA_TIPOCAMBIO_REQUERIDO" ReglaTipoCompCondiciones = "REGLA_TIPOCOMP_CONDICIONES" ReglaTipoCompImpuestos = "REGLA_TIPOCOMP_IMPUESTOS" ReglaTipoCompFormaPago = "REGLA_TIPOCOMP_FORMAPAGO" ReglaTipoCompMetodoPago = "REGLA_TIPOCOMP_METODOPAGO" ReglaTipoCompDescuento = "REGLA_TIPOCOMP_DESCUENTO" ReglaTipoCompSubTotalCero = "REGLA_TIPOCOMP_SUBTOTAL_CERO" ReglaTipoCompTotalCero = "REGLA_TIPOCOMP_TOTAL_CERO" ReglaTipoCompValorUnitario = "REGLA_TIPOCOMP_VALOR_UNITARIO" ReglaTipoCompMonedaNomina = "REGLA_TIPOCOMP_MONEDA_NOMINA" ReglaPagoComprobante = "REGLA_PAGO_COMPROBANTE" ReglaPagoSaldoInsoluto = "REGLA_PAGO_SALDO_INSOLUTO" ReglaPagoEquivalencia = "REGLA_PAGO_EQUIVALENCIA" ReglaPagoTipoCambioDR = "REGLA_PAGO_TIPOCAMBIODR" ReglaPagoMonto = "REGLA_PAGO_MONTO" ReglaPagoTipoCambio = "REGLA_PAGO_TIPOCAMBIO" ReglaPagosTotales = "REGLA_PAGOS_TOTALES" ReglaPagoMonedaXXX = "REGLA_PAGO_MONEDA_XXX" ReglaPagoMayorCero = "REGLA_PAGO_MAYOR_CERO" ReglaPagoDecimales = "REGLA_PAGO_DECIMALES" ReglaPagoFormaPago = "REGLA_PAGO_FORMAPAGO" ReglaPagoCuentas = "REGLA_PAGO_CUENTAS" ReglaPagoCadena = "REGLA_PAGO_CADENA" ReglaPago10Parcialidades = "REGLA_PAGO10_PARCIALIDADES" ReglaPago10Impuestos = "REGLA_PAGO10_IMPUESTOS" )
Códigos de hallazgo de ValidarReglas. Son parte de la API pública: no se renombran. La referencia de cada uno (de dónde sale la regla) está en Reglas.
const ( DocMatriz40 = "Matriz de errores CFDI 4.0 (2026-03-25)" DocEstandar40 = "Anexo 20 CFDI 4.0 (DOF 2022-01-13)" DocGuia40 = "Guía de llenado CFDI 4.0 (2026-01-16)" DocMatriz33 = "Matriz de errores CFDI 3.3" DocEstandar33 = "Anexo 20 CFDI 3.3 (DOF 2017-07-28)" DocGuia33 = "Guía de llenado CFDI 3.3 (2019-10-14)" DocMatrizPagos20 = "Matriz de errores Pagos 2.0 Rev B" DocGuiaPagos20 = "Guía de llenado Pagos 2.0 (2026-01-16)" DocEstPagos20 = "Estándar Pagos 2.0 Rev B" DocMatrizPagos10 = "Matriz de errores Pagos 1.0" DocGuiaPagos10 = "Guía de llenado Pagos 1.0 (2018-08-31)" DocImpLocal = "Estándar ImpuestosLocales" )
Documentos oficiales del SAT que citan las reglas.
const ( ReglaCCEExportacion = "REGLA_CCE_EXPORTACION" ReglaCCENodosCFDI = "REGLA_CCE_NODOS_CFDI" ReglaCCEMotivoTraslado = "REGLA_CCE_MOTIVO_TRASLADO" ReglaCCETraslado = "REGLA_CCE_TRASLADO" ReglaCCEEmisor = "REGLA_CCE_EMISOR" ReglaCCENumRegIdTrib = "REGLA_CCE_NUMREGIDTRIB" ReglaCCEFraccion = "REGLA_CCE_FRACCION" ReglaCCEValorImporte = "REGLA_CCE_VALOR_IMPORTE" ReglaCCEMuestras = "REGLA_CCE_MUESTRAS" )
Reglas de presencia y coherencia de Comercio Exterior 2.0 (matriz CCE 2.0, CCE102-172) que se pueden comprobar sin catálogos externos: lo que pide c_Pais (Unión Europea, patrones de NumRegIdTrib y de código postal), c_Estado, c_Municipio, c_Localidad, c_Colonia, c_CodigoPostal, c_FraccionArancelaria (vigencia y UMT), la lista de RFC y el tipo de cambio publicado queda fuera (ver el README).
const ( ReglaCCETipoComprobante = "REGLA_CCE_TIPOCOMPROBANTE" ReglaCCECertificado = "REGLA_CCE_CERTIFICADO" ReglaCCETotalUSD = "REGLA_CCE_TOTALUSD" ReglaCCENoIdentificacion = "REGLA_CCE_NOIDENTIFICACION" ReglaCCEDatosAduana = "REGLA_CCE_DATOS_ADUANA" ReglaCCEValorDolares = "REGLA_CCE_VALOR_DOLARES" ReglaNominaTotales = "REGLA_NOMINA_TOTALES" ReglaNominaPercepciones = "REGLA_NOMINA_PERCEPCIONES" ReglaNominaDeducciones = "REGLA_NOMINA_DEDUCCIONES" ReglaNominaImportes = "REGLA_NOMINA_IMPORTES" ReglaNominaConcepto = "REGLA_NOMINA_CONCEPTO" ReglaNominaFechas = "REGLA_NOMINA_FECHAS" ReglaNominaSubContratacion = "REGLA_NOMINA_SUBCONTRATACION" ReglaNominaOtrosPagos = "REGLA_NOMINA_OTROS_PAGOS" )
Códigos de las reglas de Comercio Exterior 2.0 y Nómina 1.2.
const ( DocMatrizCCE20 = "Matriz de errores Comercio Exterior 2.0" DocGuiaCCE20 = "Guía de llenado Comercio Exterior 2.0" DocMatrizNomina12 = "Matriz de errores Nómina 1.2 Rev D (2025-02-21)" DocGuiaNomina12 = "Guía de llenado Nómina 1.2" // DocMatrizNomina12B es la matriz de la Rev B (publicada el // 2019-12-17), la primera que trae lo que agregó la Rev B del estándar; // fija su vigencia (ver Regla.Vigencia). DocMatrizNomina12C es la de la // Rev C, con la numeración actual de esos códigos. DocMatrizNomina12B = "Matriz de errores Nómina 1.2 Rev B (2019-12-17)" DocMatrizNomina12C = "Matriz de errores Nómina 1.2 Rev C (2021-12-29)" // DocEstNomina12 es el estándar del complemento; sus páginas son las // del PDF (no las imprime). Su control de cambios (p. 56-57) dice qué // agregó cada revisión. DocEstNomina12 = "Estándar Nómina 1.2 Rev D (2025-02-21)" )
Documentos del SAT de los complementos.
const ( ReglaNominaComprobante = "REGLA_NOMINA_COMPROBANTE" ReglaNominaPeriodicidad = "REGLA_NOMINA_PERIODICIDAD" ReglaNominaRegistroPatronal = "REGLA_NOMINA_REGISTRO_PATRONAL" ReglaNominaEntidadSNCF = "REGLA_NOMINA_ENTIDAD_SNCF" ReglaNominaAntiguedad = "REGLA_NOMINA_ANTIGUEDAD" ReglaNominaTipoRegimen = "REGLA_NOMINA_TIPO_REGIMEN" ReglaNominaCuentaBancaria = "REGLA_NOMINA_CUENTA_BANCARIA" ReglaNominaNodosPercepcion = "REGLA_NOMINA_NODOS_PERCEPCION" ReglaNominaIncapacidades = "REGLA_NOMINA_INCAPACIDADES" ReglaNominaCompensacionSaldo = "REGLA_NOMINA_COMPENSACION_SALDO" )
Reglas de Nómina 1.2 que llegaron en T8 (matriz Rev D, NOM3-29 del comprobante y NOM31-106 del complemento): presencia de nodos por tipo de percepción, deducción y otro pago, relación laboral, cuenta bancaria y el CFDI de nómina 4.0. Lo que necesita la lista de RFC, la marca del SNCF o los topes del subsidio vigentes queda fuera (ver el README).
const ( ReglaPagoObjetoImpDR = "REGLA_PAGO_OBJETO_IMP_DR" ReglaPagoImpuestoDR = "REGLA_PAGO_IMPUESTO_DR" ReglaPagoImporteDR = "REGLA_PAGO_IMPORTE_DR" ReglaPagoImpuestosP = "REGLA_PAGO_IMPUESTOS_P" ReglaPagoImpuestosPSuma = "REGLA_PAGO_IMPUESTOS_P_SUMA" )
Reglas de los impuestos de Pagos 2.0: los ImpuestosDR de cada documento relacionado y los ImpuestosP de cada pago (matriz de Pagos 2.0 Rev B, CRP20246-20279; estándar Rev B p. 61-66).
const ( NSRetenciones10 = "http://www.sat.gob.mx/esquemas/retencionpago/1" NSRetenciones20 = "http://www.sat.gob.mx/esquemas/retencionpago/2" NSRetPlataformasTecnologicas10 = "http://www.sat.gob.mx/esquemas/retencionpago/1/PlataformasTecnologicas10" NSRetIntereses = "http://www.sat.gob.mx/esquemas/retencionpago/1/intereses" NSRetPagosAExtranjeros = "http://www.sat.gob.mx/esquemas/retencionpago/1/pagosaextranjeros" NSRetDividendos = "http://www.sat.gob.mx/esquemas/retencionpago/1/dividendos" NSRetEnajenacionDeAcciones = "http://www.sat.gob.mx/esquemas/retencionpago/1/enajenaciondeacciones" NSRetArrendamientoEnFideicomiso = "http://www.sat.gob.mx/esquemas/retencionpago/1/arrendamientoenfideicomiso" NSRetOperacionesConDerivados = "http://www.sat.gob.mx/esquemas/retencionpago/1/operacionesconderivados" NSRetInteresesHipotecarios = "http://www.sat.gob.mx/esquemas/retencionpago/1/intereseshipotecarios" NSRetFideicomisoNoEmpresarial = "http://www.sat.gob.mx/esquemas/retencionpago/1/fideicomisonoempresarial" NSRetPlanesDeRetiro10 = "http://www.sat.gob.mx/esquemas/retencionpago/1/planesderetiro" NSRetPlanesDeRetiro11 = "http://www.sat.gob.mx/esquemas/retencionpago/1/planesderetiro11" NSRetPremios = "http://www.sat.gob.mx/esquemas/retencionpago/1/premios" NSRetSectorFinanciero = "http://www.sat.gob.mx/esquemas/retencionpago/1/sectorfinanciero" )
Namespaces del CFDI de Retenciones e información de pagos y de sus complementos.
const ( SelloValido = "valido" // la firma corresponde a la cadena y al certificado SelloInvalido = "invalido" // el documento dice algo que su sello no respalda SelloNoVerificable = "no_verificable" // no se pudo decidir (cadena no garantizable, certificado ilegible o ausente…) )
Estado del resultado de verificar un sello.
const ( MotivoSinSello = "SIN_SELLO" // inválido: no hay Sello (o SelloSAT) MotivoSelloIlegible = "SELLO_ILEGIBLE" // inválido: el sello no es base64 MotivoSelloNoCoincide = "SELLO_NO_COINCIDE" // inválido: la firma no es de esa cadena con esa llave MotivoNoCertificadoDistinto = "NOCERTIFICADO_DISTINTO" // inválido: NoCertificado no es el número del certificado MotivoSelloCFDDistinto = "SELLO_CFD_DISTINTO" // inválido: el SelloCFD del TFD no es el Sello del comprobante MotivoSinCertificado = "SIN_CERTIFICADO" // no verificable: no viene el Certificado MotivoCertificadoIlegible = "CERTIFICADO_ILEGIBLE" // no verificable: no es base64 de un X.509 DER MotivoLlaveNoRSA = "LLAVE_NO_RSA" // no verificable: el certificado no trae llave RSA MotivoCertificadoSATFaltante = "CERTIFICADO_SAT_NO_DISPONIBLE" // no verificable: el proveedor no dio el certificado del SAT MotivoNoCertificadoSATDistinto = "NOCERTIFICADO_SAT_DISTINTO" // no verificable: el proveedor dio otro certificado )
Motivos de un resultado de sello, además de los de ErrorCadena (que dan SelloNoVerificable). Son estables.
const DocEstCCE20 = "Estándar Comercio Exterior 2.0"
DocEstCCE20 es el estándar del complemento; sus páginas son las del PDF (no las imprime).
const MotivoNoEsRetenciones = "NO_ES_RETENCIONES"
MotivoNoEsRetenciones es el motivo de CadenaOriginalRetenciones (y de un sello no verificable de VerificarRetenciones) cuando la raíz no es un Retenciones de retencionpago/1 o retencionpago/2.
const SchemaVersion = "1"
SchemaVersion es la versión del formato JSON. Sube cuando un cambio deja de ser compatible (renombrar o quitar una clave, cambiar un tipo); agregar claves opcionales no la sube.
const SchemaVersionRetenciones = "1"
SchemaVersionRetenciones es la versión del formato JSON de Retenciones (schema/retenciones.v1.schema.json). Sube por su cuenta, como SchemaVersion la del CFDI.
Variables ¶
var Codigos = []string{ AdvEncodingCorregido, AdvEncodingDesconocido, AdvCaracterInvalido, AdvXMLNoEstricto, AdvContenidoTrasRaiz, AdvVersionNoSoportada, AdvVersionAntigua, AdvVersionNamespace, AdvNamespaceInesperado, AdvNodoFaltante, AdvNodoDuplicado, AdvAtributoFaltante, AdvSinTimbre, AdvComplementoNoSoportado, AdvComplementoVersion, AdvDecimalInvalido, AdvFechaInvalida, AdvFechaFormato, AdvUUIDInvalido, AdvExentoConImporte, }
Codigos lista todos los códigos de advertencia, en el orden de arriba.
var CodigosEsquema = []string{ EsquemaXMLIlegible, EsquemaNoSoportado, EsquemaElementoNoPermitido, EsquemaElementoFaltante, EsquemaElementoExcedente, EsquemaOrden, EsquemaContenido, EsquemaAtributoFaltante, EsquemaAtributoNoPermitido, EsquemaTipo, EsquemaPatron, EsquemaCatalogo, EsquemaRango, EsquemaDigitos, EsquemaLongitud, EsquemaValorFijo, }
CodigosEsquema lista los códigos de ValidarEsquema, en el orden de arriba.
var CodigosReglas = func() []string { out := make([]string, len(Reglas)) for i, r := range Reglas { out[i] = r.Codigo } return out }()
CodigosReglas lista los códigos de ValidarReglas, en el orden de Reglas.
var ErrCertificadoNoEncontrado = errors.New("certificado no encontrado")
ErrCertificadoNoEncontrado lo devuelve el proveedor de CertificadosEn.
var Motivos = []string{ MotivoXMLIlegible, MotivoNoEsComprobante, MotivoNoEsRetenciones, MotivoVersionNoSoportada, MotivoComplementoSinCadena, MotivoSinTimbre, MotivoSinSello, MotivoSelloIlegible, MotivoSelloNoCoincide, MotivoNoCertificadoDistinto, MotivoSelloCFDDistinto, MotivoSinCertificado, MotivoCertificadoIlegible, MotivoLlaveNoRSA, MotivoCertificadoSATFaltante, MotivoNoCertificadoSATDistinto, }
Motivos lista todos los motivos de cadena y de sello, en el orden de arriba.
var MotivosCertificado = []string{ MotivoCertificadoNoVigenteAun, MotivoCertificadoVencido, MotivoVigenciaAmbigua, MotivoFechaIlegible, MotivoRFCCertificadoDistinto, MotivoCertificadoSinRFC, MotivoSinRFCEmisor, MotivoSinNoCertificado, MotivoCertificadoDelSAT, MotivoNoCertificadoDistinto, MotivoSinCertificado, MotivoCertificadoIlegible, MotivoXMLIlegible, }
MotivosCertificado lista los motivos que pueden salir en ChequeosCertificado, en el orden de arriba y luego los compartidos.
var Reglas = concatenar(reglasCFDI, reglasPagos, reglasPagosImpuestos, reglasComplementos, reglasCCE, reglasNomina)
Reglas lista las reglas que evalúa ValidarReglas, en el orden de los códigos. Cada una con su fundamento en los documentos del SAT (T7: se contrastaron todas contra la matriz de errores, el estándar y la guía de llenado de cada versión; lo que no coincidía se corrigió).
var Schema []byte
Schema es el JSON Schema (draft 2020-12) del Documento: el mismo archivo que schema/cfdi.v1.schema.json, embebido para quien quiera validar o publicar la salida.
var SchemaRetenciones []byte
SchemaRetenciones es el JSON Schema del DocumentoRetenciones: schema/retenciones.v1.schema.json.
Functions ¶
func CadenaOriginal ¶
CadenaOriginal arma la cadena original del comprobante (CFDI 3.2, 3.3 o 4.0) tal como la arman los XSLT del SAT: el orden y los atributos los fijan esas hojas (traducidas a Go en cadena_reglas.go), los nodos que se repiten van en el orden del documento y cada valor pasa por normalize-space.
Trabaja sobre los bytes y no sobre el Comprobante porque la cadena depende del documento tal cual (atributos vacíos, espacios, nodos en otro namespace) y no de lo que el modelo normaliza. Devuelve *ErrorCadena si el XML no es estrictamente válido, si la versión no tiene hoja o si trae un complemento que la librería no sabe llevar a la cadena: en ese caso el SAT lo incluiría y una cadena sin él saldría mal.
Tampoco arma la cadena (MotivoXMLIlegible) si los bytes no son del encoding que declaran o traen caracteres prohibidos en XML: Parse los lee corrigiéndolos, pero un procesador XSLT los rechazaría o leería otros caracteres, y no hay forma de saber cuáles firmó el emisor.
Example ¶
package main
import (
"fmt"
"log"
"github.com/OrtaMarco/cfdi-go"
)
// Una factura 4.0 mínima, sin sello ni timbre, con el RFC de prueba del SAT.
const facturaEjemplo = `<?xml version="1.0" encoding="UTF-8"?>
<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/4" Version="4.0" Serie="A" Folio="1"
Fecha="2026-01-15T10:30:00" Sello="" NoCertificado="30001000000500003416" Certificado=""
SubTotal="100.00" Moneda="MXN" Total="116.00" TipoDeComprobante="I" Exportacion="01"
MetodoPago="PUE" FormaPago="03" LugarExpedicion="20000">
<cfdi:Emisor Rfc="EKU9003173C9" Nombre="ESCUELA KEMPER URGATE" RegimenFiscal="601"/>
<cfdi:Receptor Rfc="XAXX010101000" Nombre="PUBLICO EN GENERAL" DomicilioFiscalReceptor="20000"
RegimenFiscalReceptor="616" UsoCFDI="S01"/>
<cfdi:Conceptos>
<cfdi:Concepto ClaveProdServ="01010101" Cantidad="1" ClaveUnidad="H87" Descripcion="Artículo"
ValorUnitario="100.00" Importe="100.00" ObjetoImp="02">
<cfdi:Impuestos>
<cfdi:Traslados>
<cfdi:Traslado Base="100.00" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="16.00"/>
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Concepto>
</cfdi:Conceptos>
<cfdi:Impuestos TotalImpuestosTrasladados="16.00">
<cfdi:Traslados>
<cfdi:Traslado Base="100.00" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="16.00"/>
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Comprobante>`
func main() {
cadena, err := cfdi.CadenaOriginal([]byte(facturaEjemplo))
if err != nil {
log.Fatal(err)
}
fmt.Println(cadena[:40] + "…")
}
Output: ||4.0|A|1|2026-01-15T10:30:00|03|3000100…
func CadenaOriginalRetenciones ¶
CadenaOriginalRetenciones arma la cadena original de un CFDI de Retenciones e información de pagos 1.0 o 2.0, como CadenaOriginal la del CFDI: con las hojas retenciones.xslt del SAT (traducidas en cadena_reglas.go), que incluyen los trece complementos de la 1.0 (ServiciosPlataformasTecnologicas, Intereses, Pagosaextranjeros, Dividendos, EnajenaciondeAcciones, Arrendamientoenfideicomiso, Operacionesconderivados, Intereseshipotecarios, Fideicomisonoempresarial, Planesderetiro 1.0 y 1.1, Premios y SectorFinanciero). La hoja 2.0 no incluye Planesderetiro 1.0. Cualquier otro complemento, o uno que la hoja de esa versión no incluye, da *ErrorCadena con COMPLEMENTO_SIN_CADENA.
La cadena del TimbreFiscalDigital de una Retenciones la arma CadenaOriginalTFD, igual que la de un CFDI.
func CadenaOriginalTFD ¶
CadenaOriginalTFD arma la cadena original del TimbreFiscalDigital (1.0 o 1.1) del CFDI, que es lo que firma el SelloSAT.
func EstadoDe ¶
EstadoDe resume una lista de hallazgos en uno de los Validacion*. Solo los errores hacen inválido un documento; las advertencias no cambian el estado.
func NoCertificado ¶
func NoCertificado(c *x509.Certificate) string
NoCertificado es el número de certificado en el formato del SAT: el número de serie del certificado, cuyos bytes son los dígitos en ASCII (serie 0x3330303031… → "30001…"). Si los bytes no son ASCII imprimible (un certificado que no es del SAT), devuelve la serie en hexadecimal.
func RFCDelCertificado ¶
func RFCDelCertificado(c *x509.Certificate) string
RFCDelCertificado devuelve el RFC del titular de un certificado del SAT: el x500UniqueIdentifier (OID 2.5.4.45) del sujeto, que en una persona moral trae "RFC / RFC del representante" (cuenta el primero). "" si no lo trae.
func TieneHallazgo ¶
TieneHallazgo dice si hay al menos un hallazgo con ese código.
Types ¶
type ACuentaTerceros ¶
type ACuentaTerceros struct {
RfcACuentaTerceros string `json:"rfc_a_cuenta_terceros,omitempty"`
NombreACuentaTerceros string `json:"nombre_a_cuenta_terceros,omitempty"`
RegimenFiscalACuentaTerceros string `json:"regimen_fiscal_a_cuenta_terceros,omitempty"`
DomicilioFiscalACuentaTerceros string `json:"domicilio_fiscal_a_cuenta_terceros,omitempty"`
}
ACuentaTerceros es el nodo cfdi:ACuentaTerceros de un concepto (CFDI 4.0).
type AccionesOTitulos ¶
type AccionesOTitulos struct {
ValorMercado *decimal.Decimal `json:"valor_mercado,omitempty"`
PrecioAlOtorgarse *decimal.Decimal `json:"precio_al_otorgarse,omitempty"`
}
AccionesOTitulos es el nodo nomina12:AccionesOTitulos de una Percepcion del complemento Nómina.
type AcreditamientoIEPS ¶
type AcreditamientoIEPS struct {
Version string `json:"version,omitempty"`
TAR string `json:"tar,omitempty"`
}
AcreditamientoIEPS 1.0 (acreditamiento, nodo acreditamientoIEPS), complemento de concepto: TAR de la enajenación de combustible.
type Advertencia ¶
type Advertencia struct {
Codigo string `json:"codigo"`
Ruta string `json:"ruta,omitempty"`
Mensaje string `json:"mensaje,omitempty"`
// Atributo es el nombre del atributo de la advertencia ("" si es de un
// nodo o del documento). Es lo que va después de "/@" en Ruta.
Atributo string `json:"atributo,omitempty"`
// Valor es el texto original del atributo, tal como venía, en las
// advertencias de valores: DECIMAL_INVALIDO (el campo quedó vacío y este
// es el único lugar con el texto), FECHA_INVALIDA, FECHA_FORMATO y
// UUID_INVALIDO. En el JSON se omite si es "".
Valor string `json:"valor,omitempty"`
}
Advertencia describe algo raro que se encontró al leer un CFDI sin que impida leerlo. Codigo es estable entre versiones (sirve para agrupar en lote); Ruta señala el nodo o atributo; Mensaje es para personas y puede cambiar.
Formato de Ruta (contrato estable) ¶
Ruta es una ruta de nodos por nombre local, sin prefijos de namespace, desde la raíz: "/Comprobante/Conceptos/Concepto[2]/Impuestos/Traslados/Traslado[1]". Si la advertencia es de un atributo, termina en "/@Nombre" y Atributo lleva ese Nombre; Nodo() devuelve la ruta sin él.
- Los nodos que el esquema permite repetir llevan su posición, desde 1, entre corchetes y siempre, también el primero: Concepto[1], CfdiRelacionados[1], Pago[1], Traslado[1]…
- Los nodos únicos (Emisor, Impuestos, Totales…) van sin índice. Si un nodo único viene repetido, la ruta es la del primero.
- Excepción: Complemento y los complementos que se acumulan (Nomina, HidroYPetro) van sin índice el primero y con [n] desde el segundo ("/Comprobante/Complemento/Nomina", ".../Nomina[2]").
- Las advertencias del documento entero (encoding, XML no estricto, contenido tras la raíz) van con Ruta "".
El nombre del atributo es el que pide el SAT ("Version", "UUID"), aunque el documento lo traiga en minúsculas (TFD 1.0, CFDI 3.2).
func (Advertencia) Nodo ¶
func (a Advertencia) Nodo() string
Nodo es la ruta del nodo de la advertencia: Ruta sin el "/@Atributo" final.
type Aerolineas ¶
type Aerolineas struct {
Version string `json:"version,omitempty"`
TUA *decimal.Decimal `json:"tua,omitempty"`
OtrosCargos *AerolineasOtrosCargos `json:"otros_cargos,omitempty"`
}
Aerolineas 1.0: TUA y otros cargos del boleto de avión.
type AerolineasCargo ¶
type AerolineasCargo struct {
CodigoCargo string `json:"codigo_cargo,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
}
AerolineasCargo es el nodo aerolineas:Cargo de OtrosCargos del complemento Aerolíneas.
type AerolineasOtrosCargos ¶
type AerolineasOtrosCargos struct {
TotalCargos *decimal.Decimal `json:"total_cargos,omitempty"`
Cargo []AerolineasCargo `json:"cargo,omitempty"`
}
AerolineasOtrosCargos es el nodo aerolineas:OtrosCargos del complemento Aerolíneas.
type AportacionesODepositos ¶
type AportacionesODepositos struct {
TipoAportacionODeposito string `json:"tipo_aportacion_o_deposito,omitempty"`
MontAportODep *decimal.Decimal `json:"mont_aport_o_dep,omitempty"`
RFCFiduciaria string `json:"rfc_fiduciaria,omitempty"`
}
AportacionesODepositos es el nodo planesderetiro11:AportacionesODepositos del complemento de Retenciones PlanesDeRetiro 1.1.
type Arrendamientoenfideicomiso ¶
type Arrendamientoenfideicomiso struct {
Version string `json:"version,omitempty"`
PagProvEfecPorFiduc *decimal.Decimal `json:"pag_prov_efec_por_fiduc,omitempty"`
RendimFideicom *decimal.Decimal `json:"rendim_fideicom,omitempty"`
DeduccCorresp *decimal.Decimal `json:"deducc_corresp,omitempty"`
MontTotRet *decimal.Decimal `json:"mont_tot_ret,omitempty"`
MontResFiscDistFibras *decimal.Decimal `json:"mont_res_fisc_dist_fibras,omitempty"`
MontOtrosConceptDistr *decimal.Decimal `json:"mont_otros_concept_distr,omitempty"`
DescrMontOtrosConceptDistr string `json:"descr_mont_otros_concept_distr,omitempty"`
}
Arrendamientoenfideicomiso es el complemento de Retenciones arrendamientoenfideicomiso:Arrendamientoenfideicomiso.
type Autotransporte ¶
type Autotransporte struct {
PermSCT string `json:"perm_sct,omitempty"`
NumPermisoSCT string `json:"num_permiso_sct,omitempty"`
IdentificacionVehicular *IdentificacionVehicular `json:"identificacion_vehicular,omitempty"`
Seguros *Seguros `json:"seguros,omitempty"`
Remolques []Remolque `json:"remolques,omitempty"`
}
Autotransporte es el nodo Autotransporte del complemento CartaPorte (2.0 y 3.x).
type AutotransporteFederal ¶
type AutotransporteFederal struct {
PermSCT string `json:"perm_sct,omitempty"`
NumPermisoSCT string `json:"num_permiso_sct,omitempty"`
NombreAseg string `json:"nombre_aseg,omitempty"`
NumPolizaSeguro string `json:"num_poliza_seguro,omitempty"`
IdentificacionVehicular *IdentificacionVehicular `json:"identificacion_vehicular,omitempty"`
Remolques []Remolque `json:"remolques,omitempty"`
}
AutotransporteFederal es el autotransporte de CartaPorte 1.0: los seguros van en atributos (en 2.0, nodo Seguros).
type BeneficiarioExtranjero ¶
type BeneficiarioExtranjero struct {
RFC string `json:"rfc,omitempty"`
CURP string `json:"curp,omitempty"`
NomDenRazSocB string `json:"nom_den_raz_soc_b,omitempty"`
ConceptoPago string `json:"concepto_pago,omitempty"`
DescripcionConcepto string `json:"descripcion_concepto,omitempty"`
}
BeneficiarioExtranjero es el nodo pagosaextranjeros:Beneficiario del complemento Pagosaextranjeros.
type CFDIRegistroFiscal ¶
type CFDIRegistroFiscal struct {
Version string `json:"version,omitempty"`
Folio string `json:"folio,omitempty"`
}
CFDIRegistroFiscal 1.0 (registrofiscal).
type CantidadTransporta ¶
type CantidadTransporta struct {
Cantidad *decimal.Decimal `json:"cantidad,omitempty"`
IDOrigen string `json:"id_origen,omitempty"`
IDDestino string `json:"id_destino,omitempty"`
CvesTransporte string `json:"cves_transporte,omitempty"`
}
CantidadTransporta es el nodo CantidadTransporta de una Mercancia del complemento CartaPorte.
type Carro ¶
type Carro struct {
TipoCarro string `json:"tipo_carro,omitempty"`
MatriculaCarro string `json:"matricula_carro,omitempty"`
GuiaCarro string `json:"guia_carro,omitempty"`
ToneladasNetasCarro *decimal.Decimal `json:"toneladas_netas_carro,omitempty"`
Contenedor []ContenedorFerroviario `json:"contenedor,omitempty"`
}
Carro es el nodo Carro del TransporteFerroviario del complemento CartaPorte.
type CartaPorte ¶
type CartaPorte struct {
Version string `json:"version,omitempty"`
IdCCP string `json:"id_ccp,omitempty"`
TranspInternac string `json:"transp_internac,omitempty"`
RegimenAduanero string `json:"regimen_aduanero,omitempty"` // 3.0
EntradaSalidaMerc string `json:"entrada_salida_merc,omitempty"`
PaisOrigenDestino string `json:"pais_origen_destino,omitempty"`
ViaEntradaSalida string `json:"via_entrada_salida,omitempty"`
TotalDistRec *decimal.Decimal `json:"total_dist_rec,omitempty"`
RegistroISTMO string `json:"registro_istmo,omitempty"`
UbicacionPoloOrigen string `json:"ubicacion_polo_origen,omitempty"`
UbicacionPoloDestino string `json:"ubicacion_polo_destino,omitempty"`
RegimenesAduaneros []RegimenAduaneroCCP `json:"regimenes_aduaneros,omitempty"` // 3.1
Ubicaciones []Ubicacion `json:"ubicaciones,omitempty"`
Mercancias *CartaPorteMercancias `json:"mercancias,omitempty"`
FiguraTransporte []TiposFigura `json:"figura_transporte,omitempty"`
FiguraTransporte10 *CartaPorte10FiguraTransporte `json:"figura_transporte10,omitempty"` // 1.0
}
CartaPorte 2.0, 3.0 y 3.1 normalizadas en un solo struct: los XSD solo agregan, quitan o mueven nodos y atributos, sin cambiar el tipo de ninguno que compartan, así que la unión no pierde datos. Version dice cuál era y lo exclusivo de una versión queda vacío en las otras:
- 2.0: Mercancia.Pedimentos, TransporteMaritimo.NumCertITC.
- 3.0 y 3.1: IdCCP, RegistroISTMO, UbicacionPoloOrigen/Destino, Mercancia.DocumentacionAduanera y los datos de COFEPRIS de Mercancia, IdentificacionVehicular.PesoBrutoVehicular, TransporteMaritimo.Puntal y PermisoTempNavegacion, los datos CCP de los contenedores marítimos.
- 3.0: RegimenAduanero (atributo) y TransporteMaritimo.RemolquesCCP.
- 3.1: RegimenesAduaneros (lista) y Contenedor.RemolquesCCP (los remolques pasaron del transporte marítimo a cada contenedor).
CartaPorte 1.0 (namespace .../CartaPorte) entra en el mismo struct con lo que comparte (Ubicacion con su Domicilio, Mercancia, CantidadTransporta, DetalleMercancia, TransporteMaritimo, TransporteAereo, TransporteFerroviario) y campos propios para lo que 2.0 cambió de forma: Ubicacion.Origen y Destino, Mercancias.AutotransporteFederal y FiguraTransporte10 (en 1.0 FiguraTransporte es un nodo con CveTransporte y sus Operadores, Propietario, Arrendatario y Notificado, y no cabe en la lista de TiposFigura de 2.0).
type CartaPorte10Arrendatario ¶
type CartaPorte10Arrendatario struct {
RFCArrendatario string `json:"rfc_arrendatario,omitempty"`
NombreArrendatario string `json:"nombre_arrendatario,omitempty"`
NumRegIdTribArrendatario string `json:"num_reg_id_trib_arrendatario,omitempty"`
ResidenciaFiscalArrendatario string `json:"residencia_fiscal_arrendatario,omitempty"`
Domicilio *Domicilio `json:"domicilio,omitempty"`
}
CartaPorte10Arrendatario es el nodo Arrendatario de la FiguraTransporte de CartaPorte 1.0.
type CartaPorte10Destino ¶
type CartaPorte10Destino struct {
IDDestino string `json:"id_destino,omitempty"`
RFCDestinatario string `json:"rfc_destinatario,omitempty"`
NombreDestinatario string `json:"nombre_destinatario,omitempty"`
NumRegIdTrib string `json:"num_reg_id_trib,omitempty"`
ResidenciaFiscal string `json:"residencia_fiscal,omitempty"`
NumEstacion string `json:"num_estacion,omitempty"`
NombreEstacion string `json:"nombre_estacion,omitempty"`
FechaHoraProgLlegada Fecha `json:"fecha_hora_prog_llegada,omitzero"`
}
CartaPorte10Destino es el nodo Destino de una Ubicacion de CartaPorte 1.0.
type CartaPorte10FiguraTransporte ¶
type CartaPorte10FiguraTransporte struct {
CveTransporte string `json:"cve_transporte,omitempty"`
Operadores []CartaPorte10Operador `json:"operadores,omitempty"`
Propietario []CartaPorte10Propietario `json:"propietario,omitempty"`
Arrendatario []CartaPorte10Arrendatario `json:"arrendatario,omitempty"`
Notificado []CartaPorte10Notificado `json:"notificado,omitempty"`
}
CartaPorte10FiguraTransporte es la FiguraTransporte de 1.0. Operadores puede repetirse y no tiene atributos: sus Operador van en una sola lista, en orden de documento.
type CartaPorte10Notificado ¶
type CartaPorte10Notificado struct {
RFCNotificado string `json:"rfc_notificado,omitempty"`
NombreNotificado string `json:"nombre_notificado,omitempty"`
NumRegIdTribNotificado string `json:"num_reg_id_trib_notificado,omitempty"`
ResidenciaFiscalNotificado string `json:"residencia_fiscal_notificado,omitempty"`
Domicilio *Domicilio `json:"domicilio,omitempty"`
}
CartaPorte10Notificado es el nodo Notificado de la FiguraTransporte de CartaPorte 1.0.
type CartaPorte10Operador ¶
type CartaPorte10Operador struct {
RFCOperador string `json:"rfc_operador,omitempty"`
NumLicencia string `json:"num_licencia,omitempty"`
NombreOperador string `json:"nombre_operador,omitempty"`
NumRegIdTribOperador string `json:"num_reg_id_trib_operador,omitempty"`
ResidenciaFiscalOperador string `json:"residencia_fiscal_operador,omitempty"`
Domicilio *Domicilio `json:"domicilio,omitempty"`
}
CartaPorte10Operador es el nodo Operador de la FiguraTransporte de CartaPorte 1.0.
type CartaPorte10Origen ¶
type CartaPorte10Origen struct {
IDOrigen string `json:"id_origen,omitempty"`
RFCRemitente string `json:"rfc_remitente,omitempty"`
NombreRemitente string `json:"nombre_remitente,omitempty"`
NumRegIdTrib string `json:"num_reg_id_trib,omitempty"`
ResidenciaFiscal string `json:"residencia_fiscal,omitempty"`
NumEstacion string `json:"num_estacion,omitempty"`
NombreEstacion string `json:"nombre_estacion,omitempty"`
FechaHoraSalida Fecha `json:"fecha_hora_salida,omitzero"`
}
CartaPorte10Origen y CartaPorte10Destino son los nodos Origen y Destino de la Ubicacion de CartaPorte 1.0 (2.0 los juntó en atributos de Ubicacion).
type CartaPorte10Propietario ¶
type CartaPorte10Propietario struct {
RFCPropietario string `json:"rfc_propietario,omitempty"`
NombrePropietario string `json:"nombre_propietario,omitempty"`
NumRegIdTribPropietario string `json:"num_reg_id_trib_propietario,omitempty"`
ResidenciaFiscalPropietario string `json:"residencia_fiscal_propietario,omitempty"`
Domicilio *Domicilio `json:"domicilio,omitempty"`
}
CartaPorte10Propietario es el nodo Propietario de la FiguraTransporte de CartaPorte 1.0.
type CartaPorteMercancia ¶
type CartaPorteMercancia struct {
BienesTransp string `json:"bienes_transp,omitempty"`
ClaveSTCC string `json:"clave_stcc,omitempty"`
Descripcion string `json:"descripcion,omitempty"`
Cantidad *decimal.Decimal `json:"cantidad,omitempty"`
ClaveUnidad string `json:"clave_unidad,omitempty"`
Unidad string `json:"unidad,omitempty"`
Dimensiones string `json:"dimensiones,omitempty"`
MaterialPeligroso string `json:"material_peligroso,omitempty"`
CveMaterialPeligroso string `json:"cve_material_peligroso,omitempty"`
Embalaje string `json:"embalaje,omitempty"`
DescripEmbalaje string `json:"descrip_embalaje,omitempty"`
SectorCOFEPRIS string `json:"sector_cofepris,omitempty"`
NombreIngredienteActivo string `json:"nombre_ingrediente_activo,omitempty"`
NomQuimico string `json:"nom_quimico,omitempty"`
DenominacionGenericaProd string `json:"denominacion_generica_prod,omitempty"`
DenominacionDistintivaProd string `json:"denominacion_distintiva_prod,omitempty"`
Fabricante string `json:"fabricante,omitempty"`
FechaCaducidad Fecha `json:"fecha_caducidad,omitzero"`
LoteMedicamento string `json:"lote_medicamento,omitempty"`
FormaFarmaceutica string `json:"forma_farmaceutica,omitempty"`
CondicionesEspTransp string `json:"condiciones_esp_transp,omitempty"`
RegistroSanitarioFolioAutorizacion string `json:"registro_sanitario_folio_autorizacion,omitempty"`
PermisoImportacion string `json:"permiso_importacion,omitempty"`
FolioImpoVUCEM string `json:"folio_impo_vucem,omitempty"`
NumCAS string `json:"num_cas,omitempty"`
RazonSocialEmpImp string `json:"razon_social_emp_imp,omitempty"`
NumRegSanPlagCOFEPRIS string `json:"num_reg_san_plag_cofepris,omitempty"`
DatosFabricante string `json:"datos_fabricante,omitempty"`
DatosFormulador string `json:"datos_formulador,omitempty"`
DatosMaquilador string `json:"datos_maquilador,omitempty"`
UsoAutorizado string `json:"uso_autorizado,omitempty"`
PesoEnKg *decimal.Decimal `json:"peso_en_kg,omitempty"`
ValorMercancia *decimal.Decimal `json:"valor_mercancia,omitempty"`
Moneda string `json:"moneda,omitempty"`
FraccionArancelaria string `json:"fraccion_arancelaria,omitempty"`
UUIDComercioExt string `json:"uuid_comercio_ext,omitempty"`
TipoMateria string `json:"tipo_materia,omitempty"`
DescripcionMateria string `json:"descripcion_materia,omitempty"`
Pedimentos []Pedimentos `json:"pedimentos,omitempty"` // 2.0
DocumentacionAduanera []DocumentacionAduanera `json:"documentacion_aduanera,omitempty"` // 3.x
GuiasIdentificacion []GuiasIdentificacion `json:"guias_identificacion,omitempty"`
CantidadTransporta []CantidadTransporta `json:"cantidad_transporta,omitempty"`
DetalleMercancia *DetalleMercancia `json:"detalle_mercancia,omitempty"`
}
CartaPorteMercancia es el nodo Mercancia del complemento CartaPorte.
type CartaPorteMercancias ¶
type CartaPorteMercancias struct {
PesoBrutoTotal *decimal.Decimal `json:"peso_bruto_total,omitempty"`
UnidadPeso string `json:"unidad_peso,omitempty"`
PesoNetoTotal *decimal.Decimal `json:"peso_neto_total,omitempty"`
NumTotalMercancias string `json:"num_total_mercancias,omitempty"`
CargoPorTasacion *decimal.Decimal `json:"cargo_por_tasacion,omitempty"`
LogisticaInversaRecoleccionDevolucion string `json:"logistica_inversa_recoleccion_devolucion,omitempty"` // 3.x
Mercancia []CartaPorteMercancia `json:"mercancia,omitempty"`
AutotransporteFederal *AutotransporteFederal `json:"autotransporte_federal,omitempty"` // 1.0
Autotransporte *Autotransporte `json:"autotransporte,omitempty"`
TransporteMaritimo *TransporteMaritimo `json:"transporte_maritimo,omitempty"`
TransporteAereo *TransporteAereo `json:"transporte_aereo,omitempty"`
TransporteFerroviario *TransporteFerroviario `json:"transporte_ferroviario,omitempty"`
}
CartaPorteMercancias es el nodo Mercancias del complemento CartaPorte.
type CertificadoDeDestruccion ¶
type CertificadoDeDestruccion struct {
Version string `json:"version,omitempty"`
Serie string `json:"serie,omitempty"`
NumFolDesVeh string `json:"num_fol_des_veh,omitempty"`
VehiculoDestruido *CertificadoDestruccionVehiculo `json:"vehiculo_destruido,omitempty"`
InformacionAduanera *CertificadoDestruccionInfoAduanera `json:"informacion_aduanera,omitempty"`
}
CertificadoDeDestruccion 1.0 (nodo certificadodedestruccion).
type CertificadoDestruccionInfoAduanera ¶
type CertificadoDestruccionInfoAduanera struct {
NumPedImp string `json:"num_ped_imp,omitempty"`
Fecha Fecha `json:"fecha,omitzero"`
Aduana string `json:"aduana,omitempty"`
}
CertificadoDestruccionInfoAduanera es el nodo destruccion:InformacionAduanera del complemento certificadodedestruccion.
type CertificadoDestruccionVehiculo ¶
type CertificadoDestruccionVehiculo struct {
Marca string `json:"marca,omitempty"`
TipooClase string `json:"tipoo_clase,omitempty"`
Anio string `json:"anio,omitempty"` // atributo "Año"
Modelo string `json:"modelo,omitempty"`
NIV string `json:"niv,omitempty"`
NumSerie string `json:"num_serie,omitempty"`
NumPlacas string `json:"num_placas,omitempty"`
NumMotor string `json:"num_motor,omitempty"`
NumFolTarjCir string `json:"num_fol_tarj_cir,omitempty"`
}
CertificadoDestruccionVehiculo es el nodo destruccion:VehiculoDestruido del complemento certificadodedestruccion.
type CertificadosSAT ¶
type CertificadosSAT func(noCertificadoSAT string) (*x509.Certificate, error)
CertificadosSAT da el certificado del SAT (o del PAC) con que se timbró, por su número (NoCertificadoSAT del timbre). El certificado no viene en el XML y la librería no usa la red: quien llama decide de dónde sale (un directorio, una caché, una descarga). Para no encontrado, devolver un error.
func CertificadosEn ¶
func CertificadosEn(certs ...*x509.Certificate) CertificadosSAT
CertificadosEn es un proveedor sobre certificados ya cargados, indexados por NoCertificado.
type CfdiRelacionado ¶
type CfdiRelacionado struct {
UUID string `json:"uuid,omitempty"`
UUIDOriginal string `json:"uuid_original,omitempty"` // solo si difiere de UUID
}
CfdiRelacionado es un UUID relacionado, normalizado como el del timbre.
type CfdiRelacionados ¶
type CfdiRelacionados struct {
TipoRelacion string `json:"tipo_relacion,omitempty"`
CfdiRelacionado []CfdiRelacionado `json:"cfdi_relacionado,omitempty"`
}
CfdiRelacionados agrupa los UUID relacionados con un mismo TipoRelacion.
type CfdiRetenRelacionados ¶
type CfdiRetenRelacionados struct {
TipoRelacion string `json:"tipo_relacion,omitempty"`
UUID string `json:"uuid,omitempty"`
UUIDOriginal string `json:"uuid_original,omitempty"` // solo si difiere de UUID
}
CfdiRetenRelacionados (2.0) es el comprobante de retenciones que este sustituye u otra relación.
type ChequeosCertificado ¶
type ChequeosCertificado struct {
Vigencia ResultadoChequeo `json:"vigencia"`
Rfc ResultadoChequeo `json:"rfc"`
NoCertificado ResultadoChequeo `json:"no_certificado"`
}
ChequeosCertificado compara el certificado del emisor (el Certificado del XML) con el documento, sin red: no dice si el certificado estaba revocado ni si lo emitió el SAT.
- Vigencia: la Fecha del CFDI (FechaExp en Retenciones) entre NotBefore y NotAfter del certificado, los dos incluidos. La Fecha del CFDI y la FechaExp de Retenciones 2.0 son hora civil sin zona del lugar de expedición, y México tiene husos de UTC−5 a UTC−8 (contando el horario de verano que hubo hasta 2022): la librería no sabe cuál es, así que esa hora es algún instante entre hora+5h y hora+8h UTC. Cumple si cae en la vigencia con todos los husos; no cumple si no cae con ninguno; si depende del huso (la fecha está a menos de tres horas de un límite), no verificable con VIGENCIA_AMBIGUA. Una fecha con zona (la FechaExp de Retenciones 1.0) es un instante exacto.
- Rfc: el RFC del certificado es el del emisor. Es el atributo x500UniqueIdentifier (OID 2.5.4.45) del sujeto; en una persona moral trae "RFC / RFC del representante" y cuenta el primero. Si el titular es el SAT (SAT970701NN3) y no el emisor, es un CFDI del servicio gratuito de facturación del SAT, que sella con su certificado a nombre del contribuyente: cumple con motivo CERTIFICADO_DEL_SAT (el único cumple con motivo), para que quien lo lea sepa que el RFC no coincide y por qué está bien. El SAT como representante, después de la barra, no cuenta.
- NoCertificado: el del documento es el número de serie del certificado (ver NoCertificado). Es lo mismo que exige el sello, pero aquí se revisa aunque la firma no verifique.
type CitaSAT ¶
type CitaSAT struct {
Documento string `json:"documento"`
Codigo string `json:"codigo,omitempty"`
Pagina int `json:"pagina,omitempty"`
}
CitaSAT es el fundamento de una regla en un documento oficial del SAT: un código de su matriz de errores o una página de un estándar o de una guía de llenado (la página impresa del PDF). La lista de documentos, con su URL oficial, está en el README.
type ComercioExterior ¶
type ComercioExterior struct {
Version string `json:"version,omitempty"`
MotivoTraslado string `json:"motivo_traslado,omitempty"`
TipoOperacion string `json:"tipo_operacion,omitempty"` // 1.1
ClaveDePedimento string `json:"clave_de_pedimento,omitempty"`
CertificadoOrigen string `json:"certificado_origen,omitempty"`
NumCertificadoOrigen string `json:"num_certificado_origen,omitempty"`
NumeroExportadorConfiable string `json:"numero_exportador_confiable,omitempty"`
Incoterm string `json:"incoterm,omitempty"`
Subdivision string `json:"subdivision,omitempty"` // 1.1
Observaciones string `json:"observaciones,omitempty"`
TipoCambioUSD *decimal.Decimal `json:"tipo_cambio_usd,omitempty"`
TotalUSD *decimal.Decimal `json:"total_usd,omitempty"`
Emisor *ComercioExteriorEmisor `json:"emisor,omitempty"`
Propietario []ComercioExteriorPropietario `json:"propietario,omitempty"`
Receptor *ComercioExteriorReceptor `json:"receptor,omitempty"`
Destinatario []ComercioExteriorDestinatario `json:"destinatario,omitempty"`
Mercancias []ComercioExteriorMercancia `json:"mercancias,omitempty"`
}
ComercioExterior 1.0, 1.1 y 2.0 en un solo struct: 1.1 y 2.0 tienen los mismos nodos y atributos salvo TipoOperacion y Subdivision, que 2.0 quitó. 2.0 vuelve requeridos ClaveDePedimento, CertificadoOrigen, TipoCambioUSD, TotalUSD, Mercancias y el Domicilio del Emisor, y acepta más decimales en ValorUnitarioAduana y ValorDolares (se conservan tal cual). 1.0 no tiene MotivoTraslado, Propietario ni domicilios del Emisor y el Receptor; su Receptor trae Curp y su único Destinatario Rfc y Curp.
type ComercioExteriorDestinatario ¶
type ComercioExteriorDestinatario struct {
NumRegIdTrib string `json:"num_reg_id_trib,omitempty"`
Rfc string `json:"rfc,omitempty"` // 1.0
Curp string `json:"curp,omitempty"` // 1.0
Nombre string `json:"nombre,omitempty"`
Domicilio []Domicilio `json:"domicilio,omitempty"`
}
ComercioExteriorDestinatario puede tener varios domicilios (en 1.0, uno solo y un solo Destinatario).
type ComercioExteriorEmisor ¶
type ComercioExteriorEmisor struct {
Curp string `json:"curp,omitempty"`
Domicilio *Domicilio `json:"domicilio,omitempty"`
}
ComercioExteriorEmisor es el nodo Emisor del complemento ComercioExterior.
type ComercioExteriorMercancia ¶
type ComercioExteriorMercancia struct {
NoIdentificacion string `json:"no_identificacion,omitempty"`
FraccionArancelaria string `json:"fraccion_arancelaria,omitempty"`
CantidadAduana *decimal.Decimal `json:"cantidad_aduana,omitempty"`
UnidadAduana string `json:"unidad_aduana,omitempty"`
ValorUnitarioAduana *decimal.Decimal `json:"valor_unitario_aduana,omitempty"`
ValorDolares *decimal.Decimal `json:"valor_dolares,omitempty"`
DescripcionesEspecificas []DescripcionesEspecificas `json:"descripciones_especificas,omitempty"`
}
ComercioExteriorMercancia no es la Mercancia de CartaPorte: aquí lo central es la fracción arancelaria y el valor en dólares.
type ComercioExteriorPropietario ¶
type ComercioExteriorPropietario struct {
NumRegIdTrib string `json:"num_reg_id_trib,omitempty"`
ResidenciaFiscal string `json:"residencia_fiscal,omitempty"`
}
ComercioExteriorPropietario es el nodo Propietario del complemento ComercioExterior.
type ComercioExteriorReceptor ¶
type ComercioExteriorReceptor struct {
Curp string `json:"curp,omitempty"` // 1.0
NumRegIdTrib string `json:"num_reg_id_trib,omitempty"`
Domicilio *Domicilio `json:"domicilio,omitempty"`
}
ComercioExteriorReceptor es el nodo Receptor del complemento ComercioExterior.
type ComisionDelServicio ¶
type ComisionDelServicio struct {
Base *decimal.Decimal `json:"base,omitempty"`
Porcentaje *decimal.Decimal `json:"porcentaje,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
}
ComisionDelServicio es el nodo plataformasTecnologicas:ComisionDelServicio de un DetallesDelServicio.
type CompensacionSaldosAFavor ¶
type CompensacionSaldosAFavor struct {
SaldoAFavor *decimal.Decimal `json:"saldo_a_favor,omitempty"`
Anio string `json:"anio,omitempty"` // atributo "Año"
RemanenteSalFav *decimal.Decimal `json:"remanente_sal_fav,omitempty"`
}
CompensacionSaldosAFavor es el nodo nomina12:CompensacionSaldosAFavor de un OtroPago del complemento Nómina.
type Comprobante ¶
type Comprobante struct {
Version string `json:"version,omitempty"`
Serie string `json:"serie,omitempty"`
Folio string `json:"folio,omitempty"`
Fecha Fecha `json:"fecha,omitzero"`
Sello string `json:"sello,omitempty"`
FormaPago string `json:"forma_pago,omitempty"`
NoCertificado string `json:"no_certificado,omitempty"`
Certificado string `json:"certificado,omitempty"`
CondicionesDePago string `json:"condiciones_de_pago,omitempty"`
SubTotal *decimal.Decimal `json:"sub_total,omitempty"`
Descuento *decimal.Decimal `json:"descuento,omitempty"`
Moneda string `json:"moneda,omitempty"`
TipoCambio *decimal.Decimal `json:"tipo_cambio,omitempty"`
Total *decimal.Decimal `json:"total,omitempty"`
TipoDeComprobante string `json:"tipo_de_comprobante,omitempty"`
Exportacion string `json:"exportacion,omitempty"`
MetodoPago string `json:"metodo_pago,omitempty"`
LugarExpedicion string `json:"lugar_expedicion,omitempty"`
Confirmacion string `json:"confirmacion,omitempty"`
InformacionGlobal *InformacionGlobal `json:"informacion_global,omitempty"`
// CfdiRelacionados: en 3.3 hay a lo más uno; en 4.0 puede haber varios.
// Siempre se normaliza a lista.
CfdiRelacionados []CfdiRelacionados `json:"cfdi_relacionados,omitempty"`
Emisor *Emisor `json:"emisor,omitempty"`
Receptor *Receptor `json:"receptor,omitempty"`
Conceptos []Concepto `json:"conceptos,omitempty"`
Impuestos *Impuestos `json:"impuestos,omitempty"`
// Complementos soportados.
TimbreFiscalDigital *TimbreFiscalDigital `json:"timbre_fiscal_digital,omitempty"`
Pagos *Pagos `json:"pagos,omitempty"`
Nomina []Nomina `json:"nomina,omitempty"`
ImpuestosLocales *ImpuestosLocales `json:"impuestos_locales,omitempty"`
CartaPorte *CartaPorte `json:"carta_porte,omitempty"`
ComercioExterior *ComercioExterior `json:"comercio_exterior,omitempty"`
Divisas *Divisas `json:"divisas,omitempty"`
CFDIRegistroFiscal *CFDIRegistroFiscal `json:"cfdi_registro_fiscal,omitempty"`
LeyendasFiscales *LeyendasFiscales `json:"leyendas_fiscales,omitempty"`
EstadoDeCuentaCombustible *EstadoDeCuentaCombustible `json:"estado_de_cuenta_combustible,omitempty"`
// HidroYPetro es complemento de concepto (Concepto.HidroYPetro); aquí van
// los que vienen fuera de lugar, en el Complemento del comprobante.
HidroYPetro []HidroYPetro `json:"hidro_y_petro,omitempty"`
Aerolineas *Aerolineas `json:"aerolineas,omitempty"`
Donatarias *Donatarias `json:"donatarias,omitempty"`
INE *INE `json:"ine,omitempty"`
ValesDeDespensa *ValesDeDespensa `json:"vales_de_despensa,omitempty"`
ConsumoDeCombustibles *ConsumoDeCombustibles `json:"consumo_de_combustibles,omitempty"`
PagoEnEspecie *PagoEnEspecie `json:"pago_en_especie,omitempty"`
NotariosPublicos *NotariosPublicos `json:"notarios_publicos,omitempty"`
ParcialesConstruccion *ParcialesConstruccion `json:"parcialesconstruccion,omitempty"`
VehiculoUsado *VehiculoUsado `json:"vehiculo_usado,omitempty"`
TuristaPasajeroExtranjero *TuristaPasajeroExtranjero `json:"turista_pasajero_extranjero,omitempty"`
ComplementoSPEI []SPEITercero `json:"complemento_spei,omitempty"` // Complemento_SPEI/SPEI_Tercero
RenovacionySustitucionVehiculos *RenovacionySustitucionVehiculos `json:"renovacionysustitucionvehiculos,omitempty"`
CertificadoDeDestruccion *CertificadoDeDestruccion `json:"certificadodedestruccion,omitempty"`
ObrasArteAntiguedades *ObrasArteAntiguedades `json:"obrasarteantiguedades,omitempty"`
PFintegranteCoordinado *PFintegranteCoordinado `json:"pf_integrante_coordinado,omitempty"`
GastosHidrocarburos *GastosHidrocarburos `json:"gastos_hidrocarburos,omitempty"`
IngresosHidrocarburos *IngresosHidrocarburos `json:"ingresos_hidrocarburos,omitempty"`
EstadoDeCuentaBancario *EstadoDeCuentaBancario `json:"estado_de_cuenta_bancario,omitempty"`
// ComplementosNoSoportados lista los nodos de Complemento (y de
// ComplementoConcepto) que no se leen, como "{namespace}NombreLocal",
// sin repetir.
ComplementosNoSoportados []string `json:"complementos_no_soportados,omitempty"`
// Advertencias de la lectura. En JSON van fuera de "cfdi", en el sobre.
Advertencias []Advertencia `json:"-"`
}
Comprobante es un CFDI 3.3 o 4.0 leído y normalizado.
func Parse ¶
func Parse(r io.Reader) (*Comprobante, error)
Parse lee un CFDI 3.3 o 4.0.
Solo devuelve error (un *Error) si el documento no es XML o si su raíz no es un Comprobante de los namespaces cfd/3 o cfd/4. Cualquier otra rareza se lee como se pueda y queda en Comprobante.Advertencias.
Example ¶
package main
import (
"fmt"
"log"
"strings"
"github.com/OrtaMarco/cfdi-go"
)
// Una factura 4.0 mínima, sin sello ni timbre, con el RFC de prueba del SAT.
const facturaEjemplo = `<?xml version="1.0" encoding="UTF-8"?>
<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/4" Version="4.0" Serie="A" Folio="1"
Fecha="2026-01-15T10:30:00" Sello="" NoCertificado="30001000000500003416" Certificado=""
SubTotal="100.00" Moneda="MXN" Total="116.00" TipoDeComprobante="I" Exportacion="01"
MetodoPago="PUE" FormaPago="03" LugarExpedicion="20000">
<cfdi:Emisor Rfc="EKU9003173C9" Nombre="ESCUELA KEMPER URGATE" RegimenFiscal="601"/>
<cfdi:Receptor Rfc="XAXX010101000" Nombre="PUBLICO EN GENERAL" DomicilioFiscalReceptor="20000"
RegimenFiscalReceptor="616" UsoCFDI="S01"/>
<cfdi:Conceptos>
<cfdi:Concepto ClaveProdServ="01010101" Cantidad="1" ClaveUnidad="H87" Descripcion="Artículo"
ValorUnitario="100.00" Importe="100.00" ObjetoImp="02">
<cfdi:Impuestos>
<cfdi:Traslados>
<cfdi:Traslado Base="100.00" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="16.00"/>
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Concepto>
</cfdi:Conceptos>
<cfdi:Impuestos TotalImpuestosTrasladados="16.00">
<cfdi:Traslados>
<cfdi:Traslado Base="100.00" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="16.00"/>
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Comprobante>`
func main() {
c, err := cfdi.Parse(strings.NewReader(facturaEjemplo))
if err != nil {
log.Fatal(cfdi.ClaseDe(err))
}
fmt.Println(c.Version, c.TipoDeComprobante, c.Emisor.Rfc, c.Total.Original())
for _, a := range c.Advertencias {
fmt.Println(a.Codigo, a.Ruta)
}
}
Output: 4.0 I EKU9003173C9 116.00 SIN_TIMBRE /Comprobante/Complemento
func ParseBytes ¶
func ParseBytes(b []byte) (*Comprobante, error)
ParseBytes es Parse sobre un []byte. No modifica b.
func ParseBytesOpciones ¶
func ParseBytesOpciones(b []byte, o Opciones) (*Comprobante, error)
ParseBytesOpciones es ParseBytes con opciones.
func ParseOpciones ¶
func ParseOpciones(r io.Reader, o Opciones) (*Comprobante, error)
ParseOpciones es Parse con opciones.
func (*Comprobante) AdvertenciaEn ¶
func (c *Comprobante) AdvertenciaEn(rutaNodo, atributo string) (Advertencia, bool)
AdvertenciaEn devuelve la primera advertencia del atributo de ese nodo: AdvertenciaEn("/Comprobante", "Fecha") en vez de buscar el sufijo "/@Fecha" en Ruta.
func (*Comprobante) AdvertenciasDe ¶
func (c *Comprobante) AdvertenciasDe(rutaNodo string) []Advertencia
AdvertenciasDe devuelve las advertencias del nodo con esa ruta (ver el formato en Advertencia) y las de sus atributos, sin las de sus hijos. Con rutaNodo "" devuelve las del documento entero.
func (*Comprobante) Complementos ¶
func (c *Comprobante) Complementos() []string
Complementos lista los complementos presentes, también los de concepto y sin repetir: los soportados como "Nombre versión" ("TimbreFiscalDigital 1.1", "Pagos 2.0", "CartaPorte 3.1", "VentaVehiculos 1.1") y los no soportados como "{namespace}NombreLocal".
func (*Comprobante) Documento ¶
func (c *Comprobante) Documento(o OpcionesJSON) Documento
Documento arma el sobre. Sin IncluirSello trabaja sobre una copia: el Comprobante original no se toca.
func (*Comprobante) JSON ¶
func (c *Comprobante) JSON() ([]byte, error)
JSON devuelve el Documento sin sellos y sin indentar.
Example ¶
package main
import (
"fmt"
"log"
"strings"
"github.com/OrtaMarco/cfdi-go"
)
// Una factura 4.0 mínima, sin sello ni timbre, con el RFC de prueba del SAT.
const facturaEjemplo = `<?xml version="1.0" encoding="UTF-8"?>
<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/4" Version="4.0" Serie="A" Folio="1"
Fecha="2026-01-15T10:30:00" Sello="" NoCertificado="30001000000500003416" Certificado=""
SubTotal="100.00" Moneda="MXN" Total="116.00" TipoDeComprobante="I" Exportacion="01"
MetodoPago="PUE" FormaPago="03" LugarExpedicion="20000">
<cfdi:Emisor Rfc="EKU9003173C9" Nombre="ESCUELA KEMPER URGATE" RegimenFiscal="601"/>
<cfdi:Receptor Rfc="XAXX010101000" Nombre="PUBLICO EN GENERAL" DomicilioFiscalReceptor="20000"
RegimenFiscalReceptor="616" UsoCFDI="S01"/>
<cfdi:Conceptos>
<cfdi:Concepto ClaveProdServ="01010101" Cantidad="1" ClaveUnidad="H87" Descripcion="Artículo"
ValorUnitario="100.00" Importe="100.00" ObjetoImp="02">
<cfdi:Impuestos>
<cfdi:Traslados>
<cfdi:Traslado Base="100.00" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="16.00"/>
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Concepto>
</cfdi:Conceptos>
<cfdi:Impuestos TotalImpuestosTrasladados="16.00">
<cfdi:Traslados>
<cfdi:Traslado Base="100.00" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="16.00"/>
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Comprobante>`
func main() {
c, err := cfdi.ParseBytes([]byte(facturaEjemplo))
if err != nil {
log.Fatal(err)
}
b, err := c.JSON()
if err != nil {
log.Fatal(err)
}
inicio, _, _ := strings.Cut(string(b), `"serie"`)
fmt.Println(inicio + "…")
}
Output: {"schema_version":"1","cfdi":{"version":"4.0",…
func (*Comprobante) JSONOpciones ¶
func (c *Comprobante) JSONOpciones(o OpcionesJSON) ([]byte, error)
JSONOpciones devuelve el Documento con las opciones dadas.
func (*Comprobante) TieneAdvertencia ¶
func (c *Comprobante) TieneAdvertencia(codigo string) bool
TieneAdvertencia dice si la lectura produjo al menos una advertencia con ese código.
func (*Comprobante) UUID ¶
func (c *Comprobante) UUID() string
UUID del timbre, normalizado; "" si no hay timbre.
type Concepto ¶
type Concepto struct {
ClaveProdServ string `json:"clave_prod_serv,omitempty"`
NoIdentificacion string `json:"no_identificacion,omitempty"`
Cantidad *decimal.Decimal `json:"cantidad,omitempty"`
ClaveUnidad string `json:"clave_unidad,omitempty"`
Unidad string `json:"unidad,omitempty"`
Descripcion string `json:"descripcion,omitempty"`
ValorUnitario *decimal.Decimal `json:"valor_unitario,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
Descuento *decimal.Decimal `json:"descuento,omitempty"`
ObjetoImp string `json:"objeto_imp,omitempty"`
Impuestos *ImpuestosConcepto `json:"impuestos,omitempty"`
ACuentaTerceros *ACuentaTerceros `json:"a_cuenta_terceros,omitempty"`
InformacionAduanera []InformacionAduanera `json:"informacion_aduanera,omitempty"`
// CuentaPredial: 3.3 admite una, 4.0 varias. Siempre lista.
CuentaPredial []CuentaPredial `json:"cuenta_predial,omitempty"`
// Complementos de concepto soportados.
PorCuentadeTerceros *PorCuentadeTerceros `json:"por_cuentade_terceros,omitempty"`
VentaVehiculos *VentaVehiculos `json:"venta_vehiculos,omitempty"`
HidroYPetro *HidroYPetro `json:"hidro_y_petro,omitempty"`
InstEducativas *InstEducativas `json:"inst_educativas,omitempty"`
AcreditamientoIEPS *AcreditamientoIEPS `json:"acreditamiento_ieps,omitempty"`
// ParcialesConstruccion fuera de lugar: el XSD lo pone en el Complemento
// del comprobante (Comprobante.ParcialesConstruccion).
ParcialesConstruccion *ParcialesConstruccion `json:"parcialesconstruccion,omitempty"`
// ComplementoConcepto lista los complementos del concepto que no se
// leen, como "{namespace}NombreLocal".
ComplementoConcepto []string `json:"complemento_concepto,omitempty"`
Parte []Parte `json:"parte,omitempty"`
}
Concepto es el nodo cfdi:Concepto del comprobante, con sus impuestos y complementos de concepto.
type ConceptoConsumoDeCombustibles ¶
type ConceptoConsumoDeCombustibles struct {
Identificador string `json:"identificador,omitempty"`
Fecha Fecha `json:"fecha,omitzero"`
Rfc string `json:"rfc,omitempty"`
ClaveEstacion string `json:"clave_estacion,omitempty"`
TipoCombustible string `json:"tipo_combustible,omitempty"` // 1.1
Cantidad *decimal.Decimal `json:"cantidad,omitempty"`
NombreCombustible string `json:"nombre_combustible,omitempty"`
FolioOperacion string `json:"folio_operacion,omitempty"`
ValorUnitario *decimal.Decimal `json:"valor_unitario,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
Determinados []ConsumoDeCombustiblesDeterminado `json:"determinados,omitempty"`
}
ConceptoConsumoDeCombustibles es el nodo ConceptoConsumoDeCombustibles del complemento ConsumoDeCombustibles.
type ConceptoEstadoDeCuentaCombustible ¶
type ConceptoEstadoDeCuentaCombustible struct {
Identificador string `json:"identificador,omitempty"`
Fecha Fecha `json:"fecha,omitzero"`
Rfc string `json:"rfc,omitempty"`
ClaveEstacion string `json:"clave_estacion,omitempty"`
TAR string `json:"tar,omitempty"` // 1.1
Cantidad *decimal.Decimal `json:"cantidad,omitempty"`
TipoCombustible string `json:"tipo_combustible,omitempty"` // 1.2
NoIdentificacion string `json:"no_identificacion,omitempty"` // 1.1
Unidad string `json:"unidad,omitempty"`
NombreCombustible string `json:"nombre_combustible,omitempty"`
FolioOperacion string `json:"folio_operacion,omitempty"`
ValorUnitario *decimal.Decimal `json:"valor_unitario,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
// Traslados usa el mismo struct que los del CFDI: Impuesto ("IVA" o
// "IEPS", no la clave 002/003), TasaOCuota (TasaoCuota en 1.1) e
// Importe; no hay Base ni TipoFactor.
Traslados []Impuesto `json:"traslados,omitempty"`
}
ConceptoEstadoDeCuentaCombustible es el nodo ConceptoEstadoDeCuentaCombustible del complemento EstadoDeCuentaCombustible.
type ConsumoDeCombustibles ¶
type ConsumoDeCombustibles struct {
Version string `json:"version,omitempty"`
TipoOperacion string `json:"tipo_operacion,omitempty"`
NumeroDeCuenta string `json:"numero_de_cuenta,omitempty"`
SubTotal *decimal.Decimal `json:"sub_total,omitempty"`
Total *decimal.Decimal `json:"total,omitempty"`
Conceptos []ConceptoConsumoDeCombustibles `json:"conceptos,omitempty"`
}
ConsumoDeCombustibles 1.1 (ConsumoDeCombustibles11) y 1.0 (consumodecombustibles). 1.1 agregó tipoCombustible al concepto y renombró la tasa del Determinado (tasa → tasaOCuota): cada una en su campo.
type ConsumoDeCombustiblesDeterminado ¶
type ConsumoDeCombustiblesDeterminado struct {
Impuesto string `json:"impuesto,omitempty"`
Tasa *decimal.Decimal `json:"tasa,omitempty"` // 1.0
TasaOCuota *decimal.Decimal `json:"tasa_o_cuota,omitempty"` // 1.1
Importe *decimal.Decimal `json:"importe,omitempty"`
}
ConsumoDeCombustiblesDeterminado es el nodo Determinado de un concepto del complemento ConsumoDeCombustibles.
type ContenedorFerroviario ¶
type ContenedorFerroviario struct {
TipoContenedor string `json:"tipo_contenedor,omitempty"`
PesoContenedorVacio *decimal.Decimal `json:"peso_contenedor_vacio,omitempty"`
PesoNetoMercancia *decimal.Decimal `json:"peso_neto_mercancia,omitempty"`
}
ContenedorFerroviario es el nodo Contenedor de un Carro del complemento CartaPorte.
type ContenedorMaritimo ¶
type ContenedorMaritimo struct {
MatriculaContenedor string `json:"matricula_contenedor,omitempty"`
TipoContenedor string `json:"tipo_contenedor,omitempty"`
NumPrecinto string `json:"num_precinto,omitempty"`
IdCCPRelacionado string `json:"id_ccp_relacionado,omitempty"` // 3.x
PlacaVMCCP string `json:"placa_vmccp,omitempty"` // 3.x
FechaCertificacionCCP Fecha `json:"fecha_certificacion_ccp,omitzero"` // 3.x
RemolquesCCP []RemolqueCCP `json:"remolques_ccp,omitempty"` // 3.1
}
ContenedorMaritimo es el nodo Contenedor del TransporteMaritimo del complemento CartaPorte.
type ContribucionGubernamental ¶
type ContribucionGubernamental struct {
ImpContrib *decimal.Decimal `json:"imp_contrib,omitempty"`
EntidadDondePagaLaContribucion string `json:"entidad_donde_paga_la_contribucion,omitempty"`
}
ContribucionGubernamental es el nodo plataformasTecnologicas:ContribucionGubernamental de un DetallesDelServicio.
type CuentaPredial ¶
type CuentaPredial struct {
Numero string `json:"numero,omitempty"`
}
CuentaPredial es el nodo cfdi:CuentaPredial de un concepto.
type DeduccOSalidas ¶
type DeduccOSalidas struct {
MontTotEgresPeriodo *decimal.Decimal `json:"mont_tot_egres_periodo,omitempty"`
PartPropDelFideicom *decimal.Decimal `json:"part_prop_del_fideicom,omitempty"`
PropDelMontTot *decimal.Decimal `json:"prop_del_mont_tot,omitempty"`
// IntegracEgresos/@ConceptoS.
IntegracEgresos string `json:"integrac_egresos,omitempty"`
}
DeduccOSalidas es el nodo fideicomisonoempresarial:DeduccOSalidas del complemento Fideicomisonoempresarial.
type Deduccion ¶
type Deduccion struct {
TipoDeduccion string `json:"tipo_deduccion,omitempty"`
Clave string `json:"clave,omitempty"`
Concepto string `json:"concepto,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
ImporteGravado *decimal.Decimal `json:"importe_gravado,omitempty"` // 1.1
ImporteExento *decimal.Decimal `json:"importe_exento,omitempty"` // 1.1
}
Deduccion es el nodo nomina12:Deduccion del complemento Nómina.
type Deducciones ¶
type Deducciones struct {
TotalOtrasDeducciones *decimal.Decimal `json:"total_otras_deducciones,omitempty"`
TotalImpuestosRetenidos *decimal.Decimal `json:"total_impuestos_retenidos,omitempty"`
TotalGravado *decimal.Decimal `json:"total_gravado,omitempty"` // 1.1
TotalExento *decimal.Decimal `json:"total_exento,omitempty"` // 1.1
Deduccion []Deduccion `json:"deduccion,omitempty"`
}
Deducciones es el nodo nomina12:Deducciones del complemento Nómina.
type DerechosDePaso ¶
type DerechosDePaso struct {
TipoDerechoDePaso string `json:"tipo_derecho_de_paso,omitempty"`
KilometrajePagado *decimal.Decimal `json:"kilometraje_pagado,omitempty"`
}
DerechosDePaso es el nodo DerechosDePaso del TransporteFerroviario del complemento CartaPorte.
type DescripcionesEspecificas ¶
type DescripcionesEspecificas struct {
Marca string `json:"marca,omitempty"`
Modelo string `json:"modelo,omitempty"`
SubModelo string `json:"sub_modelo,omitempty"`
NumeroSerie string `json:"numero_serie,omitempty"`
}
DescripcionesEspecificas es el nodo DescripcionesEspecificas de una Mercancia del complemento ComercioExterior.
type DetalleMercancia ¶
type DetalleMercancia struct {
UnidadPeso string `json:"unidad_peso,omitempty"` // 1.0 (2.0 lo llamó UnidadPesoMerc)
UnidadPesoMerc string `json:"unidad_peso_merc,omitempty"`
PesoBruto *decimal.Decimal `json:"peso_bruto,omitempty"`
PesoNeto *decimal.Decimal `json:"peso_neto,omitempty"`
PesoTara *decimal.Decimal `json:"peso_tara,omitempty"`
NumPiezas string `json:"num_piezas,omitempty"`
}
DetalleMercancia es el nodo DetalleMercancia de una Mercancia del complemento CartaPorte.
type DetallesDelServicio ¶
type DetallesDelServicio struct {
FormaPagoServ string `json:"forma_pago_serv,omitempty"`
TipoDeServ string `json:"tipo_de_serv,omitempty"`
SubTipServ string `json:"sub_tip_serv,omitempty"`
RFCTerceroAutorizado string `json:"rfc_tercero_autorizado,omitempty"`
FechaServ Fecha `json:"fecha_serv,omitzero"`
PrecioServSinIVA *decimal.Decimal `json:"precio_serv_sin_iva,omitempty"`
ImpuestosTrasladadosdelServicio *ImpuestosTrasladadosdelServicio `json:"impuestos_trasladadosdel_servicio,omitempty"`
ContribucionGubernamental *ContribucionGubernamental `json:"contribucion_gubernamental,omitempty"`
ComisionDelServicio *ComisionDelServicio `json:"comision_del_servicio,omitempty"`
}
DetallesDelServicio es el nodo plataformasTecnologicas:DetallesDelServicio del complemento de Retenciones ServiciosPlataformasTecnologicas.
type DividOUtil ¶
type DividOUtil struct {
CveTipDivOUtil string `json:"cve_tip_div_o_util,omitempty"`
MontISRAcredRetMexico *decimal.Decimal `json:"mont_isr_acred_ret_mexico,omitempty"`
MontISRAcredRetExtranjero *decimal.Decimal `json:"mont_isr_acred_ret_extranjero,omitempty"`
MontRetExtDivExt *decimal.Decimal `json:"mont_ret_ext_div_ext,omitempty"`
TipoSocDistrDiv string `json:"tipo_soc_distr_div,omitempty"`
MontISRAcredNal *decimal.Decimal `json:"mont_isr_acred_nal,omitempty"`
MontDivAcumNal *decimal.Decimal `json:"mont_div_acum_nal,omitempty"`
MontDivAcumExt *decimal.Decimal `json:"mont_div_acum_ext,omitempty"`
}
DividOUtil es el nodo dividendos:DividOUtil del complemento Dividendos.
type Dividendos ¶
type Dividendos struct {
Version string `json:"version,omitempty"`
DividOUtil *DividOUtil `json:"divid_o_util,omitempty"`
Remanente *Remanente `json:"remanente,omitempty"`
}
Dividendos es el complemento de Retenciones dividendos:Dividendos.
type Divisas ¶
type Divisas struct {
Version string `json:"version,omitempty"`
TipoOperacion string `json:"tipo_operacion,omitempty"` // atributo "tipoOperacion": compra | venta
}
Divisas 1.0: compra o venta de divisas.
type DoctoRelacionado ¶
type DoctoRelacionado struct {
// IdDocumento normalizado como el UUID del timbre (mayúsculas), para
// cruzarlo contra él.
IdDocumento string `json:"id_documento,omitempty"`
IdDocumentoOriginal string `json:"id_documento_original,omitempty"` // solo si difiere
Serie string `json:"serie,omitempty"`
Folio string `json:"folio,omitempty"`
MonedaDR string `json:"moneda_dr,omitempty"`
EquivalenciaDR *decimal.Decimal `json:"equivalencia_dr,omitempty"` // 2.0
TipoCambioDR *decimal.Decimal `json:"tipo_cambio_dr,omitempty"` // 1.0
MetodoDePagoDR string `json:"metodo_de_pago_dr,omitempty"` // 1.0
NumParcialidad string `json:"num_parcialidad,omitempty"`
ImpSaldoAnt *decimal.Decimal `json:"imp_saldo_ant,omitempty"`
ImpPagado *decimal.Decimal `json:"imp_pagado,omitempty"`
ImpSaldoInsoluto *decimal.Decimal `json:"imp_saldo_insoluto,omitempty"`
ObjetoImpDR string `json:"objeto_imp_dr,omitempty"` // 2.0
ImpuestosDR *ImpuestosDR `json:"impuestos_dr,omitempty"` // 2.0
}
DoctoRelacionado es el nodo DoctoRelacionado de un Pago del complemento Pagos.
type DocumentacionAduanera ¶
type DocumentacionAduanera struct {
TipoDocumento string `json:"tipo_documento,omitempty"`
NumPedimento string `json:"num_pedimento,omitempty"`
IdentDocAduanero string `json:"ident_doc_aduanero,omitempty"`
RFCImpo string `json:"rfc_impo,omitempty"`
}
DocumentacionAduanera es el nodo DocumentacionAduanera de una Mercancia del complemento CartaPorte (3.x).
type Documento ¶
type Documento struct {
// Origen es de dónde salió el CFDI (lo llena quien lee en lote).
Origen string `json:"origen,omitempty"`
SchemaVersion string `json:"schema_version"`
CFDI *Comprobante `json:"cfdi"`
Advertencias []Advertencia `json:"advertencias"`
// VerificacionSello es el resultado de verificar el sello del emisor
// (Verificar(...).Sello). Documento no lo llena: lo agrega quien
// verifica, como `cfdi lote -sello`.
VerificacionSello *ResultadoSello `json:"verificacion_sello,omitempty"`
// VerificacionTFD es el resultado de verificar el SelloSAT del timbre
// (Verificar(...).TFD). Lo agrega quien verifica, como
// `cfdi lote -certs-sat`.
VerificacionTFD *ResultadoSello `json:"verificacion_tfd,omitempty"`
// Validacion es el resultado de Validar. Lo agrega quien valida, como
// `cfdi lote -validar`.
Validacion *Validacion `json:"validacion,omitempty"`
}
Documento es el sobre del JSON: versión del esquema, el CFDI y las advertencias de la lectura (siempre presente, [] si no hubo).
type DocumentoRetenciones ¶
type DocumentoRetenciones struct {
Origen string `json:"origen,omitempty"`
// TipoDocumento es siempre "retenciones".
TipoDocumento TipoDocumento `json:"tipo_documento"`
SchemaVersion string `json:"schema_version"`
Retenciones *Retenciones `json:"retenciones"`
Advertencias []Advertencia `json:"advertencias"`
VerificacionSello *ResultadoSello `json:"verificacion_sello,omitempty"`
VerificacionTFD *ResultadoSello `json:"verificacion_tfd,omitempty"`
Validacion *Validacion `json:"validacion,omitempty"`
}
DocumentoRetenciones es el sobre del JSON de Retenciones: como Documento, con tipo_documento para distinguirlo de un CFDI en la misma salida (una línea de `cfdi lote`).
type Domicilio ¶
type Domicilio struct {
Calle string `json:"calle,omitempty"`
NumeroExterior string `json:"numero_exterior,omitempty"`
NumeroInterior string `json:"numero_interior,omitempty"`
Colonia string `json:"colonia,omitempty"`
Localidad string `json:"localidad,omitempty"`
Referencia string `json:"referencia,omitempty"`
Municipio string `json:"municipio,omitempty"`
Estado string `json:"estado,omitempty"`
Pais string `json:"pais,omitempty"`
CodigoPostal string `json:"codigo_postal,omitempty"`
}
Domicilio de carta porte y de comercio exterior (mismos atributos).
type Donatarias ¶
type Donatarias struct {
Version string `json:"version,omitempty"`
NoAutorizacion string `json:"no_autorizacion,omitempty"`
FechaAutorizacion Fecha `json:"fecha_autorizacion,omitzero"` // AAAA-MM-DD
Leyenda string `json:"leyenda,omitempty"`
}
Donatarias 1.1 (donat11) y 1.0 (donat): comparten namespace y atributos; 1.1 solo cambió la versión fija. Los atributos van en minúsculas.
type ECBMovimiento ¶
type ECBMovimiento struct {
Fecha Fecha `json:"fecha,omitzero"`
Referencia string `json:"referencia,omitempty"`
Descripcion string `json:"descripcion,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
Moneda string `json:"moneda,omitempty"`
SaldoInicial *decimal.Decimal `json:"saldo_inicial,omitempty"`
SaldoAlCorte *decimal.Decimal `json:"saldo_al_corte,omitempty"`
}
ECBMovimiento es el nodo ecb:MovimientoECB de los Movimientos del complemento EstadoDeCuentaBancario.
type ECBMovimientoFiscal ¶
type ECBMovimientoFiscal struct {
Fecha Fecha `json:"fecha,omitzero"`
Referencia string `json:"referencia,omitempty"`
Descripcion string `json:"descripcion,omitempty"`
RFCEnajenante string `json:"rfc_enajenante,omitempty"` // atributo "RFCenajenante"
Importe *decimal.Decimal `json:"importe,omitempty"`
Moneda string `json:"moneda,omitempty"`
SaldoInicial *decimal.Decimal `json:"saldo_inicial,omitempty"`
SaldoAlCorte *decimal.Decimal `json:"saldo_al_corte,omitempty"`
}
ECBMovimientoFiscal: el XSD escribe RFCenajenante (e minúscula) e Importe con mayúscula, a diferencia de MovimientoECB.
type ECBMovimientos ¶
type ECBMovimientos struct {
MovimientoECB []ECBMovimiento `json:"movimiento_ecb,omitempty"`
MovimientoECBFiscal []ECBMovimientoFiscal `json:"movimiento_ecb_fiscal,omitempty"`
}
ECBMovimientos es el nodo ecb:Movimientos del complemento EstadoDeCuentaBancario.
type Emisor ¶
type Emisor struct {
Rfc string `json:"rfc,omitempty"`
Nombre string `json:"nombre,omitempty"`
RegimenFiscal string `json:"regimen_fiscal,omitempty"`
FacAtrAdquirente string `json:"fac_atr_adquirente,omitempty"`
}
Emisor es el nodo cfdi:Emisor del comprobante.
type EmisorRetenciones ¶
type EmisorRetenciones struct {
RfcE string `json:"rfc_e,omitempty"`
NomDenRazSocE string `json:"nom_den_raz_soc_e,omitempty"`
RegimenFiscalE string `json:"regimen_fiscal_e,omitempty"` // 2.0
CurpE string `json:"curp_e,omitempty"` // 1.0 (CURPE)
}
EmisorRetenciones es el nodo retenciones:Emisor del CFDI de Retenciones.
type EnajenaciondeAcciones ¶
type EnajenaciondeAcciones struct {
Version string `json:"version,omitempty"`
ContratoIntermediacion string `json:"contrato_intermediacion,omitempty"`
Ganancia *decimal.Decimal `json:"ganancia,omitempty"`
Perdida *decimal.Decimal `json:"perdida,omitempty"`
}
EnajenaciondeAcciones es el complemento de Retenciones enajenaciondeacciones:EnajenaciondeAcciones.
type EntidadSNCF ¶
type EntidadSNCF struct {
OrigenRecurso string `json:"origen_recurso,omitempty"`
MontoRecursoPropio *decimal.Decimal `json:"monto_recurso_propio,omitempty"`
}
EntidadSNCF es el nodo nomina12:EntidadSNCF del Emisor del complemento Nómina.
type ErrorCadena ¶
type ErrorCadena struct {
Motivo string // uno de los Motivo* de arriba
Nodo string // "{namespace}Nombre" del nodo que la impide, si aplica
Err error
}
ErrorCadena explica por qué no se pudo armar una cadena original. La librería no devuelve nunca una cadena que no pueda garantizar.
func (*ErrorCadena) Error ¶
func (e *ErrorCadena) Error() string
func (*ErrorCadena) Unwrap ¶
func (e *ErrorCadena) Unwrap() error
type EstadoDeCuentaBancario ¶
type EstadoDeCuentaBancario struct {
Version string `json:"version,omitempty"`
NumeroCuenta string `json:"numero_cuenta,omitempty"`
NombreCliente string `json:"nombre_cliente,omitempty"`
Periodo string `json:"periodo,omitempty"`
Sucursal string `json:"sucursal,omitempty"`
Movimientos *ECBMovimientos `json:"movimientos,omitempty"`
}
EstadoDeCuentaBancario 1.0 (ecb), de CFDI 3.2. Movimientos no tiene atributos pero sí dos clases de hijos: se conserva como objeto con las dos listas.
type EstadoDeCuentaCombustible ¶
type EstadoDeCuentaCombustible struct {
Version string `json:"version,omitempty"`
TipoOperacion string `json:"tipo_operacion,omitempty"`
NumeroDeCuenta string `json:"numero_de_cuenta,omitempty"`
SubTotal *decimal.Decimal `json:"sub_total,omitempty"`
Total *decimal.Decimal `json:"total,omitempty"`
Conceptos []ConceptoEstadoDeCuentaCombustible `json:"conceptos,omitempty"`
}
EstadoDeCuentaCombustible 1.2 (ecc12) y 1.1 (namespace .../EstadoDeCuentaCombustible). Conceptos aplana Conceptos/ConceptoEstadoDeCuentaCombustible.
type Fecha ¶
type Fecha struct {
Original string // texto como venía
Time time.Time // hora civil; cero si el texto no se pudo leer
// FueraDeFormato dice que el texto es una fecha legible pero no en el
// formato del SAT (con zona, con fracción de segundo, con espacios, sin
// hora o al revés): es la versión por campo de FECHA_FORMATO. Con
// Opciones.FechaEstricta esas fechas no se interpretan (Time queda en
// cero) y FueraDeFormato sigue en true. No va al JSON.
FueraDeFormato bool
}
Fecha guarda una fecha del CFDI como texto original y como hora civil.
El SAT escribe las fechas sin zona horaria ("2026-01-15T10:30:00"): es la hora local del lugar de expedición, que puede ser cualquiera de los husos de México. Esta librería no inventa la zona: Time lleva la fecha y hora tal cual (hora civil) con time.UTC como contenedor, sin que eso signifique que el instante sea UTC. Para un instante real use En con la zona que corresponda.
Los nodos de nómina usan fechas sin hora ("2026-01-15"); entonces la hora es 00:00:00.
func (Fecha) MarshalJSON ¶
MarshalJSON escribe el texto original.
func (*Fecha) UnmarshalJSON ¶
UnmarshalJSON lee el texto y vuelve a interpretar la hora civil; si no se puede, deja Time en cero sin error (igual que Parse). Como el JSON no dice si el campo era fecha u hora, FueraDeFormato acepta los dos formatos SAT.
type Fideicomisonoempresarial ¶
type Fideicomisonoempresarial struct {
Version string `json:"version,omitempty"`
IngresosOEntradas *IngresosOEntradas `json:"ingresos_o_entradas,omitempty"`
DeduccOSalidas *DeduccOSalidas `json:"deducc_o_salidas,omitempty"`
RetEfectFideicomiso *RetEfectFideicomiso `json:"ret_efect_fideicomiso,omitempty"`
}
Fideicomisonoempresarial es el complemento de Retenciones fideicomisonoempresarial:Fideicomisonoempresarial.
type GastosHidrocarburos ¶
type GastosHidrocarburos struct {
Version string `json:"version,omitempty"`
NumeroContrato string `json:"numero_contrato,omitempty"`
AreaContractual string `json:"area_contractual,omitempty"`
Erogacion []GastosHidrocarburosErogacion `json:"erogacion,omitempty"`
}
GastosHidrocarburos 1.0 (GastosHidrocarburos10).
type GastosHidrocarburosActividades ¶
type GastosHidrocarburosActividades struct {
ActividadRelacionada string `json:"actividad_relacionada,omitempty"`
SubActividades []GastosHidrocarburosSubActividades `json:"sub_actividades,omitempty"`
}
GastosHidrocarburosActividades es el nodo gceh:Actividades de una Erogacion del complemento GastosHidrocarburos.
type GastosHidrocarburosCentroCostos ¶
type GastosHidrocarburosCentroCostos struct {
Campo string `json:"campo,omitempty"`
Yacimientos []GastosHidrocarburosYacimientos `json:"yacimientos,omitempty"`
}
GastosHidrocarburosCentroCostos es el nodo gceh:CentroCostos de una Erogacion del complemento GastosHidrocarburos.
type GastosHidrocarburosDocumentoRelacionado ¶
type GastosHidrocarburosDocumentoRelacionado struct {
OrigenErogacion string `json:"origen_erogacion,omitempty"`
FolioFiscalVinculado string `json:"folio_fiscal_vinculado,omitempty"`
RFCProveedor string `json:"rfc_proveedor,omitempty"`
MontoTotalIVA *decimal.Decimal `json:"monto_total_iva,omitempty"`
MontoRetencionISR *decimal.Decimal `json:"monto_retencion_isr,omitempty"`
MontoRetencionIVA *decimal.Decimal `json:"monto_retencion_iva,omitempty"`
MontoRetencionOtrosImpuestos *decimal.Decimal `json:"monto_retencion_otros_impuestos,omitempty"`
NumeroPedimentoVinculado string `json:"numero_pedimento_vinculado,omitempty"`
ClavePedimentoVinculado string `json:"clave_pedimento_vinculado,omitempty"`
ClavePagoPedimentoVinculado string `json:"clave_pago_pedimento_vinculado,omitempty"`
MontoIVAPedimento *decimal.Decimal `json:"monto_iva_pedimento,omitempty"`
OtrosImpuestosPagadosPedimento *decimal.Decimal `json:"otros_impuestos_pagados_pedimento,omitempty"`
FechaFolioFiscalVinculado Fecha `json:"fecha_folio_fiscal_vinculado,omitzero"`
Mes string `json:"mes,omitempty"`
MontoTotalErogaciones *decimal.Decimal `json:"monto_total_erogaciones,omitempty"`
}
GastosHidrocarburosDocumentoRelacionado es el nodo gceh:DocumentoRelacionado de una Erogacion del complemento GastosHidrocarburos.
type GastosHidrocarburosErogacion ¶
type GastosHidrocarburosErogacion struct {
TipoErogacion string `json:"tipo_erogacion,omitempty"`
MontocuErogacion *decimal.Decimal `json:"montocu_erogacion,omitempty"`
Porcentaje *decimal.Decimal `json:"porcentaje,omitempty"`
DocumentoRelacionado []GastosHidrocarburosDocumentoRelacionado `json:"documento_relacionado,omitempty"`
Actividades []GastosHidrocarburosActividades `json:"actividades,omitempty"`
CentroCostos []GastosHidrocarburosCentroCostos `json:"centro_costos,omitempty"`
}
GastosHidrocarburosErogacion es el nodo gceh:Erogacion del complemento GastosHidrocarburos.
type GastosHidrocarburosPozos ¶
type GastosHidrocarburosPozos struct {
Pozo string `json:"pozo,omitempty"`
}
GastosHidrocarburosPozos es el nodo gceh:Pozos del complemento GastosHidrocarburos.
type GastosHidrocarburosSubActividades ¶
type GastosHidrocarburosSubActividades struct {
SubActividadRelacionada string `json:"sub_actividad_relacionada,omitempty"`
Tareas []GastosHidrocarburosTareas `json:"tareas,omitempty"`
}
GastosHidrocarburosSubActividades es el nodo gceh:SubActividades del complemento GastosHidrocarburos.
type GastosHidrocarburosTareas ¶
type GastosHidrocarburosTareas struct {
TareaRelacionada string `json:"tarea_relacionada,omitempty"`
}
GastosHidrocarburosTareas es el nodo gceh:Tareas del complemento GastosHidrocarburos.
type GastosHidrocarburosYacimientos ¶
type GastosHidrocarburosYacimientos struct {
Yacimiento string `json:"yacimiento,omitempty"`
Pozos []GastosHidrocarburosPozos `json:"pozos,omitempty"`
}
GastosHidrocarburosYacimientos es el nodo gceh:Yacimientos del complemento GastosHidrocarburos.
type GuiasIdentificacion ¶
type GuiasIdentificacion struct {
NumeroGuiaIdentificacion string `json:"numero_guia_identificacion,omitempty"`
DescripGuiaIdentificacion string `json:"descrip_guia_identificacion,omitempty"`
PesoGuiaIdentificacion *decimal.Decimal `json:"peso_guia_identificacion,omitempty"`
}
GuiasIdentificacion es el nodo GuiasIdentificacion de una Mercancia del complemento CartaPorte.
type Hallazgo ¶
type Hallazgo struct {
// Codigo es estable entre versiones (sirve para agrupar en lote): uno
// de los Esquema* o Regla*.
Codigo string `json:"codigo"`
// Nivel es NivelError (el documento incumple), NivelAdvertencia
// (incumple una regla sin fuente citable que la haga obligatoria: puede
// estar mal, no se afirma) o NivelAviso (una parte del documento no se
// pudo validar; no dice que esté mal).
Nivel string `json:"nivel"`
Ruta string `json:"ruta,omitempty"`
Atributo string `json:"atributo,omitempty"`
// Valor es el texto original del atributo en los hallazgos de valores.
Valor string `json:"valor,omitempty"`
// Regla es la norma concreta: en el esquema, la faceta o restricción
// XSD ("pattern", "enumeration", "minOccurs", "orden"…); en las reglas,
// la referencia a la fuente (ver ValidarReglas).
Regla string `json:"regla"`
// Mensaje es para personas y puede cambiar.
Mensaje string `json:"mensaje,omitempty"`
}
Hallazgo es una violación de una norma encontrada al validar: del esquema XSD del SAT (ValidarEsquema) o de una regla aritmética o de coherencia (ValidarReglas).
Es un tipo propio y no Advertencia porque dicen cosas distintas: una Advertencia cuenta qué tuvo que hacer la lectura tolerante para leer el documento (se lee igual), un Hallazgo dice qué norma incumple (el SAT lo rechazaría). Un CFDI puede leerse sin una sola advertencia y tener hallazgos, y al revés. Lo que sí comparten es la forma de señalar el lugar: Ruta y Atributo siguen exactamente el contrato de Advertencia (nombres locales, índices [n] en los nodos que el esquema deja repetir, "/@Atributo" al final), así que un mismo nodo se busca igual en las dos listas.
func ValidarReglas ¶
func ValidarReglas(c *Comprobante) []Hallazgo
ValidarReglas evalúa las reglas aritméticas y de coherencia que se pueden comprobar sin red ni catálogos externos (ver Reglas): importes de los conceptos y de sus impuestos con los límites del Anexo 20, SubTotal, Descuento, Total, totales de impuestos agrupados por impuesto, tipo de factor y tasa, decimales y tipo de cambio según la moneda, reglas por TipoDeComprobante, ImpuestosLocales, Pagos 1.0 y 2.0, Comercio Exterior 2.0 y Nómina 1.2. Todo con decimal, sin float.
Es aparte de ValidarEsquema y trabaja sobre el Comprobante, no sobre los bytes: las reglas son de valores (montos ya leídos como decimales) y no de la forma del documento; y quien ya hizo Parse no relee el XML. Usan el mismo tipo Hallazgo con el mismo contrato de Ruta, así que se pueden juntar en una lista.
Cada hallazgo lleva el nivel de su regla (Regla.Nivel): error si la regla tiene fundamento en un documento oficial del SAT, advertencia si no; las advertencias no hacen inválido el documento (EstadoDe). Las reglas con Regla.Margen tienen dos niveles: lo que no cumple la letra del SAT pero cae en el margen de redondeo por concepto sale como advertencia.
Una regla que necesita un valor ausente o ilegible no se evalúa: de eso avisan la lectura (Advertencias) y ValidarEsquema. CFDI 3.3 y 4.0; otra versión da un solo aviso ReglaVersionNoSoportada. Las reglas propias de 4.0 (ObjetoImp, Base de los traslados del comprobante, Pagos 2.0, Comercio Exterior 2.0) solo se evalúan en 4.0; las de Pagos 1.0, solo en 3.3.
Nunca devuelve nil: sin hallazgos es una lista vacía.
type HidroYPetro ¶
type HidroYPetro struct {
Version string `json:"version,omitempty"`
TipoPermiso string `json:"tipo_permiso,omitempty"`
NumeroPermiso string `json:"numero_permiso,omitempty"`
ClaveHYP string `json:"clave_hyp,omitempty"`
SubProductoHYP string `json:"sub_producto_hyp,omitempty"`
}
HidroYPetro 1.0 (hidrocarburospetroliferos): permiso de la operación con hidrocarburos o petrolíferos. El XSD lo define como complemento de concepto; si viene en el Complemento del comprobante también se lee (Comprobante.HidroYPetro).
type HorasExtra ¶
type HorasExtra struct {
Dias string `json:"dias,omitempty"`
TipoHoras string `json:"tipo_horas,omitempty"`
HorasExtra string `json:"horas_extra,omitempty"`
ImportePagado *decimal.Decimal `json:"importe_pagado,omitempty"`
}
HorasExtra es el nodo nomina12:HorasExtra de una Percepcion del complemento Nómina.
type INE ¶
type INE struct {
Version string `json:"version,omitempty"`
TipoProceso string `json:"tipo_proceso,omitempty"`
TipoComite string `json:"tipo_comite,omitempty"`
IdContabilidad string `json:"id_contabilidad,omitempty"`
Entidad []INEEntidad `json:"entidad,omitempty"`
}
INE 1.1 y 1.0 (ine): proceso electoral. Comparten namespace y nodos; 1.1 solo admite más entidades.
type INEContabilidad ¶
type INEContabilidad struct {
IdContabilidad string `json:"id_contabilidad,omitempty"`
}
INEContabilidad es el nodo ine:Contabilidad de una Entidad del complemento INE.
type INEEntidad ¶
type INEEntidad struct {
ClaveEntidad string `json:"clave_entidad,omitempty"`
Ambito string `json:"ambito,omitempty"`
Contabilidad []INEContabilidad `json:"contabilidad,omitempty"`
}
INEEntidad es el nodo ine:Entidad del complemento INE.
type IdentificacionVehicular ¶
type IdentificacionVehicular struct {
ConfigVehicular string `json:"config_vehicular,omitempty"`
PesoBrutoVehicular *decimal.Decimal `json:"peso_bruto_vehicular,omitempty"` // 3.x
PlacaVM string `json:"placa_vm,omitempty"`
AnioModeloVM string `json:"anio_modelo_vm,omitempty"`
}
IdentificacionVehicular es el nodo IdentificacionVehicular del Autotransporte del complemento CartaPorte.
type ImpRetenidos ¶
type ImpRetenidos struct {
BaseRet *decimal.Decimal `json:"base_ret,omitempty"`
ImpuestoRet string `json:"impuesto_ret,omitempty"`
MontoRet *decimal.Decimal `json:"monto_ret,omitempty"`
TipoPagoRet string `json:"tipo_pago_ret,omitempty"`
}
ImpRetenidos es el nodo retenciones:ImpRetenidos de los Totales del CFDI de Retenciones.
type Impuesto ¶
type Impuesto struct {
Base *decimal.Decimal `json:"base,omitempty"`
Impuesto string `json:"impuesto,omitempty"`
TipoFactor string `json:"tipo_factor,omitempty"`
TasaOCuota *decimal.Decimal `json:"tasa_o_cuota,omitempty"`
// Tasa en porcentaje (16.00): solo en los traslados del
// EstadoDeCuentaCombustible sin versión (ecc). El tasa de los traslados
// de CFDI 3.2 no se lee.
Tasa *decimal.Decimal `json:"tasa,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
}
Impuesto es un Traslado o una Retencion, del concepto o del comprobante. Con TipoFactor "Exento" no hay TasaOCuota ni Importe (nil).
type ImpuestoDR ¶
type ImpuestoDR struct {
BaseDR *decimal.Decimal `json:"base_dr,omitempty"`
ImpuestoDR string `json:"impuesto_dr,omitempty"`
TipoFactorDR string `json:"tipo_factor_dr,omitempty"`
TasaOCuotaDR *decimal.Decimal `json:"tasa_o_cuota_dr,omitempty"`
ImporteDR *decimal.Decimal `json:"importe_dr,omitempty"`
}
ImpuestoDR es un nodo pago20:RetencionDR o pago20:TrasladoDR de ImpuestosDR, en el complemento Pagos 2.0.
type ImpuestoP ¶
type ImpuestoP struct {
BaseP *decimal.Decimal `json:"base_p,omitempty"`
ImpuestoP string `json:"impuesto_p,omitempty"`
TipoFactorP string `json:"tipo_factor_p,omitempty"`
TasaOCuotaP *decimal.Decimal `json:"tasa_o_cuota_p,omitempty"`
ImporteP *decimal.Decimal `json:"importe_p,omitempty"`
}
ImpuestoP es un nodo pago20:RetencionP o pago20:TrasladoP de ImpuestosP, en el complemento Pagos 2.0.
type ImpuestoTerceros ¶
type ImpuestoTerceros struct {
Impuesto string `json:"impuesto,omitempty"`
Tasa *decimal.Decimal `json:"tasa,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
}
ImpuestoTerceros: Impuesto va por nombre (ISR, IVA, IEPS); las retenciones no llevan Tasa.
type Impuestos ¶
type Impuestos struct {
TotalImpuestosRetenidos *decimal.Decimal `json:"total_impuestos_retenidos,omitempty"`
TotalImpuestosTrasladados *decimal.Decimal `json:"total_impuestos_trasladados,omitempty"`
Retenciones []Impuesto `json:"retenciones,omitempty"`
Traslados []Impuesto `json:"traslados,omitempty"`
}
Impuestos son los totales de impuestos del comprobante. El mismo struct sirve para el nodo Impuestos de un Pago 1.0.
type ImpuestosConcepto ¶
type ImpuestosConcepto struct {
Traslados []Impuesto `json:"traslados,omitempty"`
Retenciones []Impuesto `json:"retenciones,omitempty"`
}
ImpuestosConcepto son los traslados y retenciones de un concepto.
type ImpuestosDR ¶
type ImpuestosDR struct {
RetencionesDR []ImpuestoDR `json:"retenciones_dr,omitempty"`
TrasladosDR []ImpuestoDR `json:"traslados_dr,omitempty"`
}
ImpuestosDR es el nodo pago20:ImpuestosDR de un DoctoRelacionado del complemento Pagos 2.0.
type ImpuestosLocales ¶
type ImpuestosLocales struct {
Version string `json:"version,omitempty"`
TotaldeRetenciones *decimal.Decimal `json:"totalde_retenciones,omitempty"`
TotaldeTraslados *decimal.Decimal `json:"totalde_traslados,omitempty"`
// El XSD repite la secuencia (RetencionesLocales?, TrasladosLocales?):
// cada uno puede venir varias veces.
RetencionesLocales []RetencionesLocales `json:"retenciones_locales,omitempty"`
TrasladosLocales []TrasladosLocales `json:"traslados_locales,omitempty"`
}
ImpuestosLocales 1.0 (implocal). Los importes locales no están en Comprobante.Impuestos pero sí en el Total:
Total = SubTotal - Descuento + TotalImpuestosTrasladados - TotalImpuestosRetenidos
+ TotaldeTraslados - TotaldeRetenciones
type ImpuestosP ¶
type ImpuestosP struct {
RetencionesP []ImpuestoP `json:"retenciones_p,omitempty"`
TrasladosP []ImpuestoP `json:"traslados_p,omitempty"`
}
ImpuestosP es el nodo pago20:ImpuestosP de un Pago del complemento Pagos 2.0.
type ImpuestosTerceros ¶
type ImpuestosTerceros struct {
Retenciones []ImpuestoTerceros `json:"retenciones,omitempty"`
Traslados []ImpuestoTerceros `json:"traslados,omitempty"`
}
ImpuestosTerceros es el nodo terceros:Impuestos del complemento de concepto PorCuentadeTerceros.
type ImpuestosTrasladadosdelServicio ¶
type ImpuestosTrasladadosdelServicio struct {
Base *decimal.Decimal `json:"base,omitempty"`
Impuesto string `json:"impuesto,omitempty"`
TipoFactor string `json:"tipo_factor,omitempty"`
TasaCuota *decimal.Decimal `json:"tasa_cuota,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
}
ImpuestosTrasladadosdelServicio es el nodo plataformasTecnologicas:ImpuestosTrasladadosdelServicio de un DetallesDelServicio.
type Incapacidad ¶
type Incapacidad struct {
DiasIncapacidad string `json:"dias_incapacidad,omitempty"`
TipoIncapacidad string `json:"tipo_incapacidad,omitempty"`
ImporteMonetario *decimal.Decimal `json:"importe_monetario,omitempty"`
Descuento *decimal.Decimal `json:"descuento,omitempty"` // 1.1
}
Incapacidad es el nodo nomina12:Incapacidad del complemento Nómina.
type InformacionAduanera ¶
type InformacionAduanera struct {
NumeroPedimento string `json:"numero_pedimento,omitempty"`
}
InformacionAduanera es el nodo cfdi:InformacionAduanera de un concepto o de una parte.
type InformacionAduaneraComplemento ¶
type InformacionAduaneraComplemento struct {
Numero string `json:"numero,omitempty"`
Fecha Fecha `json:"fecha,omitzero"`
Aduana string `json:"aduana,omitempty"`
}
InformacionAduaneraComplemento es el t_InformacionAduanera de terceros y ventavehiculos: pedimento con fecha y aduana. No es la InformacionAduanera del concepto (solo NumeroPedimento).
type InformacionGlobal ¶
type InformacionGlobal struct {
Periodicidad string `json:"periodicidad,omitempty"`
Meses string `json:"meses,omitempty"`
Anio string `json:"anio,omitempty"` // atributo "Año"
}
InformacionGlobal (4.0) para CFDI a público en general.
type IngresosHidrocarburos ¶
type IngresosHidrocarburos struct {
Version string `json:"version,omitempty"`
NumeroContrato string `json:"numero_contrato,omitempty"`
ContraprestacionPagadaOperador *decimal.Decimal `json:"contraprestacion_pagada_operador,omitempty"`
Porcentaje *decimal.Decimal `json:"porcentaje,omitempty"`
DocumentoRelacionado []IngresosHidrocarburosDocumentoRelacionado `json:"documento_relacionado,omitempty"`
}
IngresosHidrocarburos 1.0 (IngresosHidrocarburos10).
type IngresosHidrocarburosDocumentoRelacionado ¶
type IngresosHidrocarburosDocumentoRelacionado struct {
FolioFiscalVinculado string `json:"folio_fiscal_vinculado,omitempty"`
FechaFolioFiscalVinculado Fecha `json:"fecha_folio_fiscal_vinculado,omitzero"`
Mes string `json:"mes,omitempty"`
}
IngresosHidrocarburosDocumentoRelacionado es el nodo ieeh:DocumentoRelacionado del complemento IngresosHidrocarburos.
type IngresosOEntradas ¶
type IngresosOEntradas struct {
MontTotEntradasPeriodo *decimal.Decimal `json:"mont_tot_entradas_periodo,omitempty"`
PartPropAcumDelFideicom *decimal.Decimal `json:"part_prop_acum_del_fideicom,omitempty"`
PropDelMontTot *decimal.Decimal `json:"prop_del_mont_tot,omitempty"`
// IntegracIngresos/@Concepto.
IntegracIngresos string `json:"integrac_ingresos,omitempty"`
}
IngresosOEntradas es el nodo fideicomisonoempresarial:IngresosOEntradas del complemento Fideicomisonoempresarial.
type InstEducativas ¶
type InstEducativas struct {
Version string `json:"version,omitempty"`
NombreAlumno string `json:"nombre_alumno,omitempty"`
CURP string `json:"curp,omitempty"`
NivelEducativo string `json:"nivel_educativo,omitempty"`
AutRVOE string `json:"aut_rvoe,omitempty"`
RfcPago string `json:"rfc_pago,omitempty"`
}
InstEducativas 1.0 (iedu): colegiatura de una institución educativa privada. El nodo del SAT es instEducativas, en minúscula.
type Intereses ¶
type Intereses struct {
Version string `json:"version,omitempty"`
SistFinanciero string `json:"sist_financiero,omitempty"`
RetiroAORESRetInt string `json:"retiro_aores_ret_int,omitempty"`
OperFinancDerivad string `json:"oper_financ_derivad,omitempty"`
MontIntNominal *decimal.Decimal `json:"mont_int_nominal,omitempty"`
MontIntReal *decimal.Decimal `json:"mont_int_real,omitempty"`
Perdida *decimal.Decimal `json:"perdida,omitempty"`
}
Intereses es el complemento de Retenciones intereses:Intereses.
type Intereseshipotecarios ¶
type Intereseshipotecarios struct {
Version string `json:"version,omitempty"`
CreditoDeInstFinanc string `json:"credito_de_inst_financ,omitempty"`
SaldoInsoluto *decimal.Decimal `json:"saldo_insoluto,omitempty"`
PropDeducDelCredit *decimal.Decimal `json:"prop_deduc_del_credit,omitempty"`
MontTotIntNominalesDev *decimal.Decimal `json:"mont_tot_int_nominales_dev,omitempty"`
MontTotIntNominalesDevYPag *decimal.Decimal `json:"mont_tot_int_nominales_dev_y_pag,omitempty"`
MontTotIntRealPagDeduc *decimal.Decimal `json:"mont_tot_int_real_pag_deduc,omitempty"`
NumContrato string `json:"num_contrato,omitempty"`
}
Intereseshipotecarios es el complemento de Retenciones intereseshipotecarios:Intereseshipotecarios.
type JubilacionPensionRetiro ¶
type JubilacionPensionRetiro struct {
TotalUnaExhibicion *decimal.Decimal `json:"total_una_exhibicion,omitempty"`
TotalParcialidad *decimal.Decimal `json:"total_parcialidad,omitempty"`
MontoDiario *decimal.Decimal `json:"monto_diario,omitempty"`
IngresoAcumulable *decimal.Decimal `json:"ingreso_acumulable,omitempty"`
IngresoNoAcumulable *decimal.Decimal `json:"ingreso_no_acumulable,omitempty"`
}
JubilacionPensionRetiro es el nodo nomina12:JubilacionPensionRetiro de las Percepciones del complemento Nómina.
type Leyenda ¶
type Leyenda struct {
DisposicionFiscal string `json:"disposicion_fiscal,omitempty"`
Norma string `json:"norma,omitempty"`
TextoLeyenda string `json:"texto_leyenda,omitempty"`
}
Leyenda es el nodo leyendasFisc:Leyenda del complemento LeyendasFiscales.
type LeyendasFiscales ¶
type LeyendasFiscales struct {
Version string `json:"version,omitempty"`
Leyenda []Leyenda `json:"leyenda,omitempty"`
}
LeyendasFiscales 1.0.
type NoBeneficiarioExtranjero ¶
type NoBeneficiarioExtranjero struct {
PaisDeResidParaEfecFisc string `json:"pais_de_resid_para_efec_fisc,omitempty"`
ConceptoPago string `json:"concepto_pago,omitempty"`
DescripcionConcepto string `json:"descripcion_concepto,omitempty"`
}
NoBeneficiarioExtranjero es el nodo pagosaextranjeros:NoBeneficiario del complemento Pagosaextranjeros.
type Nomina ¶
type Nomina struct {
Version string `json:"version,omitempty"`
TipoNomina string `json:"tipo_nomina,omitempty"`
RegistroPatronal string `json:"registro_patronal,omitempty"` // 1.1
NumEmpleado string `json:"num_empleado,omitempty"` // 1.1
CURP string `json:"curp,omitempty"` // 1.1
TipoRegimen string `json:"tipo_regimen,omitempty"` // 1.1
NumSeguridadSocial string `json:"num_seguridad_social,omitempty"` // 1.1
FechaPago Fecha `json:"fecha_pago,omitzero"`
FechaInicialPago Fecha `json:"fecha_inicial_pago,omitzero"`
FechaFinalPago Fecha `json:"fecha_final_pago,omitzero"`
NumDiasPagados *decimal.Decimal `json:"num_dias_pagados,omitempty"`
TotalPercepciones *decimal.Decimal `json:"total_percepciones,omitempty"`
TotalDeducciones *decimal.Decimal `json:"total_deducciones,omitempty"`
TotalOtrosPagos *decimal.Decimal `json:"total_otros_pagos,omitempty"`
// 1.1: el resto de los atributos del trabajador. Antiguedad son semanas
// (un entero), no la duración P…W de 1.2.
Departamento string `json:"departamento,omitempty"`
CLABE string `json:"clabe,omitempty"`
Banco string `json:"banco,omitempty"`
FechaInicioRelLaboral Fecha `json:"fecha_inicio_rel_laboral,omitzero"`
Antiguedad string `json:"antiguedad,omitempty"`
Puesto string `json:"puesto,omitempty"`
TipoContrato string `json:"tipo_contrato,omitempty"`
TipoJornada string `json:"tipo_jornada,omitempty"`
PeriodicidadPago string `json:"periodicidad_pago,omitempty"`
SalarioBaseCotApor *decimal.Decimal `json:"salario_base_cot_apor,omitempty"`
RiesgoPuesto string `json:"riesgo_puesto,omitempty"`
SalarioDiarioIntegrado *decimal.Decimal `json:"salario_diario_integrado,omitempty"`
Emisor *NominaEmisor `json:"emisor,omitempty"`
Receptor *NominaReceptor `json:"receptor,omitempty"`
Percepciones *Percepciones `json:"percepciones,omitempty"`
Deducciones *Deducciones `json:"deducciones,omitempty"`
OtrosPagos []OtroPago `json:"otros_pagos,omitempty"`
Incapacidades []Incapacidad `json:"incapacidades,omitempty"`
HorasExtras []HorasExtra `json:"horas_extras,omitempty"` // 1.1: HorasExtras/HorasExtra
}
Nomina es el complemento de nómina 1.2 o 1.1 (CFDI 3.2), normalizados en un solo struct; Version dice cuál. 1.1 lleva los datos del trabajador como atributos del nodo Nomina (los campos marcados 1.1, vacíos en 1.2) y no tiene Emisor, Receptor, OtrosPagos ni los totales de 1.2. Cada atributo queda donde lo pone su XSD: un 1.1 no llena Receptor.
type NominaEmisor ¶
type NominaEmisor struct {
Curp string `json:"curp,omitempty"`
RegistroPatronal string `json:"registro_patronal,omitempty"`
RfcPatronOrigen string `json:"rfc_patron_origen,omitempty"`
EntidadSNCF *EntidadSNCF `json:"entidad_sncf,omitempty"`
}
NominaEmisor es el nodo nomina12:Emisor del complemento Nómina.
type NominaReceptor ¶
type NominaReceptor struct {
Curp string `json:"curp,omitempty"`
NumSeguridadSocial string `json:"num_seguridad_social,omitempty"`
FechaInicioRelLaboral Fecha `json:"fecha_inicio_rel_laboral,omitzero"`
Antiguedad string `json:"antiguedad,omitempty"` // atributo "Antigüedad"
TipoContrato string `json:"tipo_contrato,omitempty"`
Sindicalizado string `json:"sindicalizado,omitempty"`
TipoJornada string `json:"tipo_jornada,omitempty"`
TipoRegimen string `json:"tipo_regimen,omitempty"`
NumEmpleado string `json:"num_empleado,omitempty"`
Departamento string `json:"departamento,omitempty"`
Puesto string `json:"puesto,omitempty"`
RiesgoPuesto string `json:"riesgo_puesto,omitempty"`
PeriodicidadPago string `json:"periodicidad_pago,omitempty"`
Banco string `json:"banco,omitempty"`
CuentaBancaria string `json:"cuenta_bancaria,omitempty"`
SalarioBaseCotApor *decimal.Decimal `json:"salario_base_cot_apor,omitempty"`
SalarioDiarioIntegrado *decimal.Decimal `json:"salario_diario_integrado,omitempty"`
ClaveEntFed string `json:"clave_ent_fed,omitempty"`
SubContratacion []SubContratacion `json:"sub_contratacion,omitempty"`
}
NominaReceptor es el nodo nomina12:Receptor del complemento Nómina.
type NotariosPublicos ¶
type NotariosPublicos struct {
Version string `json:"version,omitempty"`
DescInmuebles []NotariosPublicosDescInmueble `json:"desc_inmuebles,omitempty"`
DatosOperacion *NotariosPublicosDatosOperacion `json:"datos_operacion,omitempty"`
DatosNotario *NotariosPublicosDatosNotario `json:"datos_notario,omitempty"`
DatosEnajenante *NotariosPublicosDatosEnajenante `json:"datos_enajenante,omitempty"`
DatosAdquiriente *NotariosPublicosDatosAdquiriente `json:"datos_adquiriente,omitempty"`
}
NotariosPublicos 1.0: enajenación de inmuebles ante notario. DescInmuebles aplana DescInmuebles/DescInmueble.
type NotariosPublicosDatosAdquiriente ¶
type NotariosPublicosDatosAdquiriente struct {
CoproSocConyugalE string `json:"copro_soc_conyugal_e,omitempty"`
DatosUnAdquiriente *NotariosPublicosDatosPersona `json:"datos_un_adquiriente,omitempty"`
DatosAdquirientesCopSC []NotariosPublicosDatosCopropietario `json:"datos_adquirientes_cop_sc,omitempty"`
}
NotariosPublicosDatosAdquiriente es como DatosEnajenante, con los adquirientes.
type NotariosPublicosDatosCopropietario ¶
type NotariosPublicosDatosCopropietario struct {
Nombre string `json:"nombre,omitempty"`
ApellidoPaterno string `json:"apellido_paterno,omitempty"`
ApellidoMaterno string `json:"apellido_materno,omitempty"`
RFC string `json:"rfc,omitempty"`
CURP string `json:"curp,omitempty"`
Porcentaje *decimal.Decimal `json:"porcentaje,omitempty"`
}
NotariosPublicosDatosCopropietario es DatosEnajenanteCopSC o DatosAdquirienteCopSC.
type NotariosPublicosDatosEnajenante ¶
type NotariosPublicosDatosEnajenante struct {
CoproSocConyugalE string `json:"copro_soc_conyugal_e,omitempty"`
DatosUnEnajenante *NotariosPublicosDatosPersona `json:"datos_un_enajenante,omitempty"`
DatosEnajenantesCopSC []NotariosPublicosDatosCopropietario `json:"datos_enajenantes_cop_sc,omitempty"`
}
NotariosPublicosDatosEnajenante trae uno de dos: DatosUnEnajenante, o la lista de copropietarios DatosEnajenantesCopSC (aplanada).
type NotariosPublicosDatosNotario ¶
type NotariosPublicosDatosNotario struct {
CURP string `json:"curp,omitempty"`
NumNotaria string `json:"num_notaria,omitempty"`
EntidadFederativa string `json:"entidad_federativa,omitempty"`
Adscripcion string `json:"adscripcion,omitempty"`
}
NotariosPublicosDatosNotario es el nodo notariospublicos:DatosNotario del complemento NotariosPublicos.
type NotariosPublicosDatosOperacion ¶
type NotariosPublicosDatosOperacion struct {
NumInstrumentoNotarial string `json:"num_instrumento_notarial,omitempty"`
FechaInstNotarial Fecha `json:"fecha_inst_notarial,omitzero"`
MontoOperacion *decimal.Decimal `json:"monto_operacion,omitempty"`
Subtotal *decimal.Decimal `json:"subtotal,omitempty"`
IVA *decimal.Decimal `json:"iva,omitempty"`
}
NotariosPublicosDatosOperacion es el nodo notariospublicos:DatosOperacion del complemento NotariosPublicos.
type NotariosPublicosDatosPersona ¶
type NotariosPublicosDatosPersona struct {
Nombre string `json:"nombre,omitempty"`
ApellidoPaterno string `json:"apellido_paterno,omitempty"`
ApellidoMaterno string `json:"apellido_materno,omitempty"`
RFC string `json:"rfc,omitempty"`
CURP string `json:"curp,omitempty"`
}
NotariosPublicosDatosPersona es DatosUnEnajenante o DatosUnAdquiriente (mismos atributos; el XSD exige más en el enajenante).
type NotariosPublicosDescInmueble ¶
type NotariosPublicosDescInmueble struct {
TipoInmueble string `json:"tipo_inmueble,omitempty"`
Calle string `json:"calle,omitempty"`
NoExterior string `json:"no_exterior,omitempty"`
NoInterior string `json:"no_interior,omitempty"`
Colonia string `json:"colonia,omitempty"`
Localidad string `json:"localidad,omitempty"`
Referencia string `json:"referencia,omitempty"`
Municipio string `json:"municipio,omitempty"`
Estado string `json:"estado,omitempty"`
Pais string `json:"pais,omitempty"`
CodigoPostal string `json:"codigo_postal,omitempty"`
}
NotariosPublicosDescInmueble es el nodo notariospublicos:DescInmueble del complemento NotariosPublicos.
type ObrasArteAntiguedades ¶
type ObrasArteAntiguedades struct {
Version string `json:"version,omitempty"`
TipoBien string `json:"tipo_bien,omitempty"`
OtrosTipoBien string `json:"otros_tipo_bien,omitempty"`
TituloAdquirido string `json:"titulo_adquirido,omitempty"`
OtrosTituloAdquirido string `json:"otros_titulo_adquirido,omitempty"`
Subtotal *decimal.Decimal `json:"subtotal,omitempty"`
IVA *decimal.Decimal `json:"iva,omitempty"`
FechaAdquisicion Fecha `json:"fecha_adquisicion,omitzero"`
CaracteristicasDeObraoPieza string `json:"caracteristicas_de_obrao_pieza,omitempty"` // atributo "CaracterísticasDeObraoPieza"
}
ObrasArteAntiguedades 1.0 (nodo obrasarteantiguedades).
type Opciones ¶
type Opciones struct {
// FechaEstricta solo interpreta las fechas que vienen exactamente en el
// formato del SAT (AAAA-MM-DDThh:mm:ss, o AAAA-MM-DD en los campos de
// solo fecha). Las demás se quedan con Time en cero (Fecha.Valida() da
// false), Fecha.FueraDeFormato en true, y la advertencia es
// FECHA_INVALIDA en vez de FECHA_FORMATO.
FechaEstricta bool
}
Opciones ajusta la lectura. El valor cero es la lectura tolerante de Parse y ParseBytes.
Es un struct (y no opciones funcionales) por lo mismo que OpcionesJSON: son interruptores independientes, el valor cero es el comportamiento de siempre y un campo nuevo no rompe a nadie.
type OpcionesJSON ¶
type OpcionesJSON struct {
// IncluirSello conserva Sello, Certificado, SelloCFD, SelloSAT, los
// sellos/certificados/cadenas de los pagos y el sello y la cadena de
// cada SPEI_Tercero. Por omisión se quitan: pesan varios KB y no aportan
// a quien solo quiere los datos.
IncluirSello bool
// Indentar con dos espacios.
Indentar bool
}
OpcionesJSON ajusta la salida JSON.
type Operacionesconderivados ¶
type Operacionesconderivados struct {
Version string `json:"version,omitempty"`
MontGanAcum *decimal.Decimal `json:"mont_gan_acum,omitempty"`
MontPerdDed *decimal.Decimal `json:"mont_perd_ded,omitempty"`
}
Operacionesconderivados es el complemento de Retenciones operacionesconderivados:Operacionesconderivados.
type OtroPago ¶
type OtroPago struct {
TipoOtroPago string `json:"tipo_otro_pago,omitempty"`
Clave string `json:"clave,omitempty"`
Concepto string `json:"concepto,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
SubsidioAlEmpleo *SubsidioAlEmpleo `json:"subsidio_al_empleo,omitempty"`
CompensacionSaldosAFavor *CompensacionSaldosAFavor `json:"compensacion_saldos_a_favor,omitempty"`
}
OtroPago es el nodo nomina12:OtroPago del complemento Nómina.
type PFintegranteCoordinado ¶
type PFintegranteCoordinado struct {
Version string `json:"version,omitempty"`
ClaveVehicular string `json:"clave_vehicular,omitempty"`
Placa string `json:"placa,omitempty"`
RFCPF string `json:"rfcpf,omitempty"`
}
PFintegranteCoordinado 1.0 (pfic): persona física integrante de una coordinación de autotransporte.
type Pago ¶
type Pago struct {
FechaPago Fecha `json:"fecha_pago,omitzero"`
FormaDePagoP string `json:"forma_de_pago_p,omitempty"`
MonedaP string `json:"moneda_p,omitempty"`
TipoCambioP *decimal.Decimal `json:"tipo_cambio_p,omitempty"`
Monto *decimal.Decimal `json:"monto,omitempty"`
NumOperacion string `json:"num_operacion,omitempty"`
RfcEmisorCtaOrd string `json:"rfc_emisor_cta_ord,omitempty"`
NomBancoOrdExt string `json:"nom_banco_ord_ext,omitempty"`
CtaOrdenante string `json:"cta_ordenante,omitempty"`
RfcEmisorCtaBen string `json:"rfc_emisor_cta_ben,omitempty"`
CtaBeneficiario string `json:"cta_beneficiario,omitempty"`
TipoCadPago string `json:"tipo_cad_pago,omitempty"`
CertPago string `json:"cert_pago,omitempty"`
CadPago string `json:"cad_pago,omitempty"`
SelloPago string `json:"sello_pago,omitempty"`
DoctoRelacionado []DoctoRelacionado `json:"docto_relacionado,omitempty"`
ImpuestosP *ImpuestosP `json:"impuestos_p,omitempty"` // 2.0
Impuestos []Impuestos `json:"impuestos,omitempty"` // 1.0
}
Pago es el nodo Pago del complemento Pagos (pago10:Pago o pago20:Pago).
type PagoEnEspecie ¶
type PagoEnEspecie struct {
Version string `json:"version,omitempty"`
CvePIC string `json:"cve_pic,omitempty"`
FolioSolDon string `json:"folio_sol_don,omitempty"`
PzaArtNombre string `json:"pza_art_nombre,omitempty"`
PzaArtTecn string `json:"pza_art_tecn,omitempty"`
PzaArtAProd string `json:"pza_art_a_prod,omitempty"`
PzaArtDim string `json:"pza_art_dim,omitempty"`
}
PagoEnEspecie 1.0: donación de obras de arte en pago en especie.
type Pagos ¶
type Pagos struct {
Version string `json:"version,omitempty"`
Totales *TotalesPagos `json:"totales,omitempty"`
Pago []Pago `json:"pago,omitempty"`
}
Pagos es el complemento de recepción de pagos, 1.0 o 2.0 normalizados en un solo struct. Los campos que solo existen en una versión quedan vacíos en la otra (Totales, ImpuestosP, EquivalenciaDR, ObjetoImpDR, ImpuestosDR son de 2.0; TipoCambioDR, MetodoDePagoDR e Impuestos del pago son de 1.0).
type Pagosaextranjeros ¶
type Pagosaextranjeros struct {
Version string `json:"version,omitempty"`
EsBenefEfectDelCobro string `json:"es_benef_efect_del_cobro,omitempty"`
NoBeneficiario *NoBeneficiarioExtranjero `json:"no_beneficiario,omitempty"`
Beneficiario *BeneficiarioExtranjero `json:"beneficiario,omitempty"`
}
Pagosaextranjeros es el complemento de Retenciones pagosaextranjeros:Pagosaextranjeros.
type ParcialesConstruccion ¶
type ParcialesConstruccion struct {
Version string `json:"version,omitempty"`
NumPerLicoAut string `json:"num_per_lico_aut,omitempty"`
Inmueble *ParcialesConstruccionInmueble `json:"inmueble,omitempty"`
}
ParcialesConstruccion 1.0 (servicioparcialconstruccion, nodo parcialesconstruccion): servicios parciales de construcción de inmuebles destinados a casa habitación. El XSD lo pone en el Complemento del comprobante; si viene en un ComplementoConcepto también se lee, en el concepto.
type ParcialesConstruccionInmueble ¶
type ParcialesConstruccionInmueble struct {
Calle string `json:"calle,omitempty"`
NoExterior string `json:"no_exterior,omitempty"`
NoInterior string `json:"no_interior,omitempty"`
Colonia string `json:"colonia,omitempty"`
Localidad string `json:"localidad,omitempty"`
Referencia string `json:"referencia,omitempty"`
Municipio string `json:"municipio,omitempty"`
Estado string `json:"estado,omitempty"`
CodigoPostal string `json:"codigo_postal,omitempty"`
}
ParcialesConstruccionInmueble es el nodo servicioparcial:Inmueble del complemento de servicios parciales de construcción.
type Parte ¶
type Parte struct {
ClaveProdServ string `json:"clave_prod_serv,omitempty"`
NoIdentificacion string `json:"no_identificacion,omitempty"`
Cantidad *decimal.Decimal `json:"cantidad,omitempty"`
Unidad string `json:"unidad,omitempty"`
Descripcion string `json:"descripcion,omitempty"`
ValorUnitario *decimal.Decimal `json:"valor_unitario,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
InformacionAduanera []InformacionAduanera `json:"informacion_aduanera,omitempty"`
}
Parte es el nodo cfdi:Parte de un concepto.
type ParteComplemento ¶
type ParteComplemento struct {
Cantidad *decimal.Decimal `json:"cantidad,omitempty"`
Unidad string `json:"unidad,omitempty"`
NoIdentificacion string `json:"no_identificacion,omitempty"`
Descripcion string `json:"descripcion,omitempty"`
ValorUnitario *decimal.Decimal `json:"valor_unitario,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
InformacionAduanera []InformacionAduaneraComplemento `json:"informacion_aduanera,omitempty"`
}
ParteComplemento es la Parte de terceros y ventavehiculos.
type PartesTransporte ¶
type PartesTransporte struct {
ParteTransporte string `json:"parte_transporte,omitempty"`
}
PartesTransporte es el nodo PartesTransporte de TiposFigura del complemento CartaPorte.
type Pedimentos ¶
type Pedimentos struct {
Pedimento string `json:"pedimento,omitempty"`
}
Pedimentos es el nodo Pedimentos de una Mercancia del complemento CartaPorte.
type Percepcion ¶
type Percepcion struct {
TipoPercepcion string `json:"tipo_percepcion,omitempty"`
Clave string `json:"clave,omitempty"`
Concepto string `json:"concepto,omitempty"`
ImporteGravado *decimal.Decimal `json:"importe_gravado,omitempty"`
ImporteExento *decimal.Decimal `json:"importe_exento,omitempty"`
AccionesOTitulos *AccionesOTitulos `json:"acciones_o_titulos,omitempty"`
HorasExtra []HorasExtra `json:"horas_extra,omitempty"`
}
Percepcion es el nodo nomina12:Percepcion del complemento Nómina.
type Percepciones ¶
type Percepciones struct {
TotalSueldos *decimal.Decimal `json:"total_sueldos,omitempty"`
TotalSeparacionIndemnizacion *decimal.Decimal `json:"total_separacion_indemnizacion,omitempty"`
TotalJubilacionPensionRetiro *decimal.Decimal `json:"total_jubilacion_pension_retiro,omitempty"`
TotalGravado *decimal.Decimal `json:"total_gravado,omitempty"`
TotalExento *decimal.Decimal `json:"total_exento,omitempty"`
Percepcion []Percepcion `json:"percepcion,omitempty"`
JubilacionPensionRetiro *JubilacionPensionRetiro `json:"jubilacion_pension_retiro,omitempty"`
SeparacionIndemnizacion *SeparacionIndemnizacion `json:"separacion_indemnizacion,omitempty"`
}
Percepciones es el nodo nomina12:Percepciones del complemento Nómina.
type PeriodoRetenciones ¶
type PeriodoRetenciones struct {
MesIni string `json:"mes_ini,omitempty"`
MesFin string `json:"mes_fin,omitempty"`
Ejercicio string `json:"ejercicio,omitempty"`
}
PeriodoRetenciones: meses y ejercicio como texto, como los demás enteros del SAT.
type Planesderetiro ¶
type Planesderetiro struct {
Version string `json:"version,omitempty"`
SistemaFinanc string `json:"sistema_financ,omitempty"`
MontTotAportAnioInmAnterior *decimal.Decimal `json:"mont_tot_aport_anio_inm_anterior,omitempty"`
MontIntRealesDevengAniooInmAnt *decimal.Decimal `json:"mont_int_reales_deveng_anioo_inm_ant,omitempty"`
HuboRetirosAnioInmAntPer string `json:"hubo_retiros_anio_inm_ant_per,omitempty"`
MontTotRetiradoAnioInmAntPer *decimal.Decimal `json:"mont_tot_retirado_anio_inm_ant_per,omitempty"`
MontTotExentRetiradoAnioInmAnt *decimal.Decimal `json:"mont_tot_exent_retirado_anio_inm_ant,omitempty"`
MontTotExedenteAnioInmAnt *decimal.Decimal `json:"mont_tot_exedente_anio_inm_ant,omitempty"`
HuboRetirosAnioInmAnt string `json:"hubo_retiros_anio_inm_ant,omitempty"`
MontTotRetiradoAnioInmAnt *decimal.Decimal `json:"mont_tot_retirado_anio_inm_ant,omitempty"`
NumReferencia string `json:"num_referencia,omitempty"`
AportacionesODepositos []AportacionesODepositos `json:"aportaciones_o_depositos,omitempty"`
}
Planesderetiro 1.0 y 1.1 en un objeto con version: la 1.1 agrega AportacionesODepositos y NumReferencia, que vienen vacíos en la 1.0.
type PorCuentadeTerceros ¶
type PorCuentadeTerceros struct {
Version string `json:"version,omitempty"`
Rfc string `json:"rfc,omitempty"`
Nombre string `json:"nombre,omitempty"`
InformacionFiscalTercero *UbicacionFiscal `json:"informacion_fiscal_tercero,omitempty"`
InformacionAduanera *InformacionAduaneraComplemento `json:"informacion_aduanera,omitempty"`
Parte []ParteComplemento `json:"parte,omitempty"`
CuentaPredial *CuentaPredial `json:"cuenta_predial,omitempty"`
Impuestos *ImpuestosTerceros `json:"impuestos,omitempty"`
}
PorCuentadeTerceros 1.1 (terceros), de CFDI 3.3: el concepto se cobra por cuenta de un tercero. En 4.0 lo sustituye el nodo ACuentaTerceros.
type Premios ¶
type Premios struct {
Version string `json:"version,omitempty"`
EntidadFederativa string `json:"entidad_federativa,omitempty"`
MontTotPago *decimal.Decimal `json:"mont_tot_pago,omitempty"`
MontTotPagoGrav *decimal.Decimal `json:"mont_tot_pago_grav,omitempty"`
MontTotPagoExent *decimal.Decimal `json:"mont_tot_pago_exent,omitempty"`
}
Premios es el complemento de Retenciones premios:Premios.
type Receptor ¶
type Receptor struct {
Rfc string `json:"rfc,omitempty"`
Nombre string `json:"nombre,omitempty"`
DomicilioFiscalReceptor string `json:"domicilio_fiscal_receptor,omitempty"`
ResidenciaFiscal string `json:"residencia_fiscal,omitempty"`
NumRegIdTrib string `json:"num_reg_id_trib,omitempty"`
RegimenFiscalReceptor string `json:"regimen_fiscal_receptor,omitempty"`
UsoCFDI string `json:"uso_cfdi,omitempty"`
}
Receptor es el nodo cfdi:Receptor del comprobante.
type ReceptorExtranjeroRetenciones ¶
type ReceptorExtranjeroRetenciones struct {
NumRegIdTribR string `json:"num_reg_id_trib_r,omitempty"`
NomDenRazSocR string `json:"nom_den_raz_soc_r,omitempty"`
}
ReceptorExtranjeroRetenciones es el nodo retenciones:Extranjero del Receptor del CFDI de Retenciones.
type ReceptorNacionalRetenciones ¶
type ReceptorNacionalRetenciones struct {
RfcR string `json:"rfc_r,omitempty"`
NomDenRazSocR string `json:"nom_den_raz_soc_r,omitempty"`
CurpR string `json:"curp_r,omitempty"`
DomicilioFiscalR string `json:"domicilio_fiscal_r,omitempty"` // 2.0
}
ReceptorNacionalRetenciones es el nodo retenciones:Nacional del Receptor del CFDI de Retenciones.
type ReceptorRetenciones ¶
type ReceptorRetenciones struct {
NacionalidadR string `json:"nacionalidad_r,omitempty"`
Nacional *ReceptorNacionalRetenciones `json:"nacional,omitempty"`
Extranjero *ReceptorExtranjeroRetenciones `json:"extranjero,omitempty"`
}
ReceptorRetenciones trae Nacional o Extranjero según NacionalidadR.
type RegimenAduaneroCCP ¶
type RegimenAduaneroCCP struct {
RegimenAduanero string `json:"regimen_aduanero,omitempty"`
}
RegimenAduaneroCCP es el nodo RegimenAduaneroCCP de CartaPorte 3.1.
type Regla ¶
type Regla struct {
Codigo string `json:"codigo"`
// Nivel es NivelError si la regla tiene fundamento en un documento
// oficial del SAT (Citas: matriz de errores, estándar o guía de
// llenado); NivelAdvertencia si no lo tiene o si el SAT pide no
// aplicarla.
Nivel string `json:"nivel"`
// Referencia es el texto de Citas más las fuentes secundarias
// (CfdiUtils, satcfdi) cuando ayudan a entender la regla.
Referencia string `json:"referencia"`
Descripcion string `json:"descripcion"`
Citas []CitaSAT `json:"citas,omitempty"`
// Margen, si no está vacío, hace de la regla una de dos niveles: lo
// que no cumple la letra del SAT (Descripcion) pero cae dentro de
// Margen sale con NivelAdvertencia, con el mismo código y la misma
// referencia; lo que queda fuera también del margen, con Nivel. Lo
// llevan el Importe del impuesto del concepto y las sumas de impuestos:
// los PAC timbran documentos con un centavo de diferencia por el
// redondeo de cada concepto, y marcarlos como error engañaría a quien
// usa la librería.
Margen string `json:"margen,omitempty"`
// Vigencia, si no está vacía, dice qué partes de la regla son error
// solo desde una fecha: en un comprobante con Fecha anterior, el
// hallazgo de esas partes sale con NivelAdvertencia y el mensaje lo
// dice. Lo llevan las reglas de Nómina que el SAT agregó después de la
// primera versión del estándar.
Vigencia string `json:"vigencia,omitempty"`
// SoloGuia, si no está vacío, dice qué partes de la regla solo salen de
// la guía de llenado, sin código en la matriz de errores ni texto en el
// estándar: sus hallazgos salen con NivelAdvertencia.
SoloGuia string `json:"solo_guia,omitempty"`
}
Regla describe una regla de ValidarReglas: su código, el nivel de sus hallazgos, de dónde sale (la referencia que va en Hallazgo.Regla) y qué comprueba.
type Remolque ¶
type Remolque struct {
SubTipoRem string `json:"sub_tipo_rem,omitempty"`
Placa string `json:"placa,omitempty"`
}
Remolque es el nodo Remolque del Autotransporte del complemento CartaPorte.
type RemolqueCCP ¶
type RemolqueCCP struct {
SubTipoRemCCP string `json:"sub_tipo_rem_ccp,omitempty"`
PlacaCCP string `json:"placa_ccp,omitempty"`
}
RemolqueCCP es el nodo RemolqueCCP de un Contenedor marítimo de CartaPorte 3.1.
type RenovacionDecretoRenovVehicular ¶
type RenovacionDecretoRenovVehicular struct {
VehEnaj string `json:"veh_enaj,omitempty"`
VehiculosUsadosEnajenadoPermAlFab []RenovacionVehiculoUsado `json:"vehiculos_usados_enajenado_perm_al_fab,omitempty"`
VehiculoNuvoSemEnajenadoFabAlPerm *RenovacionVehiculoNuevo `json:"vehiculo_nuvo_sem_enajenado_fab_al_perm,omitempty"`
}
RenovacionDecretoRenovVehicular es el nodo decreto:DecretoRenovVehicular del complemento renovacionysustitucionvehiculos.
type RenovacionDecretoSustitVehicular ¶
type RenovacionDecretoSustitVehicular struct {
VehEnaj string `json:"veh_enaj,omitempty"`
VehiculoUsadoEnajenadoPermAlFab *RenovacionVehiculoUsado `json:"vehiculo_usado_enajenado_perm_al_fab,omitempty"`
VehiculoNuvoSemEnajenadoFabAlPerm *RenovacionVehiculoNuevo `json:"vehiculo_nuvo_sem_enajenado_fab_al_perm,omitempty"`
}
RenovacionDecretoSustitVehicular es el nodo decreto:DecretoSustitVehicular del complemento renovacionysustitucionvehiculos.
type RenovacionVehiculoNuevo ¶
type RenovacionVehiculoNuevo struct {
Anio string `json:"anio,omitempty"` // atributo "Año"
Modelo string `json:"modelo,omitempty"`
NumPlacas string `json:"num_placas,omitempty"`
RFC string `json:"rfc,omitempty"`
}
RenovacionVehiculoNuevo es el VehiculoNuvoSemEnajenadoFabAlPerm (así, sin e) de los dos decretos.
type RenovacionVehiculoUsado ¶
type RenovacionVehiculoUsado struct {
PrecioVehUsado *decimal.Decimal `json:"precio_veh_usado,omitempty"`
TipoVeh string `json:"tipo_veh,omitempty"`
Marca string `json:"marca,omitempty"`
TipooClase string `json:"tipoo_clase,omitempty"`
Anio string `json:"anio,omitempty"` // atributo "Año"
Modelo string `json:"modelo,omitempty"`
NIV string `json:"niv,omitempty"`
NumSerie string `json:"num_serie,omitempty"`
NumPlacas string `json:"num_placas,omitempty"`
NumMotor string `json:"num_motor,omitempty"`
NumFolTarjCir string `json:"num_fol_tarj_cir,omitempty"`
NumFolAvisoint string `json:"num_fol_avisoint,omitempty"` // solo sustitución
NumPedIm string `json:"num_ped_im,omitempty"`
Aduana string `json:"aduana,omitempty"`
FechaRegulVeh Fecha `json:"fecha_regul_veh,omitzero"`
Foliofiscal string `json:"foliofiscal,omitempty"`
}
RenovacionVehiculoUsado es un vehículo usado enajenado al fabricante: el de un decreto de sustitución trae además NumFolAvisoint y exige más.
type RenovacionySustitucionVehiculos ¶
type RenovacionySustitucionVehiculos struct {
Version string `json:"version,omitempty"`
TipoDeDecreto string `json:"tipo_de_decreto,omitempty"`
DecretoRenovVehicular *RenovacionDecretoRenovVehicular `json:"decreto_renov_vehicular,omitempty"`
DecretoSustitVehicular *RenovacionDecretoSustitVehicular `json:"decreto_sustit_vehicular,omitempty"`
}
RenovacionySustitucionVehiculos 1.0 (nodo renovacionysustitucionvehiculos): decretos de renovación (varios vehículos usados) o sustitución (uno) del parque vehicular.
type ResultadoChequeo ¶
type ResultadoChequeo struct {
Estado string `json:"estado"` // ChequeoCumple, ChequeoNoCumple o ChequeoNoVerificable
Motivo string `json:"motivo,omitempty"` // código estable; vacío si cumple, salvo CERTIFICADO_DEL_SAT
Mensaje string `json:"mensaje,omitempty"` // para personas; puede cambiar
}
ResultadoChequeo es uno de los chequeos del certificado.
type ResultadoSello ¶
type ResultadoSello struct {
Estado string `json:"estado"` // SelloValido, SelloInvalido o SelloNoVerificable
Motivo string `json:"motivo,omitempty"` // código estable; vacío si es válido
Mensaje string `json:"mensaje,omitempty"` // para personas; puede cambiar
// Algoritmo con que verificó la firma ("SHA256withRSA", "SHA1withRSA").
Algoritmo string `json:"algoritmo,omitempty"`
// NoCertificado del certificado con que se verificó (ver NoCertificado).
NoCertificado string `json:"no_certificado,omitempty"`
}
ResultadoSello es la verificación de un sello (el del emisor o el del SAT en el timbre).
type ResultadoValidacion ¶
type ResultadoValidacion struct {
Estado string `json:"estado"`
Hallazgos []Hallazgo `json:"hallazgos"`
}
ResultadoValidacion es el resultado de ValidarEsquema.
func ValidarEsquema ¶
func ValidarEsquema(xml []byte) *ResultadoValidacion
ValidarEsquema valida el documento contra los esquemas XSD del SAT que trae la librería (traducidos a Go en esquema_reglas.go y esquema_catalogos.go): CFDI 4.0 y 3.3, TimbreFiscalDigital 1.1, y los complementos Pagos 2.0 y 1.0, Nómina 1.2, ImpuestosLocales, CartaPorte 3.1, 3.0 y 2.0, ComercioExterior 2.0 y 1.1, HidroYPetro, CFDIRegistroFiscal, Divisas, EstadoDeCuentaCombustible 1.2, PorCuentadeTerceros 1.1, VentaVehiculos 1.1, Aerolineas, LeyendasFiscales, instEducativas y Donatarias 1.1, con sus catálogos.
Valida como lo haría un validador XSD (libxml2, p. ej.) con esos esquemas cargados: estructura (orden, minOccurs, maxOccurs, elementos y atributos no declarados, texto), atributos requeridos y fijos, tipos y facetas (pattern, catálogos, rangos, dígitos, longitudes), después de aplicar el whiteSpace del tipo. Los xs:any del SAT (Complemento, ComplementoConcepto, Addenda) son estrictos: un elemento ahí sin esquema en la librería no se valida y queda como aviso EsquemaNoSoportado (el resultado es ValidacionIncompleta si no hay errores), igual que la raíz si no es un Comprobante 3.3 o 4.0.
Trabaja sobre los bytes, como CadenaOriginal: el esquema habla del documento tal cual y no de lo que el modelo normaliza. Por lo mismo, lee el XML como un procesador conforme: con el encoding que declara y sin corregir nada. Un documento que Parse lee con advertencias de encoding, caracteres prohibidos o XML no estricto aquí es EsquemaXMLIlegible.
Nunca falla: todo lo que encuentra va en los hallazgos.
type RetEfectFideicomiso ¶
type RetEfectFideicomiso struct {
MontRetRelPagFideic *decimal.Decimal `json:"mont_ret_rel_pag_fideic,omitempty"`
DescRetRelPagFideic string `json:"desc_ret_rel_pag_fideic,omitempty"`
}
RetEfectFideicomiso es el nodo fideicomisonoempresarial:RetEfectFideicomiso del complemento Fideicomisonoempresarial.
type Retenciones ¶
type Retenciones struct {
Version string `json:"version,omitempty"`
FolioInt string `json:"folio_int,omitempty"`
Sello string `json:"sello,omitempty"`
NoCertificado string `json:"no_certificado,omitempty"`
Certificado string `json:"certificado,omitempty"`
// FechaExp: en 2.0, hora civil sin zona como la Fecha del CFDI; en 1.0
// trae su zona («2015-02-24T11:02:46-06:00»). Fecha.Time es la hora tal
// cual viene escrita, sin aplicar la zona; el texto la conserva.
FechaExp Fecha `json:"fecha_exp,omitzero"`
LugarExpRetenc string `json:"lugar_exp_retenc,omitempty"`
CveRetenc string `json:"cve_retenc,omitempty"`
DescRetenc string `json:"desc_retenc,omitempty"`
CfdiRetenRelacionados *CfdiRetenRelacionados `json:"cfdi_reten_relacionados,omitempty"`
Emisor *EmisorRetenciones `json:"emisor,omitempty"`
Receptor *ReceptorRetenciones `json:"receptor,omitempty"`
Periodo *PeriodoRetenciones `json:"periodo,omitempty"`
Totales *TotalesRetenciones `json:"totales,omitempty"`
// Complementos soportados.
TimbreFiscalDigital *TimbreFiscalDigital `json:"timbre_fiscal_digital,omitempty"`
ServiciosPlataformasTecnologicas *ServiciosPlataformasTecnologicas `json:"servicios_plataformas_tecnologicas,omitempty"`
Intereses *Intereses `json:"intereses,omitempty"`
Pagosaextranjeros *Pagosaextranjeros `json:"pagosaextranjeros,omitempty"`
Dividendos *Dividendos `json:"dividendos,omitempty"`
EnajenaciondeAcciones *EnajenaciondeAcciones `json:"enajenacionde_acciones,omitempty"`
Arrendamientoenfideicomiso *Arrendamientoenfideicomiso `json:"arrendamientoenfideicomiso,omitempty"`
Operacionesconderivados *Operacionesconderivados `json:"operacionesconderivados,omitempty"`
Intereseshipotecarios *Intereseshipotecarios `json:"intereseshipotecarios,omitempty"`
Fideicomisonoempresarial *Fideicomisonoempresarial `json:"fideicomisonoempresarial,omitempty"`
Planesderetiro *Planesderetiro `json:"planesderetiro,omitempty"`
Premios *Premios `json:"premios,omitempty"`
SectorFinanciero *SectorFinanciero `json:"sector_financiero,omitempty"`
// ComplementosNoSoportados lista los nodos de Complemento que no se
// leen, como "{namespace}NombreLocal", sin repetir.
ComplementosNoSoportados []string `json:"complementos_no_soportados,omitempty"`
// Advertencias de la lectura. En JSON van fuera de "retenciones", en el
// sobre.
Advertencias []Advertencia `json:"-"`
}
Retenciones es un CFDI de Retenciones e información de pagos (1.0 o 2.0) leído y normalizado.
Las dos versiones van en el mismo modelo con los nombres de la 2.0; en 1.0 cambian estos (el nombre de 1.0 entre paréntesis): NoCertificado (NumCert), Certificado (Cert), Emisor.RfcE (RFCEmisor), Emisor.CurpE (CURPE, solo 1.0), Receptor.NacionalidadR (Nacionalidad), Nacional.RfcR (RFCRecep), Nacional.CurpR (CURPR), Extranjero.NumRegIdTribR (NumRegIdTrib), Periodo.Ejercicio (Ejerc), Totales.MontoTot* y MontoRet (montoTot*, montoRet) e ImpRetenidos.ImpuestoRet (Impuesto). Las rutas de las advertencias usan el nombre que trae el documento. Lo exclusivo de 2.0 (LugarExpRetenc, CfdiRetenRelacionados, RegimenFiscalE, DomicilioFiscalR, UtilidadBimestral, ISRCorrespondiente) viene vacío en 1.0.
func ParseRetenciones ¶
func ParseRetenciones(r io.Reader) (*Retenciones, error)
ParseRetenciones lee un CFDI de Retenciones e información de pagos 1.0 o 2.0, con la misma tolerancia que Parse.
Solo devuelve error (un *Error) si el documento no es XML o si su raíz no es un Retenciones de retencionpago/1 o retencionpago/2 (ClaseNoEsRetenciones). Cualquier otra rareza se lee como se pueda y queda en Retenciones.Advertencias.
func ParseRetencionesBytes ¶
func ParseRetencionesBytes(b []byte) (*Retenciones, error)
ParseRetencionesBytes es ParseRetenciones sobre un []byte. No modifica b.
func (*Retenciones) AdvertenciaEn ¶
func (rt *Retenciones) AdvertenciaEn(rutaNodo, atributo string) (Advertencia, bool)
AdvertenciaEn es Comprobante.AdvertenciaEn para Retenciones.
func (*Retenciones) Complementos ¶
func (rt *Retenciones) Complementos() []string
Complementos lista los complementos presentes sin repetir: los soportados como "Nombre versión" ("TimbreFiscalDigital 1.1", "ServiciosPlataformasTecnologicas 1.0", "Planesderetiro 1.1") y los no soportados como "{namespace}NombreLocal".
func (*Retenciones) Documento ¶
func (rt *Retenciones) Documento(o OpcionesJSON) DocumentoRetenciones
Documento arma el sobre. Sin IncluirSello trabaja sobre una copia.
func (*Retenciones) JSON ¶
func (rt *Retenciones) JSON() ([]byte, error)
JSON devuelve el DocumentoRetenciones sin sellos y sin indentar.
func (*Retenciones) JSONOpciones ¶
func (rt *Retenciones) JSONOpciones(o OpcionesJSON) ([]byte, error)
JSONOpciones devuelve el DocumentoRetenciones con las opciones dadas.
func (*Retenciones) TieneAdvertencia ¶
func (rt *Retenciones) TieneAdvertencia(codigo string) bool
TieneAdvertencia dice si la lectura produjo al menos una advertencia con ese código.
func (*Retenciones) UUID ¶
func (rt *Retenciones) UUID() string
UUID del timbre, normalizado; "" si no hay timbre.
type RetencionesLocales ¶
type RetencionesLocales struct {
ImpLocRetenido string `json:"imp_loc_retenido,omitempty"`
TasadeRetencion *decimal.Decimal `json:"tasade_retencion,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
}
RetencionesLocales es el nodo implocal:RetencionesLocales del complemento ImpuestosLocales.
type SPEIBeneficiario ¶
type SPEIBeneficiario struct {
BancoReceptor string `json:"banco_receptor,omitempty"`
Nombre string `json:"nombre,omitempty"`
TipoCuenta *decimal.Decimal `json:"tipo_cuenta,omitempty"`
Cuenta *decimal.Decimal `json:"cuenta,omitempty"`
RFC string `json:"rfc,omitempty"`
Concepto string `json:"concepto,omitempty"`
IVA *decimal.Decimal `json:"iva,omitempty"`
MontoPago *decimal.Decimal `json:"monto_pago,omitempty"`
}
SPEIBeneficiario es el nodo spei:Beneficiario del complemento SPEI de terceros.
type SPEIOrdenante ¶
type SPEIOrdenante struct {
BancoEmisor string `json:"banco_emisor,omitempty"`
Nombre string `json:"nombre,omitempty"`
TipoCuenta *decimal.Decimal `json:"tipo_cuenta,omitempty"`
Cuenta *decimal.Decimal `json:"cuenta,omitempty"`
RFC string `json:"rfc,omitempty"`
}
SPEIOrdenante y SPEIBeneficiario: TipoCuenta y Cuenta son xs:decimal en el XSD; el decimal conserva el texto (los ceros a la izquierda de una CLABE incluidos).
type SPEITercero ¶
type SPEITercero struct {
FechaOperacion Fecha `json:"fecha_operacion,omitzero"`
Hora string `json:"hora,omitempty"` // xs:time, tal cual
ClaveSPEI string `json:"clave_spei,omitempty"`
Sello string `json:"sello,omitempty"`
NumeroCertificado string `json:"numero_certificado,omitempty"`
CadenaCDA string `json:"cadena_cda,omitempty"`
Ordenante *SPEIOrdenante `json:"ordenante,omitempty"`
Beneficiario *SPEIBeneficiario `json:"beneficiario,omitempty"`
}
SPEITercero es un SPEI_Tercero del complemento SPEI (spei), que no tiene versión: el comprobante de una transferencia SPEI a terceros que emite Banxico. Complemento_SPEI no tiene atributos y se aplana (Comprobante.ComplementoSPEI). Sello y CadenaCDA son de Banxico y, como los demás sellos, solo salen en JSON con IncluirSello.
type SectorFinanciero ¶
type SectorFinanciero struct {
Version string `json:"version,omitempty"`
IdFideicom string `json:"id_fideicom,omitempty"`
NomFideicom string `json:"nom_fideicom,omitempty"`
DescripFideicom string `json:"descrip_fideicom,omitempty"`
}
SectorFinanciero es el complemento de Retenciones sectorfinanciero:SectorFinanciero.
type Seguros ¶
type Seguros struct {
AseguraRespCivil string `json:"asegura_resp_civil,omitempty"`
PolizaRespCivil string `json:"poliza_resp_civil,omitempty"`
AseguraMedAmbiente string `json:"asegura_med_ambiente,omitempty"`
PolizaMedAmbiente string `json:"poliza_med_ambiente,omitempty"`
AseguraCarga string `json:"asegura_carga,omitempty"`
PolizaCarga string `json:"poliza_carga,omitempty"`
PrimaSeguro *decimal.Decimal `json:"prima_seguro,omitempty"`
}
Seguros es el nodo Seguros del Autotransporte del complemento CartaPorte.
type SeparacionIndemnizacion ¶
type SeparacionIndemnizacion struct {
TotalPagado *decimal.Decimal `json:"total_pagado,omitempty"`
NumAniosServicio string `json:"num_anios_servicio,omitempty"` // atributo "NumAñosServicio"
UltimoSueldoMensOrd *decimal.Decimal `json:"ultimo_sueldo_mens_ord,omitempty"`
IngresoAcumulable *decimal.Decimal `json:"ingreso_acumulable,omitempty"`
IngresoNoAcumulable *decimal.Decimal `json:"ingreso_no_acumulable,omitempty"`
}
SeparacionIndemnizacion es el nodo nomina12:SeparacionIndemnizacion de las Percepciones del complemento Nómina.
type ServiciosPlataformasTecnologicas ¶
type ServiciosPlataformasTecnologicas struct {
Version string `json:"version,omitempty"`
Periodicidad string `json:"periodicidad,omitempty"`
NumServ string `json:"num_serv,omitempty"`
MonTotServSIVA *decimal.Decimal `json:"mon_tot_serv_siva,omitempty"`
TotalIVATrasladado *decimal.Decimal `json:"total_iva_trasladado,omitempty"`
TotalIVARetenido *decimal.Decimal `json:"total_iva_retenido,omitempty"`
TotalISRRetenido *decimal.Decimal `json:"total_isr_retenido,omitempty"`
DifIVAEntregadoPrestServ *decimal.Decimal `json:"dif_iva_entregado_prest_serv,omitempty"`
MonTotalporUsoPlataforma *decimal.Decimal `json:"mon_totalpor_uso_plataforma,omitempty"`
MonTotalContribucionGubernamental *decimal.Decimal `json:"mon_total_contribucion_gubernamental,omitempty"`
Servicios []DetallesDelServicio `json:"servicios,omitempty"` // Servicios/DetallesDelServicio
}
ServiciosPlataformasTecnologicas 1.0: servicios de plataformas tecnológicas de intermediación.
type SubContratacion ¶
type SubContratacion struct {
RfcLabora string `json:"rfc_labora,omitempty"`
PorcentajeTiempo *decimal.Decimal `json:"porcentaje_tiempo,omitempty"`
}
SubContratacion es el nodo nomina12:SubContratacion del Receptor del complemento Nómina.
type SubsidioAlEmpleo ¶
type SubsidioAlEmpleo struct {
SubsidioCausado *decimal.Decimal `json:"subsidio_causado,omitempty"`
}
SubsidioAlEmpleo es el nodo nomina12:SubsidioAlEmpleo de un OtroPago del complemento Nómina.
type TimbreFiscalDigital ¶
type TimbreFiscalDigital struct {
Version string `json:"version,omitempty"`
// UUID normalizado: sin espacios y en mayúsculas.
UUID string `json:"uuid,omitempty"`
// UUIDOriginal es el texto como venía, solo si difiere de UUID.
UUIDOriginal string `json:"uuid_original,omitempty"`
FechaTimbrado Fecha `json:"fecha_timbrado,omitzero"`
RfcProvCertif string `json:"rfc_prov_certif,omitempty"`
Leyenda string `json:"leyenda,omitempty"`
SelloCFD string `json:"sello_cfd,omitempty"`
NoCertificadoSAT string `json:"no_certificado_sat,omitempty"`
SelloSAT string `json:"sello_sat,omitempty"`
}
TimbreFiscalDigital 1.0 o 1.1. En 1.0 los atributos van en minúsculas (version, selloCFD…) y no existe RfcProvCertif; se leen igual.
type TipoDocumento ¶
type TipoDocumento string
TipoDocumento es lo que dice Detectar de un XML.
const ( TipoComprobante TipoDocumento = "comprobante" // raíz Comprobante de cfd/3 o cfd/4: se lee con Parse TipoRetenciones TipoDocumento = "retenciones" // raíz Retenciones de retencionpago/1 o /2: se lee con ParseRetenciones TipoOtro TipoDocumento = "otro" // otra raíz, o no es XML )
Tipos de documento de Detectar.
func Detectar ¶
func Detectar(b []byte) TipoDocumento
Detectar mira solo el elemento raíz para decidir con qué función leer el documento. Lee tolerante como Parse (encoding corregido, XML no estricto): lo que Parse o ParseRetenciones rechazarían por no ser XML sale como TipoOtro.
type TiposFigura ¶
type TiposFigura struct {
TipoFigura string `json:"tipo_figura,omitempty"`
RFCFigura string `json:"rfc_figura,omitempty"`
NumLicencia string `json:"num_licencia,omitempty"`
NombreFigura string `json:"nombre_figura,omitempty"`
NumRegIdTribFigura string `json:"num_reg_id_trib_figura,omitempty"`
ResidenciaFiscalFigura string `json:"residencia_fiscal_figura,omitempty"`
PartesTransporte []PartesTransporte `json:"partes_transporte,omitempty"`
Domicilio *Domicilio `json:"domicilio,omitempty"`
}
TiposFigura es el nodo TiposFigura de la FiguraTransporte del complemento CartaPorte (2.0 y 3.x).
type TotalesPagos ¶
type TotalesPagos struct {
TotalRetencionesIVA *decimal.Decimal `json:"total_retenciones_iva,omitempty"`
TotalRetencionesISR *decimal.Decimal `json:"total_retenciones_isr,omitempty"`
TotalRetencionesIEPS *decimal.Decimal `json:"total_retenciones_ieps,omitempty"`
TotalTrasladosBaseIVA16 *decimal.Decimal `json:"total_traslados_base_iva16,omitempty"`
TotalTrasladosImpuestoIVA16 *decimal.Decimal `json:"total_traslados_impuesto_iva16,omitempty"`
TotalTrasladosBaseIVA8 *decimal.Decimal `json:"total_traslados_base_iva8,omitempty"`
TotalTrasladosImpuestoIVA8 *decimal.Decimal `json:"total_traslados_impuesto_iva8,omitempty"`
TotalTrasladosBaseIVA0 *decimal.Decimal `json:"total_traslados_base_iva0,omitempty"`
TotalTrasladosImpuestoIVA0 *decimal.Decimal `json:"total_traslados_impuesto_iva0,omitempty"`
TotalTrasladosBaseIVAExento *decimal.Decimal `json:"total_traslados_base_iva_exento,omitempty"`
MontoTotalPagos *decimal.Decimal `json:"monto_total_pagos,omitempty"`
}
TotalesPagos es el nodo pago20:Totales del complemento Pagos 2.0.
type TotalesRetenciones ¶
type TotalesRetenciones struct {
MontoTotOperacion *decimal.Decimal `json:"monto_tot_operacion,omitempty"`
MontoTotGrav *decimal.Decimal `json:"monto_tot_grav,omitempty"`
MontoTotExent *decimal.Decimal `json:"monto_tot_exent,omitempty"`
MontoTotRet *decimal.Decimal `json:"monto_tot_ret,omitempty"`
UtilidadBimestral *decimal.Decimal `json:"utilidad_bimestral,omitempty"` // 2.0
ISRCorrespondiente *decimal.Decimal `json:"isr_correspondiente,omitempty"` // 2.0
ImpRetenidos []ImpRetenidos `json:"imp_retenidos,omitempty"`
}
TotalesRetenciones es el nodo retenciones:Totales del CFDI de Retenciones.
type TransporteAereo ¶
type TransporteAereo struct {
PermSCT string `json:"perm_sct,omitempty"`
NumPermisoSCT string `json:"num_permiso_sct,omitempty"`
NombreAseg string `json:"nombre_aseg,omitempty"`
NumPolizaSeguro string `json:"num_poliza_seguro,omitempty"`
NumeroGuia string `json:"numero_guia,omitempty"`
LugarContrato string `json:"lugar_contrato,omitempty"`
RFCTransportista string `json:"rfc_transportista,omitempty"` // 1.0
CodigoTransportista string `json:"codigo_transportista,omitempty"`
NumRegIdTribTranspor string `json:"num_reg_id_trib_transpor,omitempty"` // 1.0
ResidenciaFiscalTranspor string `json:"residencia_fiscal_transpor,omitempty"` // 1.0
NombreTransportista string `json:"nombre_transportista,omitempty"` // 1.0
RFCEmbarcador string `json:"rfc_embarcador,omitempty"`
NumRegIdTribEmbarc string `json:"num_reg_id_trib_embarc,omitempty"`
ResidenciaFiscalEmbarc string `json:"residencia_fiscal_embarc,omitempty"`
NombreEmbarcador string `json:"nombre_embarcador,omitempty"`
}
TransporteAereo es el nodo TransporteAereo del complemento CartaPorte.
type TransporteFerroviario ¶
type TransporteFerroviario struct {
TipoDeServicio string `json:"tipo_de_servicio,omitempty"`
TipoDeTrafico string `json:"tipo_de_trafico,omitempty"`
NombreAseg string `json:"nombre_aseg,omitempty"`
NumPolizaSeguro string `json:"num_poliza_seguro,omitempty"`
Concesionario string `json:"concesionario,omitempty"` // 1.0
DerechosDePaso []DerechosDePaso `json:"derechos_de_paso,omitempty"`
Carro []Carro `json:"carro,omitempty"`
}
TransporteFerroviario es el nodo TransporteFerroviario del complemento CartaPorte.
type TransporteMaritimo ¶
type TransporteMaritimo struct {
PermSCT string `json:"perm_sct,omitempty"`
NumPermisoSCT string `json:"num_permiso_sct,omitempty"`
NombreAseg string `json:"nombre_aseg,omitempty"`
NumPolizaSeguro string `json:"num_poliza_seguro,omitempty"`
TipoEmbarcacion string `json:"tipo_embarcacion,omitempty"`
Matricula string `json:"matricula,omitempty"`
NumeroOMI string `json:"numero_omi,omitempty"`
AnioEmbarcacion string `json:"anio_embarcacion,omitempty"`
NombreEmbarc string `json:"nombre_embarc,omitempty"`
NacionalidadEmbarc string `json:"nacionalidad_embarc,omitempty"`
UnidadesDeArqBruto *decimal.Decimal `json:"unidades_de_arq_bruto,omitempty"`
TipoCarga string `json:"tipo_carga,omitempty"`
NumCertITC string `json:"num_cert_itc,omitempty"` // 2.0
Eslora *decimal.Decimal `json:"eslora,omitempty"`
Manga *decimal.Decimal `json:"manga,omitempty"`
Calado *decimal.Decimal `json:"calado,omitempty"`
Puntal *decimal.Decimal `json:"puntal,omitempty"` // 3.x
NumViaje string `json:"num_viaje,omitempty"`
NumConocEmbarc string `json:"num_conoc_embarc,omitempty"`
Contenedor []ContenedorMaritimo `json:"contenedor,omitempty"`
RemolquesCCP []RemolqueCCP `json:"remolques_ccp,omitempty"` // 3.0
}
TransporteMaritimo es el nodo TransporteMaritimo del complemento CartaPorte.
type TrasladosLocales ¶
type TrasladosLocales struct {
ImpLocTrasladado string `json:"imp_loc_trasladado,omitempty"`
TasadeTraslado *decimal.Decimal `json:"tasade_traslado,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
}
TrasladosLocales es el nodo implocal:TrasladosLocales del complemento ImpuestosLocales.
type TuristaPasajeroExtranjero ¶
type TuristaPasajeroExtranjero struct {
Version string `json:"version,omitempty"`
FechadeTransito Fecha `json:"fechade_transito,omitzero"`
TipoTransito string `json:"tipo_transito,omitempty"`
DatosTransito *TuristaPasajeroExtranjeroDatosTransito `json:"datos_transito,omitempty"`
}
TuristaPasajeroExtranjero 1.0.
type TuristaPasajeroExtranjeroDatosTransito ¶
type TuristaPasajeroExtranjeroDatosTransito struct {
Via string `json:"via,omitempty"`
TipoId string `json:"tipo_id,omitempty"`
NumeroId string `json:"numero_id,omitempty"`
Nacionalidad string `json:"nacionalidad,omitempty"`
EmpresaTransporte string `json:"empresa_transporte,omitempty"`
IdTransporte string `json:"id_transporte,omitempty"`
}
TuristaPasajeroExtranjeroDatosTransito es el nodo tpe:datosTransito del complemento TuristaPasajeroExtranjero.
type Ubicacion ¶
type Ubicacion struct {
TipoUbicacion string `json:"tipo_ubicacion,omitempty"`
IDUbicacion string `json:"id_ubicacion,omitempty"`
RFCRemitenteDestinatario string `json:"rfc_remitente_destinatario,omitempty"`
NombreRemitenteDestinatario string `json:"nombre_remitente_destinatario,omitempty"`
NumRegIdTrib string `json:"num_reg_id_trib,omitempty"`
ResidenciaFiscal string `json:"residencia_fiscal,omitempty"`
NumEstacion string `json:"num_estacion,omitempty"`
NombreEstacion string `json:"nombre_estacion,omitempty"`
FechaHoraSalidaLlegada Fecha `json:"fecha_hora_salida_llegada,omitzero"`
TipoEstacion string `json:"tipo_estacion,omitempty"`
DistanciaRecorrida *decimal.Decimal `json:"distancia_recorrida,omitempty"`
Origen *CartaPorte10Origen `json:"origen,omitempty"` // 1.0
Destino *CartaPorte10Destino `json:"destino,omitempty"` // 1.0
Domicilio *Domicilio `json:"domicilio,omitempty"`
}
Ubicacion es el nodo Ubicacion del complemento CartaPorte.
type UbicacionFiscal ¶
type UbicacionFiscal struct {
Calle string `json:"calle,omitempty"`
NoExterior string `json:"no_exterior,omitempty"`
NoInterior string `json:"no_interior,omitempty"`
Colonia string `json:"colonia,omitempty"`
Localidad string `json:"localidad,omitempty"`
Referencia string `json:"referencia,omitempty"`
Municipio string `json:"municipio,omitempty"`
Estado string `json:"estado,omitempty"`
Pais string `json:"pais,omitempty"`
CodigoPostal string `json:"codigo_postal,omitempty"`
}
UbicacionFiscal es el t_UbicacionFiscal de terceros (atributos en minúsculas: calle, noExterior…).
type ValesDeDespensa ¶
type ValesDeDespensa struct {
Version string `json:"version,omitempty"`
TipoOperacion string `json:"tipo_operacion,omitempty"`
RegistroPatronal string `json:"registro_patronal,omitempty"`
NumeroDeCuenta string `json:"numero_de_cuenta,omitempty"`
Total *decimal.Decimal `json:"total,omitempty"`
Conceptos []ValesDeDespensaConcepto `json:"conceptos,omitempty"`
}
ValesDeDespensa 1.0. Conceptos aplana Conceptos/Concepto.
type ValesDeDespensaConcepto ¶
type ValesDeDespensaConcepto struct {
Identificador string `json:"identificador,omitempty"`
Fecha Fecha `json:"fecha,omitzero"`
Rfc string `json:"rfc,omitempty"`
Curp string `json:"curp,omitempty"`
Nombre string `json:"nombre,omitempty"`
NumSeguridadSocial string `json:"num_seguridad_social,omitempty"`
Importe *decimal.Decimal `json:"importe,omitempty"`
}
ValesDeDespensaConcepto es el nodo valesdedespensa:Concepto del complemento ValesDeDespensa.
type Validacion ¶
type Validacion struct {
// Estado es el peor de los dos: invalido si alguno lo es; incompleto
// si alguno lo es y ninguno es inválido; si no, valido.
Estado string `json:"estado"`
Esquema *ResultadoValidacion `json:"esquema"`
// Reglas es nil si el documento no se pudo leer como CFDI (Parse
// falló).
Reglas *ResultadoValidacion `json:"reglas,omitempty"`
}
Validacion junta las dos validaciones de un documento: la del esquema (sobre los bytes) y la de las reglas (sobre el Comprobante). Es lo que escriben `cfdi validar` y `cfdi lote -validar`.
func Validar ¶
func Validar(xml []byte, c *Comprobante) *Validacion
Validar corre ValidarEsquema sobre xml y ValidarReglas sobre c. Si c es nil lee xml con ParseBytes; si tampoco se puede leer, Reglas queda nil y el estado es el del esquema (que entonces es inválido). Nunca falla.
Example ¶
package main
import (
"fmt"
"github.com/OrtaMarco/cfdi-go"
)
// Una factura 4.0 mínima, sin sello ni timbre, con el RFC de prueba del SAT.
const facturaEjemplo = `<?xml version="1.0" encoding="UTF-8"?>
<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/4" Version="4.0" Serie="A" Folio="1"
Fecha="2026-01-15T10:30:00" Sello="" NoCertificado="30001000000500003416" Certificado=""
SubTotal="100.00" Moneda="MXN" Total="116.00" TipoDeComprobante="I" Exportacion="01"
MetodoPago="PUE" FormaPago="03" LugarExpedicion="20000">
<cfdi:Emisor Rfc="EKU9003173C9" Nombre="ESCUELA KEMPER URGATE" RegimenFiscal="601"/>
<cfdi:Receptor Rfc="XAXX010101000" Nombre="PUBLICO EN GENERAL" DomicilioFiscalReceptor="20000"
RegimenFiscalReceptor="616" UsoCFDI="S01"/>
<cfdi:Conceptos>
<cfdi:Concepto ClaveProdServ="01010101" Cantidad="1" ClaveUnidad="H87" Descripcion="Artículo"
ValorUnitario="100.00" Importe="100.00" ObjetoImp="02">
<cfdi:Impuestos>
<cfdi:Traslados>
<cfdi:Traslado Base="100.00" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="16.00"/>
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Concepto>
</cfdi:Conceptos>
<cfdi:Impuestos TotalImpuestosTrasladados="16.00">
<cfdi:Traslados>
<cfdi:Traslado Base="100.00" Impuesto="002" TipoFactor="Tasa" TasaOCuota="0.160000" Importe="16.00"/>
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Comprobante>`
func main() {
v := cfdi.Validar([]byte(facturaEjemplo), nil)
fmt.Println(v.Estado)
for _, h := range v.Hallazgos() {
fmt.Println(h.Nivel, h.Codigo, h.Ruta)
}
}
Output: valido
func ValidarRetenciones ¶
func ValidarRetenciones(xml []byte) *Validacion
ValidarRetenciones valida un CFDI de Retenciones 1.0 o 2.0 contra los XSD del SAT (retencionpagov1/v2, sus trece complementos y el TFD 1.1): es ValidarEsquema en una Validacion sin Reglas. No hay reglas aritméticas de Retenciones: el SAT no publica para ellas matriz de errores ni guía con las fórmulas, y la librería no inventa reglas sin fuente. Nunca falla.
func (*Validacion) Hallazgos ¶
func (v *Validacion) Hallazgos() []Hallazgo
Hallazgos devuelve los hallazgos del esquema y luego los de las reglas.
type VehiculoUsado ¶
type VehiculoUsado struct {
Version string `json:"version,omitempty"`
MontoAdquisicion *decimal.Decimal `json:"monto_adquisicion,omitempty"`
MontoEnajenacion *decimal.Decimal `json:"monto_enajenacion,omitempty"`
ClaveVehicular string `json:"clave_vehicular,omitempty"`
Marca string `json:"marca,omitempty"`
Tipo string `json:"tipo,omitempty"`
Modelo string `json:"modelo,omitempty"`
NumeroMotor string `json:"numero_motor,omitempty"`
NumeroSerie string `json:"numero_serie,omitempty"`
NIV string `json:"niv,omitempty"`
Valor *decimal.Decimal `json:"valor,omitempty"`
InformacionAduanera []InformacionAduaneraComplemento `json:"informacion_aduanera,omitempty"`
}
VehiculoUsado 1.0: enajenación de un vehículo usado por una persona física. InformacionAduanera es la de terceros y ventavehiculos.
type VentaVehiculos ¶
type VentaVehiculos struct {
Version string `json:"version,omitempty"`
ClaveVehicular string `json:"clave_vehicular,omitempty"`
Niv string `json:"niv,omitempty"`
InformacionAduanera []InformacionAduaneraComplemento `json:"informacion_aduanera,omitempty"`
Parte []ParteComplemento `json:"parte,omitempty"`
}
VentaVehiculos 1.0 y 1.1 (ventavehiculos). 1.1 agregó Niv.
type Verificacion ¶
type Verificacion struct {
// CadenaOriginal del comprobante; vacía si no se pudo garantizar.
CadenaOriginal string `json:"cadena_original,omitempty"`
// Sello del emisor sobre CadenaOriginal, con el Certificado del XML.
Sello ResultadoSello `json:"sello"`
// CadenaOriginalTFD del timbre, si lo hay y se pudo armar.
CadenaOriginalTFD string `json:"cadena_original_tfd,omitempty"`
// TFD es el SelloSAT del timbre; nil si no se pidió (certificados nil).
TFD *ResultadoSello `json:"tfd,omitempty"`
// Certificado son los chequeos del certificado del emisor (vigencia,
// RFC y número), aparte del sello: no cambian Sello.Estado.
Certificado *ChequeosCertificado `json:"certificado,omitempty"`
}
Verificacion es el resultado de Verificar.
func Verificar ¶
func Verificar(xml []byte, certs CertificadosSAT) *Verificacion
Verificar arma la cadena original y verifica el sello del emisor con el Certificado que trae el XML: RSA PKCS#1 v1.5 con SHA-256 (CFDI 3.3 y 4.0; en 3.2 también SHA-1), y que NoCertificado sea el número de ese certificado. No revisa la cadena de confianza del certificado ni si estaba revocado (eso necesita red).
Aparte, sin cambiar el veredicto del sello, Verificacion.Certificado dice si la Fecha cae en la vigencia del certificado, si su RFC es el del Emisor y si su número es el NoCertificado (ver ChequeosCertificado).
Si certs no es nil, verifica también el timbre: SelloSAT sobre la cadena del TFD con el certificado que dé certs para NoCertificadoSAT (SHA-256 en TFD 1.1; en 1.0 también SHA-1), y que SelloCFD sea el Sello del comprobante.
Nunca falla: lo que no se puede decidir sale como SelloNoVerificable con su motivo.
Example ¶
Verificar arma la cadena original y comprueba el sello del emisor con el certificado que trae el XML, sin red. Este CFDI está sellado con el CSD de pruebas del SAT.
package main
import (
"fmt"
"log"
"os"
"github.com/OrtaMarco/cfdi-go"
)
func main() {
xml, err := os.ReadFile("testdata/sinteticos/sellados/ingreso40-pue.xml")
if err != nil {
log.Fatal(err)
}
v := cfdi.Verificar(xml, nil)
fmt.Println(v.Sello.Estado, v.Sello.Algoritmo, v.Sello.NoCertificado)
}
Output: valido SHA256withRSA 30001000000500003416
func VerificarRetenciones ¶
func VerificarRetenciones(xml []byte, certs CertificadosSAT) *Verificacion
VerificarRetenciones es Verificar para un CFDI de Retenciones 1.0 o 2.0: el sello del emisor sobre CadenaOriginalRetenciones con el certificado del XML (SHA-256; en 1.0 también SHA-1) y que su NoCertificado (NumCert en 1.0) sea el número del certificado; el timbre, si certs no es nil, como en Verificar; y los chequeos del certificado, con FechaExp. Nunca falla.
Source Files
¶
- advertencias.go
- cadena.go
- cadena_reglas.go
- cartaporte.go
- cartaporte10.go
- certificado.go
- codificacion.go
- comercioexterior.go
- complementos.go
- complementos_chicos.go
- complementos_comunes.go
- complementos_concepto.go
- complementos_otros.go
- comprobante.go
- conforme.go
- doc.go
- errores.go
- esquema.go
- esquema_catalogos.go
- esquema_reglas.go
- fecha.go
- hallazgo.go
- implocal.go
- json.go
- lector.go
- leer.go
- modelo.go
- modelo_complementos.go
- monedas.go
- nomina.go
- reglas.go
- reglas_cce.go
- reglas_complementos.go
- reglas_nomina.go
- reglas_pagos.go
- reglas_pagos_impuestos.go
- retenciones.go
- retenciones_cadena.go
- retenciones_complementos.go
- retenciones_leer.go
- schema.go
- validacion.go
- verificar.go
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
cfdi
command
Comando cfdi lee CFDI 3.3/4.0 y de Retenciones 1.0/2.0 y los escribe como JSON.
|
Comando cfdi lee CFDI 3.3/4.0 y de Retenciones 1.0/2.0 y los escribe como JSON. |
|
Package decimal es un número decimal exacto para los montos de un CFDI.
|
Package decimal es un número decimal exacto para los montos de un CFDI. |
|
internal
|
|
|
gencadena
Package gencadena traduce las hojas XSLT del SAT que arman la cadena original (CFDI 3.2, 3.3 y 4.0, TFD 1.0 y 1.1, y los complementos que lee la librería) a reglas Go: el archivo cadena_reglas.go del paquete cfdi.
|
Package gencadena traduce las hojas XSLT del SAT que arman la cadena original (CFDI 3.2, 3.3 y 4.0, TFD 1.0 y 1.1, y los complementos que lee la librería) a reglas Go: el archivo cadena_reglas.go del paquete cfdi. |
|
gencadena/generar
command
Comando generar escribe cadena_reglas.go a partir de los XSLT del SAT.
|
Comando generar escribe cadena_reglas.go a partir de los XSLT del SAT. |
|
genxsd
Package genxsd traduce los esquemas XSD del SAT (CFDI 4.0 y 3.3, TFD 1.1 y 1.0 y los complementos de Raices y Variantes, con los catálogos y tipos de datos que importan) a tablas Go: los archivos esquema_reglas.go y esquema_catalogos.go del paquete cfdi, que usa ValidarEsquema.
|
Package genxsd traduce los esquemas XSD del SAT (CFDI 4.0 y 3.3, TFD 1.1 y 1.0 y los complementos de Raices y Variantes, con los catálogos y tipos de datos que importan) a tablas Go: los archivos esquema_reglas.go y esquema_catalogos.go del paquete cfdi, que usa ValidarEsquema. |
|
genxsd/generar
command
Comando generar escribe esquema_reglas.go y esquema_catalogos.go a partir de los XSD del SAT.
|
Comando generar escribe esquema_reglas.go y esquema_catalogos.go a partir de los XSD del SAT. |