Qué hace bien tu código
El módulo verifica el certificado (verify=True por defecto). Eso es correcto y es lo que debe hacer un conector serio. El navegador, en cambio, perdona cadenas incompletas porque cachea intermedios; Python no.
Si estás integrando un módulo delivery carrier de Correos Express y, al llamar al entorno de pruebas www.test.cexpr.es, Odoo revienta con un error SSL de verificación de certificado, no es tu código. Es la cadena de certificado del host de staging de Correos Express. Aquí te explicamos la causa real y cómo solucionarlo sin debilitar producción.
Cuando integras Correos Express y ves este error, el instinto es revisar tu código. No hace falta. El problema está del lado de Correos Express, no del módulo.
Mientras desarrollas contra el entorno de pruebas de Correos Express, la petición HTTPS de Python (requests / urllib vía el módulo delivery carrier de Odoo) falla con una traza similar a esta:
requests.exceptions.SSLError: HTTPSConnectionPool(host='www.test.cexpr.es', port=443):
Max retries exceeded with url: /...
(Caused by SSLError(SSLCertVerificationError(1,
'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed:
unable to get local issuer certificate (_ssl.c:1007)')))
La frase clave es unable to get local issuer certificate. No dice que el certificado esté caducado, ni que el host no coincida, ni que la CA no sea de confianza. Dice que Python no puede construir la cadena hasta una raíz de confianza porque le falta un eslabón por el medio: el certificado intermedio.
El módulo verifica el certificado (verify=True por defecto). Eso es correcto y es lo que debe hacer un conector serio. El navegador, en cambio, perdona cadenas incompletas porque cachea intermedios; Python no.
www.test.cexpr.es presenta en el handshake TLS solo el certificado de servidor, sin adjuntar el intermedio que lo encadena con la raíz. El cliente queda sin poder validar contra el bundle público de CAs.
El host de producción, envio.correosexpress.com, sirve la cadena completa (servidor + intermedio). Por eso el mismo código que falla en staging valida sin tocar nada en producción. Confirma que el problema es de cadena, no de módulo.
La tentación es poner verify=False y seguir. No lo hagas: debilitas TODAS las llamadas HTTPS de esa instancia de Odoo, incluida producción. La solución correcta es darle al cliente el intermedio que falta, solo para este carrier.
Apunta REQUESTS_CA_BUNDLE a un bundle que incluya el intermedio y relanza la llamada. Si pasa, queda probado que es completitud de cadena, no el módulo.
Obtén el certificado intermedio de la cadena publicada del emisor y guárdalo junto a la raíz en un bundle PEM propio del carrier. No inventes nada: usas el intermedio oficial que el host de staging se olvida de servir.
En la llamada del carrier, usa requests(..., verify=<bundle>) apuntando al bundle de Correos Express (que ya incluye el intermedio). Solo afecta a este carrier; producción y el resto de integraciones siguen verificando contra el bundle de CAs por defecto.
Deja escrito en el README que el bundle existe porque el host de staging sirve cadena incompleta, y que producción no lo necesita. Así el siguiente que toque el módulo no "arregla" quitándolo y rompe staging otra vez.
En una frase: no toques el verify global ni metas verify=False. Construye un bundle por carrier con el intermedio de Correos Express, pásalo como verify en las llamadas de pruebas y documenta el motivo. Staging valida, producción sigue intacta y el módulo mantiene la verificación TLS que debe tener.
Mantenemos un conector de Correos Express para Odoo 19 y nos hemos topado exactamente con este comportamiento del certificado de pruebas. No es un misterio para nosotros: tenemos el setup del bundle funcional resuelto y documentado. No vendemos humo: somos un desarrollador en Barcelona, el módulo está mantenido para Odoo 19 y el soporte es directo, sin reseller por medio.
Puedes coger el conector de Correos Express del App Store y aplicar tú mismo el setup del bundle, o pedirnos que te lo dejemos funcionando en tu instancia. Si además trabajas otros carriers o marketplaces, mantenemos también el conector de MRW y conectores de marketplace (Mirakl y derivados), con el mismo criterio técnico.
Conectamos esta página técnica con el resto del catálogo de conectores y servicios de FlexigoTech.
No. El módulo hace lo correcto al verificar el certificado. El fallo está en el host de pruebas de Correos Express (www.test.cexpr.es), que sirve una cadena de certificado incompleta: falta el intermedio y por eso no valida contra el bundle de CAs públicas. El host de producción (envio.correosexpress.com) valida sin problemas.
No es recomendable. Desactivar verify globalmente debilita TODAS las llamadas HTTPS de esa instancia de Odoo, incluida producción, y te expone a man-in-the-middle. La solución correcta es pasar verify apuntando a un bundle propio que incluya el intermedio de Correos Express, solo para ese carrier, sin tocar el resto.
Apunta REQUESTS_CA_BUNDLE a un bundle que incluya el intermedio que falta y vuelve a lanzar la llamada. Si la verificación pasa, queda confirmado que el problema es la completitud de la cadena del host de staging y no el código del módulo.
Sí. Mantenemos un conector de Correos Express para Odoo 19 publicado en el App Store y ya hemos resuelto este comportamiento del certificado de staging. Ofrecemos el setup del bundle funcional y soporte directo con el desarrollador, sin reseller intermedio.
Te dejamos el bundle funcionando en tu instancia o te pasamos el conector de Correos Express para Odoo 19 con el problema ya resuelto. Soporte directo, sin reseller por medio.