Manejo de estados y errores
La API responde los errores con un sobre (envelope) JSON uniforme. Programar contra ese sobre te evita parsear HTML o adivinar.
El sobre de error
{ "success": false, "message": "<texto legible>", "code": "<CÓDIGO>" }
success— siemprefalseen un error.message— texto para diagnosticar (no lo muestres tal cual al usuario final).code— código estable para ramificar tu lógica.
Códigos por escenario
| HTTP | code | Cuándo | Qué hacer |
|---|---|---|---|
400 | VALIDATION | El cuerpo no cumple el contrato (falta un campo, tipo inválido) | Corrige el payload; revisa los campos obligatorios |
401 | UNAUTHENTICATED | Falta el Authorization: Bearer o el token es inválido | Reautentica; revisa el header |
404 | NOT_FOUND | El recurso no existe o no es tuyo | No expongas que existe; trata como no encontrado |
Aislamiento por cuenta: consultar una sesión de otra cuenta devuelve
404(no403): nunca revelamos la existencia de recursos ajenos.
Ejemplos (verificados contra el simulador)
# sin Bearer en una ruta protegida -> 401 UNAUTHENTICATED
curl https://sim-productos.abiertolab.com/api/v1/ext/payment-sessions/status/ses_xxxxx
# cuerpo inválido (con Bearer) -> 400 VALIDATION
curl -X POST https://sim-productos.abiertolab.com/api/v1/ext/agreements \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{"no":"es-un-agreement"}'
Orden validación → auth: en un
POST, la validación del cuerpo corre antes que la autenticación. Un cuerpo inválido sin Bearer devuelve400 VALIDATION(no401); para ver el401usa una ruta protegida sin cuerpo (como elGETde arriba) o un cuerpo válido sinAuthorization.
Estos sobres (401 UNAUTHENTICATED, 400 VALIDATION, 404 NOT_FOUND) están verificados sobre HTTP en simulador/test/func/http-roundtrip.func.test.ts.
Sobre los estados de la sesión
No confundas error (la llamada falló) con estado (pending/paid/failed/expired): un paid o un expired son respuestas exitosas que describen el desenlace. → Ciclo de vida · Estados y contrato de error.