Guías
CFDI y facturación electrónica, para developers
En México un pago no termina hasta que hay un CFDI válido detrás. Esta es la capa fiscal que la mayoría de los stacks internacionales ignora — SAT, PACs, complementos y catálogos — escrita para el ingeniero que tiene que hacer que la factura salga automática y correcta.
El CFDI es donde "aceptar un pago" se convierte en "producir un documento legal que la autoridad fiscal va a aceptar". La buena noticia es que nunca hablas directo con el SAT — integras un PAC (proveedor autorizado de certificación) que timbra tu XML. Por eso estas guías tratan al PAC como una dependencia intercambiable: elige por calidad de SDK y documentación, construye hacia la forma del CFDI y mantente neutral para que un cambio de precio o una caída no te dejen varado.
Los patrones duraderos son los mismos en cada complemento. Guarda el XML timbrado y validado indexado por su UUID y reconcílialo contra el id del pago, para que cada cargo tenga una factura comprobable adjunta — ese vínculo es lo que te salva en una auditoría. Y trata los catálogos del SAT como datos que actualizas con calendario, no constantes que quemas en el código: cambian, y un catálogo viejo es la razón más común de que se rechace un timbrado. Del CFDI 4.0 estándar a Carta Porte, hidrocarburos y las reglas de Banxico de al lado, esa columna vertebral se sostiene.
Las guías

