Ejemplo en PYTHON
Ejemplo de uso del API SAT en python.
Archivo fuente: python.py
#!/usr/bin/env python3
"""
Ejemplo Python — POST /api/v1/usuario/datos-fiscales
Usa requests (pip install requests).
"""
import os
import sys
import json
import requests
from typing import Optional
class SatApiClient:
"""Cliente para la API de SAT API."""
def __init__(self, api_key: str, base_url: str = "https://api.cfdi4.com",
user_agent: str = "python-sat-api/1.0", timeout: int = 30):
self.api_key = api_key
self.base_url = base_url.rstrip("/")
self.user_agent = user_agent
self.timeout = timeout
self.session = requests.Session()
self.session.headers.update({
"Authorization": f"Bearer {api_key}",
"User-Agent": user_agent,
"Content-Type": "application/json",
})
def _post(self, endpoint: str, body: dict) -> dict:
"""Hace POST y devuelve el body parseado."""
url = f"{self.base_url}{endpoint}"
try:
r = self.session.post(url, json=body, timeout=self.timeout)
r.raise_for_status()
data = r.json()
return data.get("body", {})
except requests.exceptions.HTTPError as e:
return {"cfdi_codigo": 4001, "cfdi_texto": str(e), "data": None}
except requests.exceptions.Timeout:
return {"cfdi_codigo": 3001, "cfdi_texto": "Timeout", "data": None}
except requests.exceptions.RequestException as e:
return {"cfdi_codigo": 5001, "cfdi_texto": str(e), "data": None}
def datos_fiscales(self, rfc: str) -> dict:
"""POST /api/v1/usuario/datos-fiscales"""
return self._post("/api/v1/usuario/datos-fiscales", {"rfc": rfc.upper().strip()})
def opinion_cumplimiento(self, rfc: str) -> dict:
"""POST /api/v1/sat/opinion-cumplimiento"""
return self._post("/api/v1/sat/opinion-cumplimiento", {"rfc": rfc.upper().strip()})
def csf(self, rfc: str) -> dict:
"""POST /api/v1/sat/constancia-situacion-fiscal"""
return self._post("/api/v1/sat/constancia-situacion-fiscal", {"rfc": rfc.upper().strip()})
def main():
api_key = os.environ.get("SAT_API_KEY")
if not api_key:
print("ERROR: configura la variable de entorno SAT_API_KEY", file=sys.stderr)
print(" export SAT_API_KEY=039;sat_xxxxxxxxxxxx039;", file=sys.stderr)
sys.exit(1)
rfc = sys.argv[1] if len(sys.argv) > 1 else "XAXX010101000"
client = SatApiClient(api_key)
print(f"Consultando datos fiscales de RFC: {rfc}\n")
result = client.datos_fiscales(rfc)
codigo = result.get("cfdi_codigo", 0)
texto = result.get("cfdi_texto", "")
desc = result.get("cfdi_descripcion", "")
saldo = result.get("saldo", 0)
data = result.get("data")
print(f" Código: {codigo}")
print(f" Texto: {texto}")
print(f" Detalle: {desc}")
print(f" Saldo: {saldo} créditos")
if codigo == 1 and data:
print(f"\n Datos fiscales:")
print(f" {json.dumps(data, indent=4, ensure_ascii=False)}")
elif codigo == 1004:
print("\n ⚠️ Saldo insuficiente. Recarga en https://panel.cfdi4.com/saldos")
elif codigo == 1001:
print("\n ⚠️ API key inválida. Verifica la variable SAT_API_KEY")
sys.exit(0 if codigo == 1 else 1)
if __name__ == "__main__":
main()