Skip to content

En QRwey!, un código QR representa una intención de autofactura. Cada QR tiene un campo status que indica su estado actual, y una fecha de expiración que limita su vigencia.

Esta guía explica cómo interpretar correctamente el ciclo de vida de un QR usando el campo status y los códigos HTTP de la API.


Campo status

El estado de un QR se devuelve en el campo status tanto al generarlo (POST /v1/qrs) como al consultar su detalle (GET /v1/qrs/{qrId}).

StatusSignificado
PENDINGQR generado, esperando a ser escaneado
SCANNEDQR escaneado por el usuario desde la app
INVOICEDLa intención fue confirmada y el CFDi fue timbrado
EXPIREDEl QR alcanzó su fecha expires_at sin ser facturado
CANCELLEDEl QR fue cancelado manualmente

Flujo de estados

PENDING → SCANNED → INVOICED
   │         │
   │         └──→ EXPIRED

   ├──→ EXPIRED

   └──→ CANCELLED
  • Un QR inicia en PENDING al ser generado
  • Pasa a SCANNED cuando el usuario lo escanea desde la app
  • Si el usuario confirma la factura, pasa a INVOICED
  • Si el QR alcanza expires_at sin completar el flujo, pasa a EXPIRED
  • Un QR puede ser cancelado manualmente en cualquier momento previo a INVOICED

Códigos HTTP al consultar un QR

Además del campo status, el API responde con códigos HTTP que reflejan el estado:

Respuesta del APIInterpretación
200 OKQR encontrado, revisa el campo status para conocer su estado
404 Not FoundQR no encontrado (ID inválido o recurso eliminado)
422 Unprocessable EntityError de reglas de negocio o configuración

Este comportamiento aplica al endpoint:

GET /v1/qrs/{qrId}

QR pendiente (PENDING)

Cuando el status es PENDING:

  • El QR fue generado exitosamente
  • Aún no ha sido escaneado
  • Está dentro de su ventana de vigencia

Acciones recomendadas:

  • Mostrar o imprimir el QR al cliente
  • Monitorear si se desea

QR escaneado (SCANNED)

Cuando el status es SCANNED:

  • El usuario escaneó el QR desde la app de QRwey!
  • La intención está siendo revisada por el usuario
  • Aún no se ha confirmado la factura

Acciones recomendadas:

  • Esperar a que el usuario confirme
  • No generar un QR nuevo

QR facturado (INVOICED)

Cuando el status es INVOICED:

  • El CFDi fue timbrado exitosamente
  • Los campos invoice y customer del detalle contienen la información de la factura
  • El flujo se completó

Acciones recomendadas:

  • Registrar el invoice.uuid para conciliación
  • Descargar XML/PDF si es necesario desde invoice.xml_url y invoice.pdf_url

QR expirado (EXPIRED)

Cuando el status es EXPIRED:

  • El QR alcanzó su fecha expires_at
  • No puede resolverse ni facturarse
  • No puede reactivarse

Acciones recomendadas:

  • Informar al usuario que el QR expiró
  • Generar un nuevo QR si es necesario

QR cancelado (CANCELLED)

Cuando el status es CANCELLED:

  • El QR fue cancelado manualmente
  • No puede usarse

Acciones recomendadas:

  • Tratarlo como finalizado
  • Generar un nuevo QR si la operación sigue vigente

Expiración (expires_at)

Cada QR define una ventana de validez mediante expires_at.

Recomendaciones:

  • Usa expiraciones acordes a las reglas del negocio (ej. 5 días, hasta fin de mes)
  • Maneja siempre el estado EXPIRED
  • No intentes reutilizar QRs expirados

Reuso del QR

Por diseño:

  • Un QR representa una sola transacción
  • No debe reutilizarse
  • No debe regenerarse sin idempotencia

Si necesitas generar otro QR para la misma venta:

  • Crea una nueva intención
  • Usa un nuevo Idempotency-Key

Buenas prácticas de seguridad

  • Consulta QRs siempre desde tu backend
  • No expongas lógica de validación en frontend
  • Maneja explícitamente todos los estados

Checklist para producción

Antes de ir a producción:

  • Consultas el campo status para determinar el estado del QR
  • Manejas PENDING, SCANNED, INVOICED, EXPIRED y CANCELLED
  • Verificas invoice y customer cuando status es INVOICED
  • Logs con qr_id, status y timestamps
  • Mensajes claros para el usuario final

¿Qué sigue?