Skip to main content

Python SDK para construir, firmar y timbrar CFDI 4.0 contra el API de ContaDB

Project description

contadb-sdk

PyPI version Python versions License: MIT

SDK oficial de Python para construir, firmar y timbrar CFDI 4.0 contra el API público de ContaDB.

Consume timbres de tu bolsa prepagada usando un API token. Sin pagos por uso, sin contratos mensuales — solo timbra cuando lo necesites.


Instalación

pip install contadb-sdk

Requiere Python 3.10+.

Quickstart

from decimal import Decimal
from contadb_sdk import (
    ContaDBClient,
    CFDIBuilder,
    Certificado,
    Emisor,
    Receptor,
    Concepto,
)

# 1. Carga tu CSD (Certificado de Sello Digital del SAT)
cert = Certificado.cargar(
    cer_path="emisor.cer",
    key_path="emisor.key",
    password="MI_PASSWORD",
)

# 2. Construye el CFDI
cfdi_xml = (
    CFDIBuilder(
        emisor=Emisor(
            rfc="EKU9003173C9",
            nombre="ESCUELA KEMPER URGATE",
            regimen_fiscal="601",
        ),
        receptor=Receptor(
            rfc="URE180429TM6",
            nombre="UNIVERSIDAD ROBOTICA ESPAÑOLA",
            uso_cfdi="G03",
            domicilio_fiscal_receptor="65000",
            regimen_fiscal_receptor="601",
        ),
        serie="A",
        folio="1001",
        forma_pago="03",       # Transferencia electrónica
        metodo_pago="PUE",      # Pago en una sola exhibición
        lugar_expedicion="64000",
    )
    .agregar_concepto(
        Concepto(
            clave_prod_serv="43232408",
            clave_unidad="E48",
            descripcion="Servicios de consultoría en sistemas",
            cantidad=Decimal("1"),
            valor_unitario=Decimal("1000.00"),
            objeto_imp="02",
            tasa_iva=Decimal("0.16"),
        )
    )
    .construir_y_firmar(cert)
)

# 3. Timbra contra ContaDB
with ContaDBClient(api_token="cdb_TU_TOKEN_AQUI") as client:
    resultado = client.timbrar(cfdi_xml)

print(f"UUID:           {resultado.uuid}")
print(f"Saldo restante: {resultado.saldo_restante} timbres")
print(f"XML timbrado:   {len(resultado.xml_timbrado)} chars")

Características

  • Construcción CFDI 4.0 — Builder con API fluida, validación Pydantic, cálculo automático de impuestos.
  • Firma RSA-SHA256 — Carga .cer + .key del SAT, firma cadena original generada con XSLT oficial.
  • Cliente HTTP tipado — Errores mapeados a excepciones específicas (SaldoInsuficienteError, TokenRevocadoError, etc.).
  • Reintentos automáticos — Backoff exponencial con jitter en errores 429/5xx/red. Honra Retry-After. Idempotency-Key resiste duplicados.
  • CFDI relacionados — Emite bloques cfdi:CfdiRelacionados (sustitución, nota de crédito, devolución, etc.).
  • Complementos oficiales — Recepción de Pagos 2.0 y Carta Porte 3.1.
  • Cancelaciónclient.cancelar(uuid_cfdi, motivo, certificado, folio_sustitucion=...) con motivos SAT 01–04.
  • 100% tipado — Marcador py.typed para inferencia perfecta en IDEs y mypy --strict.
  • Cero dependencias mágicas — Solo pydantic, httpx, cryptography, lxml.

Manejo de errores

from contadb_sdk import (
    ContaDBClient,
    SaldoInsuficienteError,
    RateLimitError,
    TokenRevocadoError,
)

try:
    resultado = client.timbrar(xml)
except SaldoInsuficienteError:
    # Comprar más timbres en https://contadb.mx/facturacion
    ...
