Integrar una API en producción implica manejar fallos de red, validaciones y reglas de negocio. Esta guía te ayuda a interpretar los errores de QRwey! y definir una estrategia estable de reintentos, mensajes al usuario y registro para soporte.
No todos los errores se reintentan. Reintentar un
4xxsuele ser un error (excepto casos muy específicos).Distingue entre fallos temporales y definitivos.
5xxy timeouts suelen ser temporales.4xxsuelen ser definitivos.Registra contexto suficiente para soporte. Incluye endpoint,
idempotency-key(si aplica),request_id, timestamps y cuerpo del error.
Todos los errores de la API de QRwey! siguen una estructura consistente:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "One or more fields failed validation",
"details": [
{
"field": "amount",
"code": "INVALID_FORMAT",
"message": "amount must be a positive number"
}
],
"request_id": "req_01JCFG..."
}
}| Campo | Descripción |
|---|---|
code | Identificador estable del error (usa este campo como clave programática) |
message | Descripción legible del error |
details | Información adicional por campo (si aplica) |
request_id | Identificador único de la solicitud para trazabilidad y soporte |
Si tu integración depende del contenido del error, usa
codecomo clave estable y evita parsear textos libres enmessage.
| Código | Significado | Cuándo se usa |
|---|---|---|
200 | OK | GET exitoso |
201 | Created | POST que crea un recurso exitosamente |
400 | Bad Request | Sintaxis inválida, campos faltantes o tipos incorrectos |
401 | Unauthorized | Autenticación ausente o inválida |
403 | Forbidden | Autenticación válida pero permisos insuficientes |
404 | Not Found | Recurso no encontrado |
409 | Conflict | Conflicto de estado (duplicado, ya consumido) |
422 | Unprocessable Entity | Sintaxis válida pero error semántico o de regla de negocio |
429 | Too Many Requests | Límite de tasa excedido |
500 | Internal Server Error | Error interno inesperado |
502 | Bad Gateway | Fallo en servicio upstream (SAT, PAC) |
503 | Service Unavailable | Servicio temporalmente no disponible |
| Status | Código | Descripción | Qué hacer |
|---|---|---|---|
| 400 | VALIDATION_ERROR | Campos requeridos faltantes o tipos de datos inválidos | Corregir request, no reintentar |
| 400 | EXPIRED_QR_DATE | expires_at está en el pasado | Corregir la fecha de expiración |
| 401 | UNAUTHORIZED | API Key inválida o ausente | Verificar X-API-Key y el ambiente |
| 404 | STORE_NOT_FOUND | No se encontró la tienda con el store_uid proporcionado | Verificar el store_uid |
| 409 | DUPLICATE_IDEMPOTENCY_KEY | idempotency-key ya utilizada con datos distintos | Usar un nuevo idempotency-key o verificar el request original |
| 422 | STORE_DISABLED | La tienda está deshabilitada o su CSD es inválido/expirado | Verificar configuración de la tienda y CSD |
| 422 | INVALID_SAT_CATALOG_VALUE | Valor de catálogo SAT inválido | Verificar claves SAT en el request |
| 5xx | — | Error temporal del servidor | Reintentar con el mismo idempotency-key |
| Status | Código | Descripción | Qué hacer |
|---|---|---|---|
| 401 | UNAUTHORIZED | API Key inválida o ausente | Verificar X-API-Key y el ambiente |
| 404 | RESOURCE_NOT_FOUND | QR no encontrado | Verificar que el qr_id sea correcto |
| 422 | STORE_CONFIGURATION_ERROR | Configuración de la tienda o emisor incorrecta | Revisar code y message en la respuesta |
| Código | HTTP | Descripción |
|---|---|---|
VALIDATION_ERROR | 400 | Uno o más campos fallaron validación |
INVALID_RFC_FORMAT | 400 | Formato de RFC inválido |
INVALID_CSD_FORMAT | 400 | Formato de certificado CSD inválido |
AUTHENTICATION_REQUIRED | 401 | No se proporcionó autenticación |
INVALID_TOKEN | 401 | Token inválido o expirado |
INSUFFICIENT_PERMISSIONS | 403 | Token sin permisos suficientes |
RESOURCE_NOT_FOUND | 404 | Recurso no encontrado |
RFC_ALREADY_EXISTS | 409 | RFC ya registrado en esta cuenta |
QR_ALREADY_INVOICED | 409 | No se puede modificar un QR ya facturado |
CSF_VALIDATION_FAILED | 422 | Validación de CSF con el SAT falló |
CSD_RFC_MISMATCH | 422 | CSD no corresponde al RFC |
CSD_EXPIRED | 422 | Certificado CSD expirado |
RATE_LIMIT_EXCEEDED | 429 | Demasiadas solicitudes |
SAT_SERVICE_UNAVAILABLE | 502 | Servicios del SAT no disponibles |
PAC_SERVICE_UNAVAILABLE | 502 | Servicios del PAC no disponibles |
- Timeout (sin respuesta)
500–503429(respetando backoff)
- Cualquier
400–422(salvo429) 409(conflicto) sin revisar lógica404(no encontrado)
Para verificar si un QR expiró, consulta
GET /v1/qrs/{qrId}y revisa el campostatus: EXPIRED.
Para reintentos temporales:
- 1er retry: 1s
- 2do retry: 2s
- 3er retry: 4s
- 4to retry: 8s
Límite recomendado:
- Máximo 3–5 reintentos
- Máximo 30s de ventana total
Evita mostrar mensajes técnicos al usuario final. Mejor:
status: EXPIRED: "Este QR ya expiró. Solicita uno nuevo."409: "Este QR ya fue utilizado."404: "QR inválido. Verifica el código e inténtalo de nuevo."401: "No se pudo validar la solicitud." (solo si aplica al comercio)502: "Los servicios fiscales están temporalmente fuera de servicio. Intenta más tarde."
Recomendación mínima de logs por request:
- Método + path
- Timestamp inicio/fin
- Código HTTP
request_idde la respuesta de erroridempotency-key(si aplica)codeymessagedel error
Registra siempre el
request_iddevuelto por QRwey! — es la clave para soporte y escalación.
- Manejas explícitamente
404,409,422y los diferentes estatus del QR - Manejas
502y503(servicios SAT/PAC) - Reintentas solo en timeouts,
429y5xx - Reusas el mismo
idempotency-keyen reintentos - Mensajes al usuario son claros y no técnicos
- Logs incluyen
request_id,idempotency-keyy timestamps - Usas
code(nomessage) como clave programática para lógica de negocio
- Reintentos seguros: Idempotencia & Reintentos
- Flujo completo: Quickstart
- Detalle de endpoints y schemas: Referencia del API