Skip to content
Last updated

Guía Rápida

En esta guía integrarás un flujo completo de autofactura CFDI usando QRwey!.

Al finalizar este Quickstart habrás logrado:

  • Registrar una venta
  • Generar una intención de autofactura mediante un código QR
  • Resolver el QR desde la app de QRwey!
  • Convertir la intención en un CFDI timbrado (XML)
  • Obtener su representación impresa (PDF)
  • Opcionalmente consultar la intención de factura

Todo usando la API de QRwey!, sin portales complejos ni formularios innecesarios.


Flujo general

Antes de comenzar, este es el flujo que implementarás:

  1. Tu sistema registra una venta
  2. Usas el API de QRwey! para generar una intención de autofactura
  3. Se genera un código QR seguro y efímero
  4. El usuario escanea el QR desde la app de QRwey! y:
    • El usuario valida la información
    • Con un clic, QRwey! timbra el CFDI y genera el XML y PDF
    • Dentro de la aplicación móvil puedes visualizar, compartir o enviar por correo el XML y PDF

Requisitos previos

Antes de iniciar, asegúrate de contar con:

  • Una API Key válida de QRwey! modo developer para usar una SA y timbres de prueba
  • Acceso al entorno de pruebas
  • Un cliente HTTP (curl, Postman, etc.)
  • La app de QRwey! que puedes descargar para iOS o para Android
  • Configurar la app de QRwey! para que tenga al menos un RFC al cual facturar tu(s) prueba(s)

Autenticación

Todas las peticiones a la API de QRwey! requieren:

  • Header X-API-Key
  • Header Idempotency-Key para operaciones de escritura

Ejemplo base:

X-API-Key: TU_API_KEY_MODO_DEV
Idempotency-Key: uuid-unico
Content-Type: application/json

⚠️ Importante
Idempotency-Key evita operaciones duplicadas si ocurre un reintento por problemas de red por ejemplo


Base URL (servidores)

La especificación OpenAPI de QRwey! define estos servidores:

  • Producción: https://clients.qrwey.com
  • Desarrollo/Pruebas: https://api-dev.qrwey.com

En este Quickstart usaremos Desarrollo/Pruebas por default.

Cuando pases a producción, solo cambia el host a https://clients.qrwey.com y no olvides cambiar TU_API_KEY productiva


Paso 1: Generar un Código QR (POST /api/v1/qrs)

Este endpoint crea una transacción y regresa el QR en 3 formatos:

  • qr_base64 (imagen PNG en base64 para incrustar/impresión)
  • qr_url (URL firmada para ver/descargar el PNG)
  • qr_content (deep link que contiene v, t y m)

Request de ejemplo (DEV)

Consejo: usa un expires_at razonable (p.ej. 5–15 minutos) para pruebas y operación.

curl -X POST "https://api-dev.qrwey.com/api/v1/qrs" \
  -H "X-API-Key: TU_API_KEY" \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
  -H "Content-Type: application/json" \
  -d '{
    "store": "PetroStation #45",
    "issuer_rfc": "EKU9003173C9",
    "amount": 133.00,
    "subtotal": 115.08,
    "currency": "MXN",
    "sat_payment_method": "04",
    "expires_at": "2025-12-29T23:59:59Z",
    "operation": "INVOICE",
    "operation_data": [
      {
        "sku": "GAS87",
        "description": "Gasolina Magna",
        "amount": 115.08,
        "quantity": 5.662,
        "sat_unit_key": "LTR",
        "unit_price": 20.325,
        "sat_product_service_key": "15101515",
        "sat_tax_object_key": "02",
        "taxes": [
          {
            "type": "Traslado",
            "tax": "002",
            "factor": "Tasa",
            "rate": "0.160000",
            "taxable_base": 112.0,
            "amount": 17.92
          }
        ]
      }
    ]
  }'

Respuesta esperada (201)

{
  "qr_base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...",
  "qr_url": "https://api-dev.qrwey.com/qr.png?t=YWFh...&exp=1696200000&sig=YmJi...",
  "qr_content": "https://api-dev.qrwey.com/go?v=1&t=YWFh...&m=YmJi...",
  "created_at": "2025-09-11T18:25:43Z",
  "expires_at": "2025-09-30T23:59:59Z"
}

