# 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 el detalle de la transacción QR


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](https://apps.apple.com/mx/app/qrwey/id6752782250) o
para [Android](https://play.google.com/store/apps/details?id=com.petroverse.qrwey&pcampaignid=web_share)
- 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:


```http
X-API-Key: TU_API_KEY_MODO_DEV
idempotency-key: uuid-único
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://api.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://api.qrwey.com`
y no olvides cambiar TU_API_KEY productiva

## Paso 1: Generar un Código QR (POST /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 días o hasta fin de mes) para pruebas y operación.



```bash
curl -X POST "https://api-dev.qrwey.com/v1/qrs" \
  -H "X-API-Key: TU_API_KEY" \
  -H "X-TIME-ZONE: America/Mexico_City" \
  -H "idempotency-key: 550e8400-e29b-41d4-a716-446655440000" \
  -H "Content-Type: application/json" \
  -d '{
    "store_uid": "store_abc123",
    "sale_id": "fcd68791-6a27-412f-a50f-8d47b7bc34d2",
    "operation": "INVOICE",
    "amount": 133.00,
    "subtotal": 115.08,
    "currency": "MXN",
    "exchange_rate": 1.0,
    "sat_payment_method": "PUE",
    "sat_payment_form": "04",
    "expires_at": "2026-01-03T23:59:59Z",
    "type_of_receipt": "I",
    "export_code": "01",
    "related_cfdis": null,
    "global_info": null,
    "metadata": null,
    "operation_data": [
      {
        "sku": "GAS87",
        "description": "Gasolina Magna",
        "quantity": 5.662,
        "unit_price": 20.325,
        "discount": 0.00,
        "amount": 115.08,
        "sat_unit_key": "LTR",
        "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)


```json
{
  "qr_id": "tra_4aca0361cfcd41c097663db44008fbb9",
  "store_uid": "store_abc123",
  "sale_id": "fcd68791-6a27-412f-a50f-8d47b7bc34d2",
  "idempotency_key": "550e8400-e29b-41d4-a716-446655440000",
  "amount": 133.00,
  "subtotal": 115.08,
  "currency": "MXN",
  "exchange_rate": 1.0,
  "sat_payment_method": "PUE",
  "sat_payment_form": "04",
  "type_of_receipt": "I",
  "export_code": "01",
  "operation": "INVOICE",
  "status": "PENDING",
  "operation_data": [
    {
      "sku": "GAS87",
      "description": "Gasolina Magna",
      "quantity": 5.662,
      "unit_price": 20.325,
      "discount": 0.00,
      "amount": 115.08,
      "sat_unit_key": "LTR",
      "sat_unit_desc": "Litro",
      "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
        }
      ]
    }
  ],
  "metadata": null,
  "qr_base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...",
  "qr_url": "https://api-dev.qrwey.com/qr.png?...",
  "qr_content": "https://api-dev.qrwey.com/go?v=1&t=YWFh...&m=YmJi...",
  "created_at": "2026-01-01T13:00:00Z",
  "expires_at": "2026-01-03T23:59:59Z"
}
```

### ¿Qué debes guardar?

- Guarda `qr_id` como identificador de la transacción.
- 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! **convierte la intención de factura a 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: Consultar el detalle de la transacción QR (GET /v1/qrs/{qrId})

Opcionalmente, puedes consultar el detalle completo de la transacción usando el `qr_id`
que obtuviste al generar el QR.

### Request de ejemplo (DEV)


```bash
curl -X GET "https://api-dev.qrwey.com/v1/qrs/tra_4aca0361cfcd41c097663db44008fbb9" \
  -H "X-API-Key: TU_API_KEY"
```

### Respuesta esperada (200)


```json
{
  "qr_id": "tra_4aca0361cfcd41c097663db44008fbb9",
  "store_uid": "store_abc123",
  "store_name": "PetroStation #45",
  "sale_id": "fcd68791-6a27-412f-a50f-8d47b7bc34d2",
  "idempotency_key": "550e8400-e29b-41d4-a716-446655440000",
  "issuer_rfc": "EKU9003173C9",
  "issuer_name": "ESCUELA KEMPER URGATE",
  "amount": 133.00,
  "subtotal": 115.08,
  "currency": "MXN",
  "exchange_rate": 1.0,
  "sat_payment_form": "04",
  "sat_payment_form_desc": "Tarjeta de crédito",
  "sat_payment_method": "PUE",
  "sat_payment_method_desc": "Pago en una sola exhibición",
  "type_of_receipt": "I",
  "type_of_receipt_desc": "Ingreso",
  "export_code": "01",
  "export_code_desc": "No aplica",
  "operation": "INVOICE",
  "status": "PENDING",
  "operation_data": [
    {
      "sku": "GAS87",
      "description": "Gasolina Magna",
      "amount": 115.08,
      "quantity": 5.662,
      "discount": 0.00,
      "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
        }
      ]
    }
  ],
  "related_cfdis": null,
  "global_info": null,
  "metadata": null,
  "invoice": null,
  "customer": null,
  "qr_base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...",
  "qr_url": "https://api-dev.qrwey.com/qr.png?...",
  "qr_content": "https://api-dev.qrwey.com/go?v=1&t=YWFh...&m=YmJi...",
  "created_at": "2026-01-01T13:00:00Z",
  "updated_at": "2026-01-01T13:00:00Z",
  "scanned_at": null,
  "expires_at": "2026-01-03T23:59:59Z"
}
```

> Cuando el QR ya fue facturado, los campos `invoice` y `customer` contendrán los datos
de la factura generada y del cliente que se facturó.


Detalle completo: [Obtener detalle de QR](/guides/resolve-qr)

## Errores comunes y qué hacer

- **400 Bad Request**: validación (campos faltantes, tipos, `expires_at` en el pasado)
- **401 Unauthorized**: `X-API-Key` inválida o ausente
- **404 Not Found**: `qr_id` o `store_uid` no encontrado
- **409 Conflict**: `idempotency-key` duplicada con datos distintos
- **422 Unprocessable Entity**: error de negocio (tienda deshabilitada, CSD inválido, catálogo SAT incorrecto)


> Para verificar si un QR expiró, consulta `GET /v1/qrs/{qrId}` y revisa el campo `status: EXPIRED`.


Guía recomendada: [Manejo de errores](/guides/error-handling)

## Checklist para pasar a Producción

Antes de mover tu integración a `https://api.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` (idempotencia o duplicado)
  - [ ] `status: EXPIRED` vía `GET /v1/qrs/{qrId}` (QR expirado)
  - [ ] `422 Unprocessable Entity` (reglas de negocio / configuración)
- [ ] `expires_at` definido según tu operación (ventana realista según reglas del negocio)
- [ ] Logs con `request_id`, `idempotency-key` y timestamps para depuración y soporte


## ¿Qué sigue?

Ahora que tienes un flujo básico funcionando:

- Aprende a manejar errores → [Manejo de errores](/guides/error-handling)
- Controla reintentos → [Idempotencia](/guides/idempotency)
- Entiende expiración y seguridad → [Ciclo de vida del QR](/guides/qr-lifecycle)
- Consulta parámetros avanzados → [Referencia del API](/apis/qrwey)