Sincpro SIAT SOAP SDK
SDK para consumir servicios SOAP del SIAT (Sistema Integral de Facturación) de Bolivia. Implementado con Sincpro Framework 3.0 siguiendo arquitectura hexagonal y el patrón Unified Bus.
📋 Sobre el Proyecto
Este SDK proporciona una interfaz Python completa para interactuar con los servicios de facturación electrónica del SIAT de Bolivia, cubriendo:
- ✅ Facturación electrónica y computarizada
- ✅ Múltiples sectores (compra-venta, hotel, hospital, educativo, alquiler, etc.)
- ✅ Gestión de contingencias y eventos significativos
- ✅ Notas de crédito y débito
- ✅ Sincronización de catálogos
- ✅ Validación y firma digital de documentos XML
- ✅ Facturación masiva
Características principales
- Arquitectura modular: Basado en Sincpro Framework con arquitectura hexagonal
- Type-safe: Validación completa con Pydantic DTOs
- Gestión automática: CUFD (renovación diaria) y CUIS por punto de venta
- Context manager: Propagación automática de metadatos (token, ambiente, etc.)
- Multi-ambiente: Soporte para entornos de producción y piloto
- Tests completos: Suite de tests siguiendo las 9 etapas de certificación SIAT
📄 Licencia
Este proyecto está licenciado bajo LICENCIA EMPRESARIAL DE USO DE SOFTWARE de Sincpro S.R.L.
Resumen de términos
- ✅ Licencia no exclusiva e intransferible
- ✅ Uso limitado según contrato de licencia
- ❌ Prohibido: copiar, modificar o distribuir sin autorización
- ⚠️ El uso no autorizado activa mecanismos de seguridad
- ⚖️ Protegido por leyes de propiedad intelectual
Importante: El uso del Software requiere una licencia válida emitida por Sincpro S.R.L. El uso no autorizado puede resultar en sanciones legales y activación de medidas de protección.
Para más detalles, consulta el archivo LICENSE.md.
Pre-Requirements
- Python 3.12+
- Poetry para gestión de dependencias
- Virtualenv configurado (el proyecto usa virtualenv in-project)
Configuración de Poetry
El proyecto incluye un poetry.toml para crear el virtualenv dentro del proyecto:
[virtualenvs]
create = true
in-project = true
Esto crea el entorno virtual en .venv/ dentro del directorio del proyecto, facilitando la gestión y el aislamiento de dependencias.
Instalación
# Verificar que Poetry está instalado
poetry --version
# Instalar dependencias
poetry install
Configuración de Variables de Entorno
Códigos de Sistema (System Codes)
| Código | Sectores Soportados |
|---|---|
| 7C3121D9A5A00BCE7B6A8DF | Prevalorado, Alquiler, Prevalorado sin crédito fiscal |
| 7755D817B7935A52BC1A8DF | Hotel, Hospital, Educativo |
| 721CDB813A795709E2128DF | Computarizada, Electrónica, Nota de crédito/débito |
| 353274141204F512BD7F | Tasa cero, Educativo |
Variables Requeridas
# Token de autenticación SIAT
export SIAT_TOKEN="<tu_token_aqui>"
# Ambiente: 1=producción, 2=piloto/testing
export SIAT_ENVIRONMENT=2
# Modalidad: 1=electrónica, 2=computarizada
export SIAT_MODALITY=1
# Password para certificados de firma digital
export KEY_PASSWORD="<password_certificado>"
# Nivel de logging (opcional)
export SP_SIAT_LOG_LEVEL="INFO"
# Timeout para sincronización (opcional, en segundos)
export SYNC_OBJ_TIMEOUT=300
Uso del SDK
Este SDK está construido sobre Sincpro Framework 3.0.1 utilizando el patrón Unified Bus. El punto de entrada principal es siat_soap_sdk, que ejecuta Features y ApplicationServices del SDK.
Uso básico
Por defecto, el SDK utiliza el SIAT_TOKEN y SIAT_ENVIRONMENT configurados en las variables de entorno:
from sincpro_siat_soap import siat_soap_sdk
from sincpro_siat_soap.services.auth_permissions import (
CommandGenerateCUIS,
ResponseGenerateCUIS,
)
from sincpro_siat_soap.global_definitions import SIATEnvironment, SIATModality
# Ejecutar una operación (Feature)
response = siat_soap_sdk(
CommandGenerateCUIS(
nit=412158028,
system_code="353274141204F512BD7F",
point_of_sale=1,
branch_office=0,
billing_type=SIATModality.ELECTRONICA,
environment=SIATEnvironment.TEST,
),
ResponseGenerateCUIS,
)
print(f"CUIS generado: {response.cuis}")
Uso con contexto personalizado
Si necesitas usar un token o ambiente diferente al configurado por defecto, puedes usar el context manager:
from sincpro_siat_soap import siat_soap_sdk
from sincpro_siat_soap.global_definitions import SIATEnvironment
from sincpro_siat_soap.services.billing import (
CommandCheckHealth,
ResponseCheckHealth,
)
# Ejecutar con contexto personalizado usando context manager
with siat_soap_sdk.context({
"TOKEN": "tu_token_personalizado_aqui",
"SIAT_ENV": SIATEnvironment.PRODUCTION, # o SIATEnvironment.TEST
}) as sdk_with_context:
response = sdk_with_context(
CommandCheckHealth(),
ResponseCheckHealth,
)
print(f"Estado del servicio: {response.raw_response}")
El context manager del framework Sincpro permite:
- Thread-safe: Aislamiento de contexto por hilo
- Nested contexts: Soporta contextos anidados con capacidad de override
- Automatic propagation: El contexto se propaga automáticamente a Features y ApplicationServices internos
Servicios disponibles
El SDK organiza las operaciones en módulos por tipo de servicio:
from sincpro_siat_soap import siat_soap_sdk
# Autenticación y permisos
from sincpro_siat_soap.services.auth_permissions import (
CommandGenerateCUIS,
CommandGenerateCUFD,
)
# Sincronización de datos (catálogos)
from sincpro_siat_soap.services.synchronization_data import (
CommandGenerateSyncDataDict,
CommandCreateOrLoadSyncObj,
)
# Operaciones (puntos de venta, eventos significativos)
from sincpro_siat_soap.services.operations import (
CommandCreatePointOfSale,
CommandRegisterSignificantEvent,
)
# Archivos digitales (envío, verificación, anulación)
from sincpro_siat_soap.services.digital_files import (
CmdSendDocumentToSiat,
CmdVerifyDocument,
CmdCancelDocument,
)
# Facturación
from sincpro_siat_soap.services.billing import (
CommandCheckHealth,
CommandMasiveInvoceReception,
)
Ejemplo completo: Flujo de facturación
from sincpro_siat_soap import siat_soap_sdk
from sincpro_siat_soap.global_definitions import (
SIATEnvironment,
SIATModality,
SIATApprovedDocumentId,
SIATEmissionType,
SIATInvoiceType,
)
from sincpro_siat_soap.services.auth_permissions import (
CommandGenerateCUIS,
ResponseGenerateCUIS,
)
from sincpro_siat_soap.services.synchronization_data import (
CommandCreateOrLoadSyncObj,
ResponseCreateOrLoadSyncObj,
)
from sincpro_siat_soap.services.digital_files import (
CmdSendDocumentToSiat,
ResSendDocumentToSiat,
)
# 1. Generar CUIS (una vez por punto de venta)
cuis_response = siat_soap_sdk(
CommandGenerateCUIS(
nit=412158028,
system_code="353274141204F512BD7F",
point_of_sale=1,
branch_office=0,
billing_type=SIATModality.ELECTRONICA,
environment=SIATEnvironment.TEST,
),
ResponseGenerateCUIS,
)
# 2. Crear/cargar objeto de sincronización (gestiona CUFD y catálogos)
sync_response = siat_soap_sdk(
CommandCreateOrLoadSyncObj(
nit=412158028,
cuis=cuis_response.cuis,
branch_office=0,
point_of_sale=1,
system_code="353274141204F512BD7F",
path_serialized="./sync_data",
environment=SIATEnvironment.TEST,
modality=SIATModality.ELECTRONICA,
),
ResponseCreateOrLoadSyncObj,
)
sync_obj = sync_response.sync_obj
# 3. Enviar factura (con XML firmado previamente)
invoice_response = siat_soap_sdk(
CmdSendDocumentToSiat(
nit=sync_obj.nit,
cuis=sync_obj.cuis,
cufd=sync_obj.cufd,
sector_document=SIATApprovedDocumentId.COMPRA_VENTA,
emission_code=SIATEmissionType.ONLINE,
sent_date="2025-02-25T10:30:00.000",
hash_invoice_file="hash_del_archivo",
branch_office=sync_obj.branch_office,
system_code=sync_obj.system_code,
point_of_sale=sync_obj.point_of_sale,
xml="xml_comprimido_y_firmado",
type_invoice=SIATInvoiceType.CREDITO_FISCAL,
environment=SIATEnvironment.TEST,
modality=SIATModality.ELECTRONICA,
),
ResSendDocumentToSiat,
)
print(f"Factura enviada: {invoice_response.raw_response}")
Manejo de errores
El SDK lanza excepciones SIATException cuando hay errores en las operaciones:
from sincpro_siat_soap import siat_soap_sdk
from sincpro_siat_soap.shared.core_exceptions import SIATException
try:
response = siat_soap_sdk(command, ResponseType)
except SIATException as e:
print(f"Error SIAT: {e}")
# Manejar el error según tu lógica de negocio
Tests
poetry run pytest
SIAT Integration Tests (test/siat_test)
El directorio test/siat_test contiene tests de integración que validan el flujo completo de facturación electrónica con el sistema SIAT (Sistema de Facturación de Bolivia). Estos tests simulan el proceso real de certificación y operación con SIAT.
Estructura de tests por etapas
Los tests están organizados siguiendo las etapas de certificación SIAT:
Etapa 1: Obtención de CUIS (test_etapa_1.py)
Valida la generación del Código Único de Inicio de Sistemas (CUIS) para cada punto de venta.
from sincpro_siat_soap import siat_soap_sdk
from sincpro_siat_soap.services.auth_permissions import (
CommandGenerateCUIS,
ResponseGenerateCUIS,
)
# Generar CUIS para punto de venta
response = siat_soap_sdk(
CommandGenerateCUIS(
nit=customer_nit,
system_code=customer_system_code,
point_of_sale=1,
branch_office=0,
billing_type=SIATModality.ELECTRONICA,
environment=SIATEnvironment.TEST,
),
ResponseGenerateCUIS,
)
Conceptos clave:
- Cada punto de venta requiere su propio CUIS
- El CUIS se genera una sola vez por punto de venta
- Es necesario para todas las operaciones posteriores
Etapa 2: Sincronización de catálogos (test_etapa_2.py)
Sincroniza los catálogos de códigos del SIAT (tipos de documento, monedas, unidades de medida, etc.).
from sincpro_siat_soap.services.synchronization_data import (
CommandGenerateSyncDataDict,
ResponseGenerateSyncDataDict,
)
# Sincronizar catálogos
response = siat_soap_sdk(
CommandGenerateSyncDataDict(
nit=nit,
cuis=cuis,
system_code=system_code,
environment=environment,
point_of_sale=point_of_sale,
branch_office=branch_office,
),
ResponseGenerateSyncDataDict,
)
Etapa 3: Generación de CUFD (test_etapa_3.py)
El Código Único de Factura Diaria (CUFD) debe renovarse diariamente.
# Renovar CUFD (se hace automáticamente con el SynchronizationObject)
sync_obj.request_new_cufd()
Etapa 4, 7, 8: Facturación en línea (test_etapa_4_7_8_v2.py)
Tests de emisión, verificación, anulación y reversión de facturas en línea.
from sincpro_siat_soap.services.digital_files import (
CmdSendDocumentToSiat,
CmdVerifyDocument,
CmdCancelDocument,
CmdRevertCancelledDocument,
)
# 1. Enviar factura
res_send = siat_soap_sdk(
CmdSendDocumentToSiat(
nit=nit,
cuis=cuis,
cufd=cufd,
sector_document=SIATApprovedDocumentId.COMPRA_VENTA,
emission_code=SIATEmissionType.ONLINE,
xml=invoice_xml.compressed_xml,
# ... otros parámetros
),
ResSendDocumentToSiat,
)
# 2. Verificar estado de la factura
res_verify = siat_soap_sdk(
CmdVerifyDocument(
cuf_or_reception_code=cuf,
# ... otros parámetros
),
ResVerifyDocument,
)
# 3. Anular factura
res_cancel = siat_soap_sdk(
CmdCancelDocument(
cuf=cuf,
cancellation_reason=cancellation_type,
# ... otros parámetros
),
ResCancelDocument,
)
# 4. Revertir anulación
res_revert = siat_soap_sdk(
CmdRevertCancelledDocument(
cuf=cuf,
# ... otros parámetros
),
ResRevertCancelledDocument,
)
Sectores soportados:
- Compra y venta (COMPRA_VENTA)
- Notas de crédito/débito
- Sector educativo
- Sector hotelero
- Sector hospitalario
- Alquiler de bienes
- Prevalorada
- Tasa cero
Etapa 5, 6: Facturación fuera de línea (Contingencia) (test_etapa_5_6_v2.py)
Tests de emisión de facturas en modo offline con eventos significativos.
from sincpro_siat_soap.services.operations import (
CommandRegisterSignificantEvent,
)
# 1. Registrar evento significativo (corte de internet, luz, etc.)
significant_event_response = siat_soap_sdk(
CommandRegisterSignificantEvent(
event_type=significant_event[0],
description=significant_event[1],
start_datetime_event=start_datetime.isoformat(),
end_datetime_event=end_datetime.isoformat(),
# ... otros parámetros
),
ResponseRegisterSignificantEvent,
)
# 2. Enviar paquete de facturas offline
package = siat_soap_sdk(
CmdSendDocumentPackage(
xml_list=signed_invoice,
cafc=cafc, # Código de Autorización de Facturas de Contingencia
with_significant_event_type=significant_event[0],
emission_code=SIATEmissionType.OFFLINE,
# ... otros parámetros
),
ResSendDocumentPackage,
)
Eventos significativos soportados:
- Corte de internet (
SE_CORTE_INTERNET) - Corte de electricidad (
SE_CORTE_ELECTRICIDAD) - Falla de hardware (
SE_FALLA_HARDWARE) - Virus informático (
SE_VIRUS_INFORMATICO) - Problemas con Administración Tributaria (
SE_ADMINISTRACION_TRIBUTARIA) - Zonas sin internet (
SE_ZONAS_SIN_INTERNET) - Despliegue a zonas sin internet (
SE_DEPLIEGUE_A_ZONAS_SIN_INTERNET)
Etapa 9: Facturación masiva (test_etapa_9.py)
Tests de envío de múltiples facturas en un solo paquete.
from sincpro_siat_soap.services.billing import (
CommandMasiveInvoceReception,
CommandVerifyMassiveInvoice,
)
# Enviar paquete masivo
massive_response = siat_soap_sdk(
CommandMasiveInvoceReception(
xml=compressed_files.zip_file,
count_invoice=len(invoice_list),
# ... otros parámetros
),
ResponseMasiveInvoiceReception,
)
# Verificar procesamiento
validation = siat_soap_sdk(
CommandVerifyMassiveInvoice(
reception_code=massive_response.reception_code,
# ... otros parámetros
),
ResponseVerifyMassiveInvoice,
)
Objeto de sincronización (SynchronizationObject)
El SynchronizationObject es una utilidad central que encapsula y gestiona automáticamente:
- CUIS (Código Único de Inicio de Sistemas)
- CUFD (Código Único de Factura Diaria) con renovación automática
- Catálogos sincronizados del SIAT
- Configuración de punto de venta y sucursal
from sincpro_siat_soap.services.synchronization_data import (
CommandCreateOrLoadSyncObj,
ResponseCreateOrLoadSyncObj,
)
# Crear o cargar objeto de sincronización
response = siat_soap_sdk(
CommandCreateOrLoadSyncObj(
nit=nit,
cuis=cuis,
branch_office=0,
point_of_sale=1,
system_code=system_code,
path_serialized=".", # Ruta para persistir el objeto
environment=SIATEnvironment.TEST,
modality=SIATModality.ELECTRONICA,
),
ResponseCreateOrLoadSyncObj,
)
sync_obj = response.sync_obj
# Renovar CUFD cuando sea necesario
sync_obj.request_new_cufd()
Configuración de tests
Los tests utilizan fixtures definidas en conftest.py:
# Variables necesarias
customer_nit = 412158028
customer_system_code = "353274141204F512BD7F"
customer_default_branch_office = 0
point_of_sale = 1
# Certificados para firma digital
certs_path = "certs_guide/siat_pilot"
cert = open(f"{certs_path}/certificate.crt", "r").read()
key = open(f"{certs_path}/private.key", "r").read()
Ejecutar tests SIAT
# Todos los tests SIAT
make test_one t=test/siat_test
# Test específico por etapa
poetry run pytest test/siat_test/test_etapa_1.py -v
# Con output detallado
poetry run pytest test/siat_test/test_etapa_4_7_8_v2.py -vvs
Importante antes de ejecutar
- Configurar variables de entorno:
export SIAT_TOKEN="<tu_token_siat>"
export SIAT_ENVIRONMENT=2 # 1=producción, 2=piloto
export SIAT_MODALITY=1 # 1=electronica, 2=computarizada
export KEY_PASSWORD="<password_certificado>"
-
Tener certificados válidos en
certs_guide/siat_pilot/ -
Ejecutar primero
test_only_run_at_the_beggining.pypara crear puntos de venta si es necesario -
Los tests de contingencia (etapa 5-6) requieren configuración especial y deben ejecutarse en orden
Notas sobre las etapas
- Etapa 1: Ejecutar una sola vez por punto de venta
- Etapa 2: Ejecutar periódicamente para actualizar catálogos
- Etapa 3: El CUFD se renueva automáticamente cada 24 horas
- Etapas 4-8: Tests de flujo completo en línea (pueden ejecutarse múltiples veces)
- Etapas 5-6: Requieren registro previo de eventos significativos
- Etapa 9: Tests de alto volumen (facturación masiva)
Uso Interactivo con IPython
Para usar el SDK de forma interactiva:
poetry run ipython
Esto te permite probar comandos y explorar el SDK en un entorno REPL.
Instalación en Otros Proyectos
Generar el Wheel
Para distribuir e instalar esta librería en otros proyectos:
# Construir el paquete wheel
poetry build
# Esto crea un directorio `dist/` con el archivo .whl
Instalar el Wheel
# Con pip
pip install dist/sincpro_siat_soap-7.2.1-py3-none-any.whl
# Con poetry en otro proyecto
poetry add /path/to/sincpro_siat_soap-7.2.1-py3-none-any.whl
📚 Documentación Adicional
Para más información sobre el SDK:
- Ver tests de ejemplo en
test/siat_test/ - Consultar documentación generada en
generated_docs/ - Revisar contexto AI en
generated_docs/ai_context/
🤝 Soporte
Para soporte técnico o consultas sobre licencias, contactar a Sincpro S.R.L.
© 2025 Sincpro S.R.L. - Todos los derechos reservados
Metadata
Release files for sincpro-siat-soap 8.0.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sincpro_siat_soap-8.0.4.tar.gz | 85.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sincpro_siat_soap-8.0.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 268.5 kB
Release files / sincpro_siat_soap-8.0.4.tar.gz
| Download URL | sincpro_siat_soap-8.0.4.tar.gz |
|---|---|
| Size | 85.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a1ad7ecb953a481f79f447601146b7c4dfb388d22ddece6b6f7bac1758060b00
|
|
BLAKE2b-256 checksum How to use checksums |
03e479997bb7c7b23c85f62468e214f8014dbcf7cbdc00d8215080ef68866380
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.1 CPython/3.12.3 Linux/6.17.0-1022-azure
|
Release files / sincpro_siat_soap-8.0.4-py3-none-any.whl
| Download URL | sincpro_siat_soap-8.0.4-py3-none-any.whl |
|---|---|
| Size | 183.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2fb4d4e89b3ce96282489f8b301e0f3c1c542e61178cad88d08fc9d6dcdeb900
|
|
BLAKE2b-256 checksum How to use checksums |
d2697f5b53c1d989eaa5741f31b7f5161f9a817c2ab96c649d82fb6c67ed4c55
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.1 CPython/3.12.3 Linux/6.17.0-1022-azure
|