Documentation
¶
Index ¶
- Constants
- func GetMensaje(code int) string
- func IsConfigCode(code int) bool
- func IsNetworkError(err error) bool
- func IsRetryable(err error) bool
- func IsRetryableCode(code int) bool
- func IsValidationCode(code int) bool
- func IsWarningCode(code int) bool
- func NewHTTPClient(cfg HTTPConfig) *http.Client
- func Verify(resp interface{}) error
- type Config
- type HTTPConfig
- type HTTPMiddleware
- type Map
- type SiatError
- type SiatServices
- func (s *SiatServices) Codigos() ports.SiatCodigosService
- func (s *SiatServices) CompraVenta() ports.SiatCompraVentaService
- func (s *SiatServices) Computarizada() ports.SiatComputarizadaService
- func (s *SiatServices) Electronica() ports.SiatElectronicaService
- func (s *SiatServices) Operaciones() ports.SiatOperacionesPort
- func (s *SiatServices) Sincronizacion() ports.SiatSincronizacionService
- func (s *SiatServices) WithConfig(token string) ports.Config
- func (s *SiatServices) WithTraceID(id string) *SiatServices
Constants ¶
const ( CodeCufdFueraDeTolerancia = 123 CodeRecepcionPendiente = 901 CodeRecepcionRechazada = 902 CodeRecepcionProcesada = 903 CodeRecepcionObservada = 904 CodeAnulacionConfirmada = 905 CodeAnulacionRechazada = 906 CodeReversionAnulacionConfirmada = 907 CodeRecepcionValidada = 908 CodeReversionAnulacionRechazada = 909 CodeAmbienteInvalido = 910 CodeCodigoSistemaInvalido = 911 CodeSistemaNoAsociadoAlContribuyente = 912 CodeCuisInvalido = 913 CodeCufdInvalido = 914 CodeTipoFacturaDocumentoInvalido = 915 CodeTipoEmisionInvalido = 916 CodeModalidadInvalida = 917 CodeSucursalInvalida = 918 CodeNitInvalido = 919 CodeArchivoInvalido = 920 CodeFirmadoXmlIncorrecto = 921 CodeFirmaXmlNoCorrespondeAlContribuyente = 922 CodeCodigoRecepcionInvalido = 923 CodeFacturaNoExisteEnSin = 924 CodeMotivoAnulacionInvalido = 925 CodeComunicacionExitosa = 926 CodeCertificadoFirmaInvalido = 927 CodeCertificadoRevocado = 928 CodeCuisNoVigente = 929 CodeCuisNoCorrespondeASucursalPuntoVenta = 930 CodeCodigoDocumentoSectorInvalido = 931 CodeCodigoDocumentoSectorNoCorrespondeAlServicio = 932 CodePuntoVentaInexistenteOInvalido = 933 CodeAnulacionFueraDePlazo = 934 CodeFechaEnvioInvalida = 935 CodeFacturaYaAnulada = 936 CodeNitNoAsociadoAModalidad = 937 CodeNitPresentaMarcasDeControl = 938 CodeFacturaNoCumpleXsd = 939 CodeNitNoHabilitadoDocumentoSector = 940 CodeFacturaNoDisponibleParaAnular = 941 CodeEventoSignificativoNoExisteEnSin = 942 CodeFormatoFechaEnvioIncorrecto = 943 CodeCodigoRecepcionNoExisteEnSin = 944 CodeEstadoRecepcionAnulacionIncorrecta = 945 CodeCufNoExisteEnSin = 946 CodeTipoPuntoVentaInvalido = 947 CodeNombrePuntoVentaVacio = 948 CodeDescripcionPuntoVentaVacio = 949 CodeEventoSignificativoVacio = 950 CodeDescripcionEventoSignificativoVacio = 951 CodeCufYaRegistradoEnSin = 952 CodeCufdNoVigente = 953 CodePaqueteContingenciaExcedido = 954 CodeNoExisteRegistroMasivo = 955 CodePaqueteMasivoExcedido = 956 CodeNoExisteEventoSignificativo = 957 CodeUsuarioNoAutorizado = 958 CodeCuisNoAsociadoAlSistema = 959 CodeFinDeEventoRequerido = 960 CodeMarcaDomicilioInexistente = 961 CodeBloqueoDosificacionFiscalizacion = 962 CodeBloqueoDosificacionJuridica = 963 CodeNoCumpleObligatoriedadDDJJ = 964 CodeContribuyenteSinFirmaVigente = 965 CodeNoSePuedeRecuperarDatosContribuyente = 966 CodeTiempoEsperaAgotadoDB = 967 CodeAnulacionYaRevertida = 968 CodeHashInvalido = 969 CodeCuisVigenteNoPuedeSolicitarOtro = 970 CodeArchivoExcedeTamano = 971 CodeCantidadFacturasExcedeNormativa = 972 CodeRangoFechasEventoInvalido = 974 CodeSistemaNoAutorizadoOObservado = 975 CodeCodigoEventoIncorrecto = 976 CodeNoExistenActividadesNIT = 977 CodeReversionFacturaConfirmada = 978 CodeCuisNoAsociadoASistemaOSucursal = 979 CodeExisteCuisVigente = 980 CodeRangoFechasEventoSignificativoInvalido = 981 CodeNoExistePuntosDeVenta = 982 CodeFechaEnvioPaqueteFueraDePlazo = 983 CodeEventoNoCorrespondeCufd = 984 CodeCantidadFacturasDiferenteADeclarada = 985 CodeNitActivo = 986 CodeNitInactivo = 987 CodeCuisFueraDeTolerancia = 988 CodeTokenInvalido = 989 CodeClienteSinActividadesSector = 990 CodeErrorBaseDeDatos = 991 CodeErrorServicioPadron = 992 CodeFechaEnvioFueraDePlazo = 993 CodeNitInexistente = 994 CodeServicioNoDisponible = 995 CodeRangoFechasInvalido = 996 CodeNombreExcedeLimite = 997 CodeDescripcionExcedeLimite = 998 CodeErrorEjecucionServicio = 999 CodeCufYaExisteEnSin = 1000 CodeNitNoCorrespondeACufd = 1001 CodeCufInvalido = 1002 CodeCufdEnXmlInvalido = 1003 CodeSucursalNoCorrespondeACufd = 1004 CodeFacturaNoPuedeSerEmitidaAlMismoEmisor = 1005 CodeCufdNoCorrespondeAEvento = 1006 CodeDireccionNoCorrespondeAPadron = 1007 CodePuntoVentaEnXmlInexistente = 1008 CodeFechaEmisionNoValidaLinea = 1009 CodeFacturaMontoExcedidoSinDatos = 1010 CodeComplementoSoloCarnet = 1011 CodeNumeroTarjetaSoloConTarjeta = 1012 CodeCalculoMontoTotalErroneo = 1013 CodeCalculoMontoTotalMonedaErroneo = 1014 CodeCalculoImporteBaseErroneo = 1015 CodeActividadNoHabilitada = 1016 CodeProductoNoRelacionadoAActividad = 1017 CodeCalculoSubtotalErroneo = 1018 CodeCalculoIceEspecificoErroneo = 1019 CodeCalculoIcePorcentualErroneo = 1020 CodeMontoIceEspecificoErroneo = 1021 CodeMontoIcePorcentualErroneo = 1022 CodeCodigoNandinaErroneo = 1023 CodeSumatoriaDetallesErronea = 1024 CodeMontoSujetoCreditoLey317Erroneo = 1025 CodeMontoTotalSujetoIJErroneo = 1026 CodeMontoDiferenciaCambioErroneo = 1027 CodeMontoIvaErroneo = 1028 CodeMontoTotalDevueltoErroneo = 1029 CodeMontoTotalOriginalErroneo = 1030 CodeMontoEfectivoDevueltoErroneo = 1031 CodeMontoTotalIPJErroneo = 1032 CodeMontoDevueltoMayorAOriginal = 1033 CodeFechaEmisionMenorPeriodoAnterior = 1034 CodeFormatoFechaIncorrecto = 1035 CodeNominatividadIncorrecta = 1036 CodeNitNoValido = 1037 CodeNitConjuntoNoValido = 1038 CodeFechaEmisionMasivaIncorrecta = 1039 CodeFechaEmisionFueraRangoContingencia = 1040 CodeFechaEmisionFueraPlazoNorma = 1041 CodeNitMedicoNoValido = 1042 CodeMontoConciliadoErroneo = 1043 CodeMontoTotalConciliadoErroneo = 1044 CodeCafcNoValido = 1045 CodeFechaEmisionCafcIncorrecta = 1046 CodeNumeroFacturaCafcIncorrecto = 1047 CodeNotaCreditoFacturaNoEncontrada = 1048 CodeNotaDetalleDiferenteAFactura = 1049 CodeMontoGiftCardNoCorresponde = 1050 CodeFechaFacturaIncorrecta = 1051 CodeCalculoMontoIehdErroneo = 1052 CodeActividadNotaAutorizadaPlazo = 1053 CodeMontoDescuentoCreditoDebitoErroneo = 1054 CodeMontoTarifaErroneo = 1055 CodeTipoCambioErroneo = 1056 CodeMontoTotalMonedaComputarizadaErroneo = 1057 CodeMontoTotalSujetoIvaErroneo = 1058 CodeRazonSocialErronea = 1059 CodeMontoDetalleErroneo = 1060 CodeNotaNoValidaParaDevolucion = 1061 CodeWarnCorrelatividadFactura = 2000 CodeWarnFechaRangoContingencia = 2001 CodeWarnFechaEmisionMasiva = 2002 CodeWarnFacturaMontoSinDatos = 2003 CodeWarnComplementoSoloCarnet = 2004 CodeWarnNitClienteNoValido = 2005 CodeWarnNumeroTarjetaSoloConTarjeta = 2006 CodeWarnCalculoMontoTotal = 2007 CodeWarnCalculoMontoTotalMoneda = 2008 CodeWarnCalculoImporteBase = 2009 CodeWarnActividadNoHabilitada = 2010 CodeWarnProductoNoRelacionado = 2011 CodeWarnCalculoSubtotal = 2012 CodeWarnEmisionAMismoEmisor = 2013 CodeWarnDireccionNoCorrespondePadron = 2014 CodeWarnCalculoIceEspecifico = 2015 CodeWarnCalculoIcePorcentual = 2016 CodeWarnMontoIceEspecifico = 2017 CodeWarnMontoIcePorcentual = 2018 CodeWarnCodigoNandinaErroneo = 2019 CodeNitNoContratoVigente = 3000 CodeCategoriaContratoNoSector = 3001 CodeExcedeLimiteCufdMasivo = 3002 CodeMarcaNoFormulariosVigentes = 3003 CodeMarcaDomicilioInexistenteMarca = 3004 CodeMarcaBloqueoFiscalizacion = 3005 CodeMarcaBloqueoJuridica = 3006 CodeMarcaNoObligatoriedadDDJJ = 3007 CodeWarnCuisExpira = 3008 CodeTamanoArchivoMayorNorma = 3009 CodeFacturaYaUtilizadaOConsolidada = 3010 )
SIAT Error Codes
const ( // AmbienteProduccion (1): Operaciones reales con validez tributaria. AmbienteProduccion = iota + 1 // AmbientePruebas (2): Entorno de desarrollo, pruebas y certificación. AmbientePruebas )
const ( // ModalidadElectronica (1): Requiere firma digital de los documentos XML. ModalidadElectronica = iota + 1 // ModalidadComputarizada (2): No requiere firma digital, usa código de control. ModalidadComputarizada )
const ( // EmisionOnline (1): La emisión se realizó con conexión al SIAT. EmisionOnline = iota + 1 // EmisionOffline (2): La emisión se realizó fuera de línea (Contingencia). EmisionOffline // EmisionMasiva (3): Para procesos de alta demanda de facturación. EmisionMasiva )
Variables ¶
This section is empty.
Functions ¶
func GetMensaje ¶ added in v0.4.0
GetMensaje retorna la descripción del código de error del SIAT. Si el código no existe, retorna una descripción genérica con el código.
func IsConfigCode ¶ added in v0.6.0
IsConfigCode retorna true si el código indica un error de configuración del sistema o credenciales.
func IsNetworkError ¶ added in v0.6.0
IsNetworkError indica si un error fue de red. Útil para distinguir entre problemas de conectividad y errores del servidor.
func IsRetryable ¶ added in v0.6.0
IsRetryable indica si un error puede/debe ser reintentado. Útil para implementar lógica de retry en la aplicación.
func IsRetryableCode ¶ added in v0.6.0
IsRetryableCode retorna true si el código de error del SIAT sugiere que la operación puede ser reintentada después de un tiempo (ej: saturación o timeout de base de datos).
func IsValidationCode ¶ added in v0.6.0
IsValidationCode retorna true si el código indica un error de validación de datos (ej: NIT inexistente, formato XSD inválido).
func IsWarningCode ¶ added in v0.6.0
IsWarningCode retorna true si el código es informativo o una advertencia que no impide el proceso.
func NewHTTPClient ¶ added in v0.6.0
func NewHTTPClient(cfg HTTPConfig) *http.Client
NewHTTPClient crea un cliente HTTP optimizado basado en HTTPConfig. Es útil para customizar la configuración sin reescribir todo el Transport.
Ejemplo:
cfg := siat.DefaultHTTPConfig() cfg.Timeout = 60 * time.Second client := siat.NewHTTPClient(cfg) s, err := siat.New(baseUrl, client)
func Verify ¶ added in v0.6.0
func Verify(resp interface{}) error
Verify analiza una respuesta del SIAT y determina si la operación fue exitosa. Si la respuesta contiene errores del SIAT (Transaccion=false o mensajes de error), construye y retorna un *SiatError detallado.
Es compatible con cualquier objeto de respuesta del SDK (RespuestaCuis, RespuestaRecepcion, etc.) utilizando reflexión para extraer los campos 'Transaccion' y 'MensajesList'.
Ejemplo:
resp, err := s.Codigos().VerificarNit(ctx, cfg, req)
if err != nil { return err } // Error de red
if err := siat.Verify(resp.Body.Content.RespuestaCuis); err != nil {
return err // Error del SIAT (ej: NIT inválido)
}
Types ¶
type Config ¶ added in v0.5.0
Config agrupa la configuración necesaria para realizar solicitudes autenticadas al SIAT. Es un alias a ports.Config y debe ser instanciada cuando se realicen llamadas a los servicios.
Campos:
- Token: Token de autenticación proporcionado por el SIAT (obligatorio)
- UserAgent: Identificador del cliente HTTP (opcional, pero recomendado para registro)
Ejemplo:
cfg := siat.Config{
Token: "tu_token_api",
UserAgent: "MyApp/1.0 (Bolivia)",
}
type HTTPConfig ¶ added in v0.6.0
type HTTPConfig = services.HTTPConfig
HTTPConfig es la configuración pública para personalizar el cliente HTTP del SDK. Permite que los usuarios customicen timeouts, connection pooling y TLS sin pasar su propio http.Client.
Campos principales:
- Timeout: Timeout total para solicitudes (default: 45s)
- MaxIdleConns: Pool global de conexiones ociosas (default: 100)
- MaxConnsPerHost: Conexiones simultáneas por host (default: 10)
- TLSMinVersion: Versión mínima de TLS (default: TLS 1.2)
Ejemplo:
cfg := siat.HTTPConfig{
Timeout: 60 * time.Second,
MaxConnsPerHost: 5,
}
client := siat.NewHTTPClient(cfg)
s, _ := siat.New(baseUrl, client)
func DefaultHTTPConfig ¶ added in v0.6.0
func DefaultHTTPConfig() HTTPConfig
DefaultHTTPConfig retorna la configuración HTTP recomendada para producción.
Valores:
- Timeout: 45 segundos
- MaxIdleConns: 100
- MaxConnsPerHost: 10
- MaxIdleConnsPerHost: 5
- TLSMinVersion: TLS 1.2
Esta es la configuración usada por defecto si no pasas un http.Client a New().
type HTTPMiddleware ¶ added in v0.6.0
type HTTPMiddleware = middleware.HTTPMiddleware
HTTPMiddleware es la interfaz pública que permite agregar comportamiento HTTP personalizado. Los usuarios pueden implementarla para agregar logging, métricas, retry, etc. sin necesidad de modificar el SDK.
Ejemplo: Implementar retry con exponential backoff:
type RetryMiddleware struct {
maxAttempts int
}
func (m *RetryMiddleware) WrapTransport(base http.RoundTripper) http.RoundTripper {
return &retryRoundTripper{
base: base,
maxAttempts: m.maxAttempts,
}
}
// Uso
s, err := siat.NewWithMiddleware(
baseUrl,
nil, // usa defaults
&RetryMiddleware{maxAttempts: 3},
)
type Map ¶ added in v0.4.0
type Map map[string]interface{}
Map es un alias para map[string]interface{} que proporciona métodos de utilidad para trabajar con datos JSON de forma más cómda. Es especialmente útil al trabajar con respuestas heterogéneas del SIAT.
func (Map) Sum ¶ added in v0.4.0
Sum retorna la suma de todos los valores numéricos en el Map. Soporta tipos float64, float32, int, int64 e int32. Los valores no numéricos se ignoran.
type SiatError ¶ added in v0.6.0
SiatError es el tipo de error que retorna el SDK. Permite al usuario distinguir entre diferentes tipos de errores: - Errores de red (timeout, conexión rechazada) - Errores del servidor SIAT (validaciones rechazadas) - Errores de autenticación (token inválido) - Y saber cuáles pueden/deben ser reintentados
Ejemplo:
resp, err := s.Codigos().SolicitudCuis(ctx, cfg, req)
if err != nil {
var siatErr *siat.SiatError
if errors.As(err, &siatErr) {
if siat.IsRetryable(err) {
// Reintentar después
} else if siat.IsNetworkError(err) {
// Error temporal de conexión
} else {
// Error del servidor o autenticación
}
}
}
func NewAuthError ¶ added in v0.6.0
NewAuthError crea un error de autenticación. No tiene sentido reintentar sin credentials válidas.
func NewNetworkError ¶ added in v0.6.0
NewNetworkError crea un error de red (timeout, connection refused, etc). Estos errores son reintentables.
func NewSiatError ¶ added in v0.6.0
NewSiatError crea un error del servidor SIAT. Indica que el servidor rechazó la solicitud por alguna razón específica.
func NewTimeoutError ¶ added in v0.6.0
NewTimeoutError crea un error de timeout. Es reintentable porque es un problema temporal.
type SiatServices ¶ added in v0.3.0
type SiatServices struct {
// contains filtered or unexported fields
}
SiatServices es el punto de entrada principal del SDK. Agrupa todas las implementaciones de los servicios del SIAT (Códigos, Sincronización, Operaciones, Compra-Venta, Computarizada, Electrónica) y proporciona acceso a ellos a través de métodos orientados a objetivos. Los usuarios deben crear una instancia usando New().
func New ¶
func New(baseUrl string, httpClient *http.Client) (*SiatServices, error)
New crea e inicializa una nueva instancia de SiatServices.
Parámetros:
- baseUrl: URL base de los servicios SIAT (ej: https://pilotosiatservicios.impuestos.gob.bo/v2)
- httpClient: Cliente HTTP personalizado (opcional). Si es nil, se crea uno con configuración segura.
La función configura automáticamente:
- Timeouts apropiados (15s handshake, 45s total)
- TLS 1.2+ para seguridad
- Pools de conexión para alto rendimiento
- Proxy desde variables de entorno si están configuradas
Retorna un error si baseUrl está vacía o si alguno de los servicios falla al inicializarse.
Ejemplo:
s, err := siat.New("https://pilotosiatservicios.impuestos.gob.bo/v2", nil)
if err != nil {
log.Fatal(err)
}
func NewWithMiddleware ¶ added in v0.6.0
func NewWithMiddleware(baseUrl string, httpClient *http.Client, middlewares ...HTTPMiddleware) (*SiatServices, error)
NewWithMiddleware crea una instancia de SiatServices con middlewares HTTP personalizados. Es útil para agregar logging, métricas, retry, circuit breaker, etc.
Parámetros:
- baseUrl: URL base del SIAT
- httpClient: Cliente HTTP (opcional, usa defaults si es nil)
- middlewares: Middlewares a aplicar en orden (primero = más externo)
Los middlewares se aplican al Transport del cliente, permitiendo interceptar todas las solicitudes.
Ejemplo completo con logging:
type LoggingMiddleware struct{}
func (LoggingMiddleware) WrapTransport(base http.RoundTripper) http.RoundTripper {
return &loggingRoundTripper{base: base}
}
type loggingRoundTripper struct { base http.RoundTripper }
func (rt *loggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
log.Printf("-> %s %s", req.Method, req.URL.Path)
resp, err := rt.base.RoundTrip(req)
if err == nil {
log.Printf("<- %d", resp.StatusCode)
}
return resp, err
}
// Uso
s, err := siat.NewWithMiddleware(baseUrl, nil, &LoggingMiddleware{})
func (*SiatServices) Codigos ¶ added in v0.3.0
func (s *SiatServices) Codigos() ports.SiatCodigosService
Codigos retorna el servicio para: - Solicitud de códigos CUIS (Código Único de Identificación de Sistemas) - Solicitud de códigos CUFD (Código Único de Facturación por Dirección) - Validación de números NIT (Rol Tributario) Los códigos CUIS y CUFD son obligatorios para emitir invoices.
func (*SiatServices) CompraVenta ¶ added in v0.3.0
func (s *SiatServices) CompraVenta() ports.SiatCompraVentaService
CompraVenta retorna el servicio para el sector de compra-venta (Sector 1). Permite enviar, recibir y anular facturas comerciales estándar. Este es el sector más común para comercios generales.
func (*SiatServices) Computarizada ¶ added in v0.4.0
func (s *SiatServices) Computarizada() ports.SiatComputarizadaService
Computarizada retorna el servicio para facturación computarizada (sin firma digital, basada en máquinas registradoras fiscales). Permite enviar, recibir y anular facturas de este tipo.
func (*SiatServices) Electronica ¶ added in v0.5.0
func (s *SiatServices) Electronica() ports.SiatElectronicaService
Electronica retorna el servicio para facturación electrónica (con firma digital). Permite enviar, recibir y anular facturas electrónicas de todos los sectores. Este es el tipo de facturación más moderno y flexible del SIAT.
func (*SiatServices) Operaciones ¶ added in v0.3.0
func (s *SiatServices) Operaciones() ports.SiatOperacionesPort
Operaciones retorna el servicio para la gestión de puntos de venta (PV), cierre de períodos de facturación y eventos significativos (cambios de modalidad, etc.).
func (*SiatServices) Sincronizacion ¶ added in v0.3.0
func (s *SiatServices) Sincronizacion() ports.SiatSincronizacionService
Sincronizacion retorna el servicio que proporciona acceso a catálogos maestros: actividades económicas, documentos fiscales, monedas, tipos de cambio, etc. Estos catálogos son esenciales para validar datos antes de emitir invoices.
func (*SiatServices) WithConfig ¶ added in v0.6.0
func (s *SiatServices) WithConfig(token string) ports.Config
WithConfig retorna una nueva instancia de ports.Config con el traceID actual. Esto permite que el usuario establezca el traceID una sola vez con WithTraceID() y que automáticamente se inyecte en todas las solicitudes posteriores.
El usuario debe proporcionar el Token de autenticación del SIAT. El UserAgent se establece en una cadena vacía y puede ser personalizado.
Parámetros:
- token: El token de autenticación del SIAT (obligatorio)
Retorna:
- ports.Config con TraceID pre-establecido
Ejemplo:
s.WithTraceID("trace-12345")
config := s.WithConfig("myToken123")
// config.TraceID es "trace-12345" automáticamente
func (*SiatServices) WithTraceID ¶ added in v0.6.0
func (s *SiatServices) WithTraceID(id string) *SiatServices
WithTraceID establece un ID de seguimiento (trace ID) para correlacionar solicitudes en sistemas distribuidos. El trace ID se inyecta en el encabezado HTTP "X-Trace-ID" en todas las solicitudes posteriores.
El trace ID es completamente opcional y no afecta la funcionalidad del SDK si no se proporciona. Es útil para:
- Correlacionar logs entre múltiples servicios
- Rastrear solicitudes a través de sistemas distribuidos
- Debugging de problemas en producción
Parámetros:
- id: El ID de seguimiento (puede estar vacío para limpiar el trace ID anterior)
Retorna el receptor (SiatServices) para permitir encadenamiento de métodos.
Ejemplo:
s.WithTraceID("trace-12345-dev").Operaciones()...
// El trace-12345-dev se incluirá en el encabezado X-Trace-ID de todas las solicitudes