⚙️ Problema con API SOAP (PHP/TypeScript): cadena downloadContent() no retorna datos al recuperar CFDIs sin UUID

  • Autor Autor PonnVolt
  • Fecha de inicio Fecha de inicio
PonnVolt

PonnVolt

Curioso
Verificado por Whatsapp
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Llevo varias semanas intentando resolver un problema con la API SOAP al consumir el método downloadContent() dentro de un flujo de recuperación de CFDIs de nómina previamente timbrados.

El objetivo es recuperar los XML y PDF de los timbrados que completaron el proceso en el PAC pero experimentaron un timeout durante la generación del PDF, por lo que no contamos con el UUID en nuestra base de datos. La restricción principal es que debemos recuperar el CFDI únicamente con los datos del comprobante (RFC, serie, folio, total, fecha, etc.), sin usar el UUID.

Contexto técnico​

La implementación se basa en el ejemplo oficial index_recovery.php para la función downloadContent(). De acuerdo con la documentación, la recuperación por datos (sin UUID) debería ser posible. No obstante, tras múltiples pruebas, todas las respuestas retornan SUCCESS: vacío, sin incluir las URLs del XML ni del PDF.

Ejemplo base utilizado (type = 2, nómina):​


text
<span><span>|#|MPXC830715BF8|#|CRISTIAN PEREZ MONTERROSAS MACEDA|#|NOM-C4FO|#|9|#|8330.69|#|2025-12-31|##||#||#||#||#||#||#|<br></span></span><span></span>
Estructura esperada:

text
<span><span>|#|RFC|#|NOMBRE|#|SERIE|#|FOLIO|#|TOTAL|#|FECHA|##||#||#||#||#||#||#|<br></span></span><span></span>
Parámetro type: 2 (Payroll)

Request SOAP completo:​

xml
<span><span>&lt;</span><span>SOAP-ENV:</span><span>Envelope</span><span> </span><span>xmlns:</span><span>SOAP-ENV</span><span>=</span><span>"</span><span>http://schemas.xmlsoap.org/soap/envelope/</span><span>"</span><span><br></span></span><span><span> </span><span>xmlns:</span><span>ns1</span><span>=</span><span>"</span><span>https://cfdi360.com/webservice</span><span>"</span><span>&gt;</span><span><br></span></span><span><span> </span><span>&lt;</span><span>SOAP-ENV:</span><span>Header</span><span>&gt;</span><span><br></span></span><span><span> </span><span>&lt;</span><span>Auth</span><span>&gt;</span><span><br></span></span><span><span> </span><span>&lt;</span><span>userName</span><span>&gt;</span><span>SAA090305UF4</span><span>&lt;/</span><span>userName</span><span>&gt;</span><span><br></span></span><span><span> </span><span>&lt;</span><span>password</span><span>&gt;</span><span>SAA090305UF4#</span><span>&lt;/</span><span>password</span><span>&gt;</span><span><br></span></span><span><span> </span><span>&lt;/</span><span>Auth</span><span>&gt;</span><span><br></span></span><span><span> </span><span>&lt;/</span><span>SOAP-ENV:</span><span>Header</span><span>&gt;</span><span><br></span></span><span><span> </span><span>&lt;</span><span>SOAP-ENV:</span><span>Body</span><span>&gt;</span><span><br></span></span><span><span> </span><span>&lt;</span><span>ns1:</span><span>downloadContent</span><span>&gt;</span><span><br></span></span><span><span> </span><span>&lt;</span><span>content</span><span>&gt;</span><span>&lt;![CDATA[|#|MOMC830815BF8|#|CRISTIAN RAFAEL MONTERROSAS MACEDA|#|NOM-C4FO|#|9|#|8330.69|#|2025-12-31|##||#||#||#||#||#||#|]]&gt;</span><span>&lt;/</span><span>content</span><span>&gt;</span><span><br></span></span><span><span> </span><span>&lt;</span><span>type</span><span>&gt;</span><span>2</span><span>&lt;/</span><span>type</span><span>&gt;</span><span><br></span></span><span><span> </span><span>&lt;/</span><span>ns1:</span><span>downloadContent</span><span>&gt;</span><span><br></span></span><span><span> </span><span>&lt;/</span><span>SOAP-ENV:</span><span>Body</span><span>&gt;</span><span><br></span></span><span><span></span><span>&lt;/</span><span>SOAP-ENV:</span><span>Envelope</span><span>&gt;</span><span><br></span></span><span></span>
Respuesta:

xml
<span><span>&lt;</span><span>return</span><span> </span><span>xsi:</span><span>type</span><span>=</span><span>"</span><span>xsd:string</span><span>"</span><span>&gt;</span><span>SUCCESS:</span><span>&lt;/</span><span>return</span><span>&gt;</span><span><br></span></span><span></span>
(Vacía, sin datos de archivo ni URLs).

Variantes probadas​

He probado múltiples combinaciones para el content string, incluyendo:

  1. Con y sin nombre del receptor.
  2. Con o sin el campo total.
  3. Con o sin fecha.
  4. Variaciones en la relación entre serie y folio:
    • |#|SERIE|#||#|FOLIO|#|
    • |#|SERIE|#|FOLIO|#|
  5. Con campos adicionales vacíos al final.
  6. Cambiando type entre 1 (Invoice) y 2 (Payroll).
Ninguna de estas variantes retornó resultados.

Prueba exitosa con UUID​

Cuando el UUID está presente, la función sí responde correctamente y entrega los datos de xml_url y pdf_url.
Ejemplo funcional:

text
<span><span>48A31747-A0C4-449A-B0C1-13F2548E46F0|#||#||#||#||#||#||<br></span></span><span></span>
o:

text
<span><span>|#|MPXC830715BF8|#||#|NOM-C4FO|#||#|9|#|2025-12-31|##|48A31747-A0C4-449A-B0C1-13F2548E46F0|#||#||#||#||#||#|<br></span></span><span></span>
Ambos devuelven correctamente las URLs del CFDI.

Sin embargo, no es viable para nuestro caso de uso depender del UUID, ya que no lo tenemos registrado en los casos con timeout durante la timbración.

Contexto adicional (colateral)​

Además del problema con la cadena SOAP, el proyecto presenta factores que podrían influir en el diagnóstico:

  • En ciertas pruebas, el botón de verificación/refresh en la interfaz invoca una función diferente, afectando el flujo de envío. (YA RESUELTO)
  • El timestamp usado en la cadena (parte del request) parece generarse con un huso horario distinto, lo que podría estar causando desincronización o invalidación del request.(YA RESUELTO)
Aun así, el núcleo del problema sigue siendo la generación y validación de la cadena SOAP downloadContent(), y cómo lograr una recuperación correcta sin UUID.

Agradecería cualquier orientación, ejemplos funcionales o documentación no oficial que ayude a comprender el formato esperado del campo content en este método.

 
PonnVolt, parece que has explorado a fondo el problema. Asegúrate de que el formato de la cadena content sea estrictamente el que la API espera. A veces, pequeños errores en el formato pueden resultar en respuestas vacías. Verifica también los posibles requerimientos adicionales en la documentación de la API, ya que algunos servicios tienen restricciones específicas para consultas sin UUID. Considera contactar al soporte del API si la documentación no es clara.
 
Atrás
Arriba