except RateLimitError as e:
    # El SDK ya reintentó automáticamente; aquí solo llegas si agotó los intentos.
    # e.retry_after trae los segundos sugeridos por el servidor.
    ...
except TokenRevocadoError:
    # Generar un nuevo token
    ...

Reintentos automáticos

El cliente reintenta solo en errores transitorios (HTTP 429, 500, 502, 503, 504 y fallos de red) con backoff exponencial + jitter. Cada reintento reusa el mismo Idempotency-Key, así que es seguro.

from contadb_sdk import ContaDBClient, RetryPolicy, RETRY_POLICY_NINGUNO

# Default: 3 intentos, backoff_factor=0.5, backoff_max=30s, honra Retry-After.
client = ContaDBClient(api_token="cdb_xxx")

# Personalizado:
client = ContaDBClient(
    api_token="cdb_xxx",
    retry_policy=RetryPolicy(max_intentos=5, backoff_factor=1.0, backoff_max=60.0),
)

# Sin reintentos (comportamiento de v1.0):
client = ContaDBClient(api_token="cdb_xxx", retry_policy=RETRY_POLICY_NINGUNO)

CFDI sustituto / nota de crédito / devolución

Para emitir un CFDI que referencia uno o varios CFDIs previos (sustitución tras cancelar con motivo 01, nota de crédito, devolución, etc.):

from contadb_sdk import CFDIBuilder, CfdiRelacionados

builder = CFDIBuilder(...).agregar_cfdi_relacionado(
    tipo_relacion="04",                 # 04 = Sustitución de los CFDI previos
    uuids=["550e8400-e29b-41d4-a716-446655440000"],
)

Catálogo c_TipoRelacion SAT: "01" nota de crédito, "02" nota de débito, "03" devolución, "04" sustitución, "05""07" traslados/anticipos.

Logging

El SDK emite eventos vía el logger estándar contadb_sdk (request, status, decisiones de reintento). Nunca loguea token, llave privada, contraseña ni XML.

import logging
logging.getLogger("contadb_sdk").setLevel(logging.INFO)

Configuración

Por defecto el cliente apunta a https://api.contadb.mx. Puedes cambiarlo:

client = ContaDBClient(
    api_token="cdb_xxx",
    base_url="https://staging.contadb.mx",  # o env var CONTADB_BASE_URL
    timeout=60.0,
)

Documentación

Cómo obtener un API token

  1. Crea cuenta en contadb.mx.
  2. Ve a Facturación → API Tokens y genera uno.
  3. Compra una bolsa de timbres (desde 100 timbres / $200 MXN).
  4. Usa el token con este SDK.

Licencia

MIT — ver LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

contadb_sdk-1.1.3.tar.gz (94.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

contadb_sdk-1.1.3-py3-none-any.whl (71.8 kB view details)

Uploaded Python 3

File details

Details for the file contadb_sdk-1.1.3.tar.gz.

File metadata

  • Download URL: contadb_sdk-1.1.3.tar.gz
  • Upload date:
  • Size: 94.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for contadb_sdk-1.1.3.tar.gz
Algorithm Hash digest
SHA256 e68f375a036a6134dab128864ada7ff651c96f07a907b60746d41dca9b73c20b
MD5 0f6b6499d5256b1158ff8cb55746fcae
BLAKE2b-256 479ad19965bcc54c61bc2b8d9634cbddb8bdc9bde553987f444c6a7ee7b47b80

See more details on using hashes here.

File details

Details for the file contadb_sdk-1.1.3-py3-none-any.whl.

File metadata

  • Download URL: contadb_sdk-1.1.3-py3-none-any.whl
  • Upload date:
  • Size: 71.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for contadb_sdk-1.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 1d808caf1d45fba2a8c137dce037be0d8c5036f6e39cc1d5fe8fdfb23c6c1a02
MD5 9a3696e713379d74fb03717ae6495e01
BLAKE2b-256 ab49957f5bc840b66a6f2086d2de234a125afc114a13d00964d307ed04d51cfc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page