Factura CFDI 4.0 automática cuando entra el pago: guía para devs con Stripe y Mercado Pago (México, 2026)
Guía vendor-neutral y con código para timbrar un CFDI 4.0 automático desde un webhook verificado de Stripe o Mercado Pago en México: PAC, CSD, RFC, PUE vs PPD.
Leer →
Cómo timbrar un CFDI de Nómina 4.0 en 2026 (guía dev)
Guía técnica para timbrar un CFDI de Nómina 4.0 con complemento 1.2 Revisión E vía API de un PAC en 2026. XML real, el subsidio en OtrosPagos, validaciones Rev E y checklist pre-timbrado.
Leer →
Outbox para timbrar CFDI: nunca pierdas ni dupliques un timbrado cuando tu PAC falla
Stripe cobra, timbras el CFDI en tu PAC y luego escribes el UUID en tu DB. Si el proceso se cae entre esas dos escrituras, dejas huérfano un timbre que pagaste — o un reintento ingenuo cambia la Fecha y genera un UUID duplicado. Lo resuelves con un comprobante congelado, un outbox transaccional e idempotencia del PAC. Primero en español, con código.
Leer →
Descarga masiva de tus CFDI del web service del SAT con tu e.firma, en Python
Guia de ingeniero para el web service de Descarga Masiva del SAT: baja en bloque tus CFDI emitidos o recibidos (o solo metadata) directo del SAT con tu e.firma (FIEL) — sin PAC, sin scrapear el portal. La maquina de estados de 4 pasos SOAP (Autenticacion, SolicitaDescarga, VerificaSolicitud, Descarga), la firma WS-Security (digest SHA1, RSA-SHA1, BinarySecurityToken, Timestamp), los limites reales de la v1.5 y código Python. Primero en espanol.
Leer →
Por qué tu descarga masiva del SAT se queda en "EnProceso" (y por qué el límite de 2,000 CFDI/día es un mito)
Tu SolicitaDescarga devuelve EnProceso porque el SAT la procesa de forma asíncrona — haces polling a VerificaSolicitud hasta Terminada y descargas los paquetes dentro de 72h. Esta guía ES-first de ingeniero modela la solicitud como máquina de estados (EnProceso/Terminada/Rechazada/Vencida/Error), desmiente el mito del "límite de 2,000 CFDI/día" con los límites reales de la v1.5 (200k registros/solicitud, 1M en metadata, 72h de disponibilidad, no descargar un XML dos veces) y muestra cómo partir rangos de fechas grandes en ventanas con jobs idempotentes y reanudables. Python/pseudocódigo.
Leer →
'Solicitud Aceptada' pero no descarga: la referencia de CodEstatus y EstadoSolicitud del SAT (5000, 5002, 5005)
Tu SolicitaDescarga devuelve 'Solicitud Aceptada' (CodEstatus 5000) y llevas 48 horas esperando: ese código es solo el acuse, no significa que el paquete esté listo. Para bajarlo tienes que pollear VerificaSolicitud con el IdSolicitud y leer EstadoSolicitud (1 Aceptada, 2 EnProceso, 3 Terminada, 4 Error, 5 Rechazada, 6 Vencida) — solo Terminada te da los IdsPaquetes. Esta referencia ES-first de ingeniero decodifica cada CodEstatus: autenticación (300 usuario no válido, 301 XML mal formado, 302/303 sello, 304/305 certificado) y solicitud (5002 se agotaron las solicitudes de por vida, 5003 tope máximo, 5004 sin información, 5005 duplicada, 5008 máximo 2 descargas por paquete, 5011 límite por folio/día, 404 error no controlado), con el fix de cada uno, las dos trampas que más pegan (5005 y 5002), un checklist de depuración de 30 segundos y los helpers isFinished()/isRejected()/isExpired() de phpcfdi y python-satcfdi. Python.
Leer →
Descarga masiva del SAT en producción: pipeline para bajar los CFDI de muchos RFC (despacho), en Python
Un despacho no baja CFDI de un RFC en un for feliz: baja de decenas de clientes, emitidas y recibidas, metadata y CFDI. Esta guía ES-first de ingeniero modela cada consulta al SAT como un job durable con máquina de estados — SolicitaDescarga una sola vez, IdSolicitud persistido, VerificaSolicitud con backoff — para nunca caer en 5005 (solicitud duplicada) ni 5002 (se agotaron las solicitudes de por vida). Sync incremental con watermark de fecha por RFC, dedup por UUID, la ventana de 72h y el 5008, y cómo repartir la carga entre muchos RFC. Python, con esquema de job y poller. De ingeniero, no de contador.
Leer →
El portal del SAT tiene tus CFDI pero tu descarga masiva baja un paquete vacío: diagnostícalo con NumeroCFDIs, en Python
El portal del SAT muestra tus CFDI para un rango de fechas, pero tu web service de Descarga Masiva baja un paquete vacío (ZIP vacío) o 'nunca termina' — un problema documentado y recurrente (python-satcfdi #49: el portal sí tiene registros pero VerificaSolicitud devuelve NumeroCFDIs 0, IdsPaquetes []). Esta guía ES-first de ingeniero parte el problema en 30 segundos con un solo dato: NumeroCFDIs en VerificaSolicitud. Si es 0, tu consulta del WS no es la del portal — rfcSolicitante debe coincidir con RfcEmisor (emitidas) o RfcReceptor (recibidas); pedir la dirección equivocada devuelve 0 en silencio, y un rango solo-fecha o con la zona horaria corrida excluye todos los registros (manda día completo T00:00:00/T23:59:59 en hora del centro de México). Si el conteo coincide pero el ZIP sale vacío, guardaste la cadena base64 en vez de hacer base64.b64decode del Paquete a bytes, y solo debes llamar Descarga cuando EstadoSolicitud es 3 (Terminada). Incluye la prueba de 30 segundos (replica la consulta exacta del portal y pide Metadata) y por qué un síntoma compartido entre issues idénticos de GitHub es el error compartido, no un bug de la librería. Python. De ingeniero, no de contador.
Leer →
Cómo leer un paquete de la Descarga Masiva del SAT: de base64 a ZIP, el TXT de Metadata delimitado por tilde y el XML del CFDI, en Python
Todos los posts de Descarga Masiva terminan cuando llega el paquete — ninguno te dice cómo leerlo. El `Paquete` de la respuesta `Descarga` llega en base64: lo decodificas y lo descomprimes como ZIP (en memoria). Un request de Metadata te da un `<UUID>-N.txt` delimitado por TILDE (`~`), con encabezado y 12 columnas (Uuid, RfcEmisor/Receptor, NombreEmisor/Receptor, RfcPac, FechaEmision, FechaCertificacionSat, Monto, EfectoComprobante I/E/N/P/T, Estatus Vigente/Cancelado, FechaCancelacion); un request de CFDI te da el XML firmado de cada comprobante. La trampa (phpcfdi #23): NombreEmisor/NombreReceptor pueden traer el propio `~`, más CR/LF y comillas, así que `line.split("~")` desalinea las columnas — parsea a la defensiva con max-split o un lector CSV tolerante (`delimiter="~"`) y normaliza. Guía de ingeniero en Python: usa Metadata para acotar, CFDI para validar.
Leer →
Cómo validar un CFDI recibido antes de deducirlo: XSD, sello, vigencia y lista negra 69-B, en Python
Todos los tutoriales de CFDI enseñan a emitir. Ninguno a confiar en lo que llega a cuentas por pagar. Antes de deducir un CFDI recibido tienen que pasar cuatro checks: el XML valida contra el XSD de CFDI 4.0, el sello es una firma RSA-SHA256 real sobre la cadena original, el SAT dice Vigente (no Cancelado) y el RFC del emisor no está Definitivo en la lista 69-B. Guía de ingeniero en Python, con el gotcha del total-como-string que rompe en silencio la consulta de vigencia y el gate de AP que rechaza o retiene ante cualquier falla.
Leer →
Automatiza cuentas por pagar en México: extrae facturas con Claude, concilia contra el CFDI recibido y monitorea la 69-B (Python, 2026)
Un pipeline de cuentas por pagar con código para México: usa Structured Outputs de Claude para extraer campos tipados de PDFs y tickets no-CFDI, luego concilia de forma determinista en Python contra el XML del CFDI recibido por UUID, RFC y total — con un monitor 69-B programado.
Leer →
Cómo validar el RFC sin pedir la Constancia de Situación Fiscal
Tutorial de ingeniero para validar el RFC de un cliente en el alta sin pedir la Constancia de Situación Fiscal. Tras el Comunicado SAT 04/2026, exigir la CSF para facturar es una infracción multable. Valida formato + dígito verificador del RFC localmente, captura CP/régimen/uso con dropdowns y verifica con un web service de PAC.
Leer →
Automatiza la factura global dentro del plazo de 24 horas del SAT: el job diario que los blogs de los PAC no te enseñan
¿Vendes a público en general? Agregas las ventas en un CFDI global (regla 2.7.1.21 RMF 2026) y lo timbras dentro de 24h del cierre. Aquí va el job diario.
Leer →
Retenciones de IVA e ISR en plataformas 2026: la guía del ingeniero para construir el cálculo y el CFDI de retenciones
Desde el 1 de enero de 2026, si tu marketplace mexicano paga a vendedores quizá seas retenedor: retén ISR 2.5% + IVA 8%, néttalo y emite el CFDI.
Leer →
No canceles el CFDI — emite una nota de crédito: automatiza el CFDI de Egreso para reembolsos de Stripe y Mercado Pago
Al reembolsar un pago en México no cancelas el CFDI original: emites un CFDI de Egreso (nota de crédito) relacionado. Guía de ingeniero para automatizarlo desde el webhook.
Leer →
Automatiza el Complemento de Pago (REP) desde Stripe y Mercado Pago — y la trampa de cancelación de la RMF 2026
Si facturas como PPD en México, el webhook de pago es tu disparador fiscal. Conecta Stripe y Mercado Pago para timbrar el REP — y la trampa de cancelación de la RMF 2026.
Leer →
Actualización de catálogos CFDI (junio 2026, c_NumPedimentoAduana): tu código no cambia, pero tu pipeline sí
El 19 de junio de 2026 el SAT agregó registros obligatorios al catálogo CFDI 4.0 c_NumPedimentoAduana. El XSD no cambió: tu código tampoco, pero tu pipeline sí debe.
Leer →
Carta Porte 3.1: la guía de un dev para timbrar el complemento de traslado del SAT (México, 2026)
Guía vendor-neutral y code-first para emitir una Carta Porte 3.1 en México: CFDI de Traslado vs Ingreso, los cuatro bloques del complemento, timbrado vía PAC y trampas 2026.
Leer →
Complemento de Hidrocarburos en CFDI: cómo timbrar facturas de combustible sin que el SAT te las rechace (abril 2026)
Guía de ingeniero para el Complemento de Hidrocarburos y Petrolíferos del SAT, vigente el 24 abril 2026: 5 atributos, validación L_CNE y multas $17k-97k.
Leer →
Facturación electrónica en LATAM 2026: el mapa para developers (MX, AR, BR, CO, CL)
Mapa para developers de la facturación electrónica en México, Argentina, Brasil, Colombia y Chile: autoridad, formato, modelo de clearance y los cambios 2026 a tiempo.
Leer →
Nivel 2 Bis y la regla de 4 pasos de Banxico: qué cambia en tu checkout y tu app de cobros antes del 14 de diciembre de 2026
Las reglas de Banxico de mediados de 2026 crean la cuenta Nivel 2 Bis sin RFC y limitan las transferencias a 4 pasos. Guía de onboarding y checkout para devs.
Leer →
Trabaja conmigo en esto
Preguntas frecuentes
- ¿Me integro directo con el SAT para emitir un CFDI?
- No. Te integras con un PAC (Proveedor Autorizado de Certificación), que valida y timbra tu CFDI XML en nombre del SAT y te devuelve el UUID. Tu trabajo es construir un documento CFDI 4.0 correcto y mandarlo al PAC — elige el PAC por calidad de SDK y docs, y mantén tu código neutral para poder cambiar.
- ¿Cómo guardo los CFDI para que una auditoría no duela?
- Guarda el XML timbrado completo (no solo un PDF) indexado por su UUID, y liga cada CFDI al id del pago que lo generó. Ten presente el periodo de conservación que exige el SAT. La conciliación — cargo ↔ UUID ↔ pedido — es justo lo que pide un auditor, así que constrúyela desde el día uno en lugar de reconstruirla después.
- ¿Necesito un complemento como Carta Porte o Hidrocarburos?
- Solo si tu operación lo dispara. La Carta Porte se exige cuando hay traslado de mercancías por vías públicas (carretera, ferrocarril, agua o aire); el complemento de Hidrocarburos aplica a transacciones del sector combustibles. Son añadidos al CFDI base con sus propios catálogos y reglas de validación — primero construye bien el CFDI base y luego adjunta el complemento que tu negocio de verdad necesita.