¿Qué debes guardar?

  • Guarda qr_content (o el QR impreso/mostrado que lo contiene).
  • qr_url es útil si quieres mostrar/descargar el PNG directamente.
  • expires_at te indica hasta cuándo el QR será válido.

Paso 2: El usuario escanea el QR

El usuario:

  • Escanea el QR desde la app de QRwey!
  • Revisa el detalle de la venta
  • Confirma que la información fiscal es correcta

Este paso ocurre fuera de tu sistema y no requiere integración adicional.


Paso 3: Timbrado del CFDi

Una vez confirmada la información por el usuario:

  • QRwey! timbra el CFDI
  • Se genera el XML timbrado
  • Se genera la representación impresa (PDF)

Este proceso es gestionado completamente por QRwey! y dentro de la app móvil donde el usuario inclusive puede visualizar, compartir o enviar por correo dicho CFDi.


Paso 4: Opcionalmente consultar la intención de factura con GET /api/v1/qrs

Cuando el usuario escanea el QR, la app móvil extrae de qr_content estos parámetros:

  • v (versión del formato; actualmente "1")
  • t (token opaco Base64URL)
  • m (firma HMAC truncada Base64URL)

Con esos valores, se consulta el endpoint de resolución.

4.1 Extraer v, t y m desde qr_content

Ejemplo de qr_content:

https://api-dev.qrwey.com/go?v=1&t=YWFh...&m=YmJi...

De ahí obtienes:

  • v=1
  • t=YWFh...
  • m=YmJi...

4.2 Request de resolución (DEV)

curl -X GET "https://api-dev.qrwey.com/api/v1/qrs?v=1&t=YWFh...&m=YmJi..." \
  -H "X-API-Key: TU_API_KEY"

Respuesta esperada (200)

{
  "id": "tra_4aca0361cfcd41c097663db44008fbb9",
  "store": "PetroStation #45",
  "issuer_rfc": "EKU9003173C9",
  "issuer_name": "ESCUELA KEMPER URGATE",
  "amount": 133.0,
  "subtotal": 115.08,
  "currency": "MXN",
  "sat_payment_method": "04",
  "sat_payment_method_desc": "Tarjeta de crédito",
  "created_at": "2025-09-29T13:00:00Z",
  "expires_at": "2025-09-30T23:59:59Z",
  "operation": "INVOICE",
  "operation_data": [
    {
      "sku": "GAS87",
      "description": "Gasolina Magna",
      "amount": 115.08,
      "quantity": 30,
      "sat_unit_key": "LTR",
      "sat_unit_desc": "Litro",
      "unit_price": 20.325,
      "sat_product_service_key": "15101515",
      "sat_product_service_desc": "Gasolina premium mayor o igual a 91 octanos",
      "sat_tax_object_key": "02",
      "sat_tax_object_desc": "Sí objeto de impuesto",
      "taxes": [
        {
          "type": "Traslado",
          "tax": "002",
          "factor": "Tasa",
          "rate": "0.160000",
          "taxable_base": 112.0,
          "amount": 17.92
        }
      ]
    }
  ]
}

Errores comunes y qué hacer

  • 400 Bad Request: validación (campos faltantes, tipos, firma inválida, expires_at en el pasado)
  • 401 Unauthorized: X-API-Key inválida o ausente
  • 404 Not Found: token no encontrado (revocado o purgado)
  • 409 Conflict: token ya consumido (si la política es de un solo uso)
  • 410 Gone: QR expirado
  • 422 Unprocessable Entity: error de negocio (ej. issuer_rfc no configurado)

Guía recomendada: Manejo de errores


Checklist para pasar a Producción

Antes de mover tu integración a https://clients.qrwey.com, valida lo siguiente:

  • API Key de producción configurada y almacenada en backend (no frontend)
  • Generas un UUID por operación y reusas la misma Idempotency-Key en reintentos
  • Manejas explícitamente:
    • 409 Conflict (token consumido)
    • 410 Gone (QR expirado)
    • 422 Unprocessable Entity (reglas de negocio / configuración)
  • expires_at definido según tu operación (ventana realista: 5–30 minutos típicamente)
  • No confías en datos del QR sin resolverlos vía API (validación server-side)
  • Logs con code y message para depuración y soporte

¿Qué sigue?

Ahora que tienes un flujo básico funcionando: