Sat.Cfdi.Descarga.Masiva.Solicitud (sat_cfdi_descarga v1.5.7)

Copy Markdown

Servicio SolicitaDescarga del WS de Descarga Masiva (v1.5).

Endpoint: https://cfdidescargamasivasolicitud.clouda.sat.gob.mx/SolicitaDescargaService.svc.

Registra una solicitud de descarga por rango de fechas, RFC emisor/receptor, tipo de comprobante, estado, complemento, UUID, etc. Retorna un IdSolicitud que se usara despues para verificar el estado.

En v1.5 la operacion SolicitaDescarga fue reemplazada por tres operaciones:

  • SolicitaDescargaEmitidos — facturas emitidas por el RFC
  • SolicitaDescargaRecibidos — facturas recibidas por el RFC
  • SolicitaDescargaFolio — un CFDI especifico por UUID (Folio)

La funcion solicitar/3 selecciona automaticamente la operacion correcta segun params.tipo_solicitud (:emitidos | :recibidos | :folio).

Summary

Functions

Endpoint del servicio.

SOAPAction base (sin sufijo de operacion).

Selecciona la operacion SOAP segun el tipo de solicitud.

Registra una solicitud y retorna el IdSolicitud.

Functions

endpoint()

Endpoint del servicio.

soap_action_base()

SOAPAction base (sin sufijo de operacion).

soap_operation(arg1)

Selecciona la operacion SOAP segun el tipo de solicitud.

solicitar(token, params, opts \\ [])

Registra una solicitud y retorna el IdSolicitud.

Requiere un token vigente (Sat.Cfdi.Descarga.Masiva.Autenticacion.autenticar/1) y la FIEL para firmar el sobre SOAP.

Selecciona la operacion SOAP segun params.tipo_solicitud:

  • :emitidosSolicitaDescargaEmitidos
  • :recibidosSolicitaDescargaRecibidos
  • :folioSolicitaDescargaFolio

Opciones

  • :credential (requerido) — FIEL para firmar.
  • :endpoint — override.
  • :timeout — HTTP timeout.

Retorno

{:ok, %SolicitudResult{id_solicitud, cod_estatus, mensaje}}.

⚠️ {:ok, _} NO significa que el SAT aceptó. El SAT responde HTTP 200 incluso cuando rechaza la petición: el resultado real está en cod_estatus. Debes ramificar sobre cod_estatus:

cod_estatusSignificadoAcción
"5000"AceptadaUsa id_solicitud para verificar.
"5002"Se agotaron las solicitudes de por vidaYa hiciste 2 idénticas. Cambia rango/criterios.
"5005"Ya existe una solicitud con esos criteriosReutiliza el IdSolicitud anterior.
"301"XML Mal Formado / info inválidaRFC inválido, o pediste CFDI sin estado_comprobante: :vigente (el SAT no da XML cancelados).
"303"El sello no corresponde con RfcSolicitanteLa FIEL no es del rfc_solicitante.
"304"/"305"Certificado caduco/revocado/inválidoRevisa la FIEL.

Ver la tabla completa en Sat.Cfdi.Descarga.Masiva.

Errores ({:error, reason})

A nivel cliente: {:missing_option, :credential}, {:http_error, status, body}, {:network_error, reason}, {:soap_fault, code, string}, {:parse_error, :missing_fields, body}.

Reglas del SAT que provocan rechazo

  • Límite de por vida: máximo 2 solicitudes con los MISMOS parámetros (mismo RFC + mismo rango). La 3.ª idéntica devuelve "5002" permanente.
  • CFDI cancelados: para tipo_solicitud: :recibidos/:emitidos con descarga de XML, el SAT solo entrega vigentes. Envía estado_comprobante: :vigente; con :todos/:cancelado devuelve "301". Si necesitas cancelados, usa tipo_solicitud: :metadata.

Semántica de fecha_inicial / fecha_final (¡ojo!)

El rango filtra por la fecha de EMISIÓN del CFDI (fecha de emisión en el timbre), NO por "cuándo lo recibiste" ni por la fecha de certificación. Un CFDI aparece si FechaInicial <= fecha_emision <= FechaFinal.

Si esperabas facturas y la verificación regresa NumeroCFDIs: 0 / codigo_estado_solicitud: "5004", lo primero a revisar es el rango de fechas: que el año/mes sean correctos y que cubran la fecha de emisión de los CFDIs. Es la causa #1 de "recibí facturas pero dice 0". Verifica el rango real en el XML enviado (<des:solicitud FechaInicial=... FechaFinal=...>) y compáralo contra el portal del SAT (Consultar facturas) con el mismo RFC.

Respuesta cruda del SAT (HTTP 200)

<SolicitaDescargaRecibidosResponse xmlns="http://DescargaMasivaTerceros.sat.gob.mx">
  <SolicitaDescargaRecibidosResult
    IdSolicitud="790040c0-1135-4a30-bf03-9cb25f863396"
    RfcSolicitante="MACA961017759" CodEstatus="5000" Mensaje="Solicitud Aceptada"/>
</SolicitaDescargaRecibidosResponse>

Ejemplo

case Solicitud.solicitar(token, params, credential: cred) do
  {:ok, %{cod_estatus: "5000", id_solicitud: id}} -> {:ok, id}
  {:ok, %{cod_estatus: "5002"}} -> {:error, :limite_agotado}
  {:ok, %{cod_estatus: cod, mensaje: msg}} -> {:error, {:rechazada, cod, msg}}
  {:error, reason} -> {:error, reason}
end