# Generar código QR

En QRwey!, **generar un código QR** significa crear una **intención de autofactura**
asociada a una transacción específica.

Este QR representa una operación fiscal pendiente que:

- Tiene un monto definido
- Tiene una expiración
- Está firmada y protegida
- Puede convertirse en un CFDi timbrado cuando el usuario la confirma


## ¿Cuándo generar un QR?

Normalmente debes generar un QR cuando:

- Se completa una venta
- Se imprime un ticket
- El cliente solicita factura
- Deseas habilitar autofactura sin capturas manuales


Cada QR debe representar **una sola transacción**.

## Endpoint


```
POST /v1/qrs
```

**Host (DEV):**


```
https://api-dev.qrwey.com
```

**Host (PROD):**


```
https://api.qrwey.com
```

## Headers requeridos


```http
X-API-Key: TU_API_KEY
X-TIME-ZONE: TU_ZONA_HORARIA
idempotency-key: <uuid>
Content-Type: application/json
```

- `X-API-Key` autentica la solicitud
- `X-TIME-ZONE` para establecer tu fecha de emisión
- `idempotency-key` evita duplicados en reintentos


> ⚠️ Usa **el mismo idempotency-key** si reintentas la operación.


## Request body

El cuerpo de la solicitud describe completamente la transacción fiscal.

### Campos principales

| Campo | Descripción |
|  --- | --- |
| `store_uid` | Identificador del punto de venta |
| `sale_id` | Identificador de la venta, generado por el comercio |
| `operation` | Tipo de operación (ej. `INVOICE`) |
| `amount` | Total de la operación |
| `subtotal` | Subtotal antes de impuestos |
| `currency` | Moneda (ej. `MXN`) |
| `exchange_rate` | Tasa de cambio, necesario si `currency` es diferente a `MXN` |
| `sat_payment_method` | Método de pago SAT (`PUE` Pago en una sola exhibición, `PPD` Pago en parcialidades o diferido) |
| `sat_payment_form` | Forma de pago SAT (ej. `04` Tarjeta de crédito) |
| `expires_at` | Fecha / hora de expiración del QR |
| `type_of_receipt` | Tipo de comprobante SAT (ej. `I` Ingreso, `E` Egreso, `P` Pago) |
| `export_code` | Identifica si la factura ampara una operación de exportación (ej. `01` No aplica) |
| `metadata` | Objeto opcional con datos adicionales del comercio (clave-valor libre) |


### Detalle de conceptos (`operation_data`)

Cada elemento representa un concepto del CFDI:

| Campo | Descripción |
|  --- | --- |
| `sku` | Identificador interno del producto |
| `description` | Descripción del concepto |
| `quantity` | Cantidad |
| `unit_price` | Precio unitario |
| `discount` | Descuento aplicado |
| `amount` | Importe del concepto |
| `sat_unit_key` | Clave de unidad SAT (ej. `LTR` Litro) |
| `sat_product_service_key` | Clave producto / servicio SAT (ej. `15101515` Gasolina premium mayor o igual a 91 octanos) |
| `sat_tax_object_key` | Objeto de impuesto SAT (ej. `02` Sí objeto de impuesto) |
| `taxes` | Impuestos aplicables |


### Impuestos del concepto (`taxes`)

Cada elemento representa un impuesto del concepto:

| Campo | Descripción |
|  --- | --- |
| `type` | Tipo de impuesto SAT (`Traslado`, `Retencion`) |
| `tax` | Clave del impuesto SAT (ej. `002` IVA) |
| `factor` | Tipo de Factor SAT (`Tasa`, `Cuota`, `Exento`) |
| `rate` | La tasa o cuota del impuesto (ej. `0.160000`) |
| `taxable_base` | La base imponible sobre la cual se calcula el impuesto |
| `amount` | El monto del impuesto |


### Para Sustitución de facturas o Notas de Crédito (`related_cfdis`)

Elemento con un tipo de relación y un listado de CFDIs relacionados:

| Campo | Descripción |
|  --- | --- |
| `tipo_relacion` | Tipo de relación entre CFDI (ej. `04` Sustitución de los CFDI previos) |
| `cfdis` | Listado con los UUID de los CFDIs relacionados |


### Para facturas globales (`global_info`)

Elemento que contiene la información relacionada con
el comprobante global de operaciones con el público en
general:

| Campo | Descripción |
|  --- | --- |
| `periodicity` | Catálogo Periodicidad SAT (ej. `04` Mensual) |
| `months` | Catálogo Meses SAT (ej. `12` Diciembre) |
| `year` | Año a cuatro dígitos |


## Ejemplo de request (DEV)


```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


```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=...&m=...",
  "created_at": "2026-01-01T13:00:00Z",
  "expires_at": "2026-01-03T23:59:59Z"
}
```

### ¿Qué debes guardar?

- `qr_id`: identificador único de la transacción QR
- `qr_content`: **valor principal** para resolver el QR
- `expires_at`: control de vigencia
- `qr_url` o `qr_base64`: para mostrar o imprimir


## Errores comunes

| Código | Motivo |
|  --- | --- |
| 400 | Campos inválidos o faltantes |
| 401 | API Key inválida |
| 409 | Solicitud duplicada |
| 422 | Error de reglas de negocio |


Consulta: [Manejo de errores](/guides/error-handling)

## Buenas prácticas

- Genera el QR **una sola vez por venta**
- Define expiraciones realistas conforme a las reglas del negocio (ej. 5 días, hasta fin de mes, etc.)
- Maneja explícitamente errores `409` y verifica los estatus del token vía `GET /v1/qrs/{qrId}`


## ¿Qué sigue?

- Obtener detalle de un QR: [Obtener detalle de QR](/guides/resolve-qr)
- Entender estados: [Ciclo de vida del QR](/guides/qr-lifecycle)
- Detalle completo: [Referencia del API](/apis/qrwey)