> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pay-me.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API de Autorización con QR

> Inicia pagos con QR usando el API de autorización de PayIn.

Usa este flujo para generar una operación QR desde el API de autorización de PayIn y entregar el QR en la misma respuesta para que el usuario complete el pago desde su app bancaria o billetera compatible.

<ParamField path="POST /charges" type="endpoint" />

<Note>
  Este flujo utiliza el mismo endpoint base de autorización. Revisa los ambientes y la configuración general en el [Overview](/payin/autorizacion).
</Note>

***

## Características del flujo

<CardGroup cols={2}>
  <Card title="Tipo de flujo" icon="clock">
    Asíncrono.
  </Card>

  <Card title="Método de pago" icon="qrcode">
    Permite generar un código QR para que el usuario complete el pago desde su app bancaria o billetera compatible.
  </Card>

  <Card title="Generación del QR" icon="image">
    El API devuelve la imagen del QR en base 64 dentro de `transaction.processor_response.qr_image`.
  </Card>

  <Card title="Validación final" icon="shield-check">
    El resultado final debe confirmarse por backend con notificación o consulta.
  </Card>
</CardGroup>

***

## Consideraciones

<Note>
  Este flujo permite enviar `callback_url` para recibir una notificación host to host cuando el estado de la operación cambie.
</Note>

<Note>
  QR no utiliza `redirect_url` ni retorno del navegador al comercio. El código QR se obtiene en la respuesta inicial del `POST /charges`.
</Note>

<Note>
  Aunque el QR se genera en la respuesta inicial, la confirmación final del pago sigue la misma lógica operativa de los métodos asíncronos. Complementa este flujo con [Notificaciones](/payin/notificaciones) o con [Consulta](/payin/consulta-qr).
</Note>

<Warning>
  No marques la orden como pagada solo porque el QR fue generado correctamente. Confirma siempre el estado final con [Notificaciones](/payin/notificaciones) o con [Consulta](/payin/consulta-qr).
</Warning>

***

## Request

<Note>
  Antes de consumir este endpoint, solicita tu `Access Token` en [Autenticación](/autenticacion#param-post-token).
</Note>

### Headers

| Campo | Descripción | Valor | Tipo | Obligatorio |
| :- | :- | :- | :- | :- |
| `Authorization` | Token Bearer obtenido desde autenticación | `Bearer {access_token}` | String | SI |
| `Content-Type` | Formato del request | `application/json` | String | SI |
| `ALG-API-VERSION` | Versión del API | `1709847567` | String | SI |

```bash theme={"system"}
Authorization: Bearer {access_token}
Content-Type: application/json
ALG-API-VERSION: 1709847567
```

***

### Body

#### Objeto raíz del request

| Campo | Descripción | Ejemplo | Tipo | Obligatorio |
| :- | :- | :- | :- | :- |
| `action` | Acción a ejecutar | `authorize` | String | SI |
| `channel` | Canal de la operación | `ecommerce` | String | SI |
| `merchant_code` | Código del comercio | `your_merchant_code` | String | SI |
| `merchant_operation_number` | Identificador único de la operación en el comercio. **Debe ser diferente en cada transacción.** | `5733813` | String | SI |
| `payment_method` | Objeto con la información del método de pago | Object | Object | SI |
| `payment_details` | Objeto con el detalle del pago y datos del cliente | Object | Object | SI |

***

#### Objeto `payment_method`

| Campo | Descripción | Ejemplo | Tipo | Obligatorio |
| :- | :- | :- | :- | :- |
| `method_name` | Nombre del método de pago | `QR` | String | SI |
| `method_details` | Objeto con la información específica del pago con QR | Object | Object | SI |

***

#### Objeto `payment_method.method_details`

| Campo | Descripción | Ejemplo | Tipo | Obligatorio |
| :- | :- | :- | :- | :- |
| `callback_url` | URL donde se realizará la notificación host to host (server to server) | `https://pay-me.com/callback` | String | NO |

<Note>
  Si envías `callback_url`, asegúrate de que sea una URL backend accesible para recibir confirmaciones server to server.
</Note>

***

#### Objeto `payment_details`

| Campo | Descripción | Ejemplo | Tipo | Obligatorio |
| :- | :- | :- | :- | :- |
| `amount` | Monto de la operación en centavos | `15000` | String | SI |
| `currency` | Código de la moneda | `604` | String | SI |
| `billing` | Datos de facturación | Object | Object | SI |
| `shipping` | Datos de envío | Object | Object | SI |
| `customer` | Datos del cliente | Object | Object | SI |
| `product_details` | Lista de productos asociados a la operación | `[]` | Array | SI |

<Note>
  Para `billing`, `shipping` y `customer`, usa la estructura ecommerce estándar con `first_name`, `last_name`, `email`, `phone` y `location`.
</Note>

***

### Ejemplo de request

```json theme={"system"}
{
  "action": "authorize",
  "channel": "ecommerce",
  "merchant_code": "your_merchant_code",
  "merchant_operation_number": "5733813",
  "payment_method": {
    "method_name": "QR",
    "method_details": {
      "callback_url": "https://pay-me.com/callback"
    }
  },
  "payment_details": {
    "amount": "15000",
    "currency": "604",
    "billing": {
      "first_name": "Pedro",
      "last_name": "Miranda",
      "email": "pedro@pay-me.com",
      "phone": {
        "country_code": "+51",
        "subscriber": "999835685"
      },
      "location": {
        "line_1": "Av. Casimiro Ulloa 333",
        "line_2": "Miraflores",
        "city": "Lima",
        "state": "Lima",
        "country": "Peru"
      }
    },
    "shipping": {
      "first_name": "Pedro",
      "last_name": "Miranda",
      "email": "pedro@pay-me.com",
      "phone": {
        "country_code": "+51",
        "subscriber": "999835685"
      },
      "location": {
        "line_1": "Av. Casimiro Ulloa 333",
        "line_2": "Miraflores",
        "city": "Lima",
        "state": "Lima",
        "country": "Peru"
      }
    },
    "customer": {
      "first_name": "Pedro",
      "last_name": "Miranda",
      "email": "pedro@pay-me.com",
      "phone": {
        "country_code": "+51",
        "subscriber": "999835685"
      },
      "location": {
        "line_1": "Av. Casimiro Ulloa 333",
        "line_2": "Miraflores",
        "city": "Lima",
        "state": "Lima",
        "country": "Peru"
      }
    },
    "product_details": []
  }
}
```

***

## Response

### Objeto `transaction`

| Campo | Descripción | Ejemplo | Tipo | Obligatorio |
| :- | :- | :- | :- | :- |
| `transaction_id` | Identificador único de la transacción | `5hk8rwa3h3cq9oyfs3a28v1ms` | String | SI |
| `channel` | Canal por el cual se realizó la transacción | `ecommerce` | String | SI |
| `state` | Estado actual de la transacción | `PENDIENTE` | String | SI |
| `state_reason` | Observación o descripción del estado actual | `QR generado exitosamente` | String | SI |
| `amount` | Monto de la transacción | `15000` | String | SI |
| `currency` | Código de la moneda de la operación | `604` | String | SI |
| `payment_method` | Objeto con información del método de pago usado en la transacción | Object | Object | SI |
| `expiration_date` | Fecha en la que expirará la transacción | Object | Object | NO |
| `processor_response` | Resultado devuelto por la procesadora con información del QR generado | Object | Object | NO |
| `additional_fields` | Datos adicionales enviados en el request | Object | Object | NO |
| `lifecycle` | Historial de estados por los que pasó la transacción | Array | Array | SI |

<Note>
  `state` puede devolver valores como `PENDIENTE` o `INVALIDO`. Cuando el QR fue generado correctamente, la transacción normalmente queda en `PENDIENTE` hasta que el pago sea completado o expire.
</Note>

<Warning>
  No uses `meta.status.code` como validador de autorización o denegación del pago. Ese código solo indica si el servicio procesó o respondió correctamente; el resultado del pago se valida con `transaction.state` y, como respaldo, desde backend con consulta o notificación.
</Warning>

***

### Objeto `transaction.payment_method`

| Campo | Descripción | Ejemplo | Tipo | Obligatorio |
| :- | :- | :- | :- | :- |
| `method_name` | Nombre del método de pago usado en la transacción | `QR` | String | SI |
| `method_details` | Objeto que contiene el detalle del método de pago usado en la transacción | Object | Object | NO |

***

### Objeto `transaction.payment_method.method_details`

| Campo | Descripción | Ejemplo | Tipo | Obligatorio |
| :- | :- | :- | :- | :- |
| `callback_url` | URL de callback enviada en el request | `https://pay-me.com/callback` | String | NO |

***

### Objeto `transaction.expiration_date`

| Campo | Descripción | Ejemplo | Tipo | Obligatorio |
| :- | :- | :- | :- | :- |
| `utc_time` | Fecha de expiración en UTC | `2024-03-12T22:49:36.018Z` | String | NO |
| `unix_time` | Fecha de expiración en unix time | `1711585037` | Integer | NO |

***

### Objeto `transaction.processor_response`

| Campo | Descripción | Ejemplo | Tipo | Obligatorio |
| :- | :- | :- | :- | :- |
| `date` | Fecha devuelta por la procesadora | `2024-03-26 19:17:19.599715` | String | NO |
| `qr_image` | Imagen del QR en base 64 | `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...` | String | NO |
| `qr_id` | ID del QR | `6d5d1ffc79234991b5592b825d6ec097` | String | NO |
| `result_message` | Mensaje del resultado de la autorización | Object | Object | NO |

***

### Objeto `transaction.processor_response.result_message`

| Campo | Descripción | Ejemplo | Tipo | Obligatorio |
| :- | :- | :- | :- | :- |
| `code` | Código del resultado de la autorización | `0` | String | NO |
| `description` | Descripción del resultado de la autorización | `Exito` | String | NO |

***

### Objeto `transaction.lifecycle`

| Campo | Descripción | Ejemplo | Tipo | Obligatorio |
| :- | :- | :- | :- | :- |
| `state` | Estado registrado en el historial | `PENDIENTE` | String | SI |
| `date` | Fecha del cambio de estado | Object | Object | SI |

<Note>
  En `lifecycle` puedes recibir estados como `REGISTRADO`, `PENDIENTE` e `INVALIDO`.
</Note>

***

### Objeto `transaction.lifecycle[].date`

| Campo | Descripción | Ejemplo | Tipo | Obligatorio |
| :- | :- | :- | :- | :- |
| `utc_time` | Fecha en UTC | `2024-03-12T22:49:36.018Z` | String | SI |
| `unix_time` | Fecha en unix time | `1710282940` | Integer | SI |

***

### Ejemplo de response

```json theme={"system"}
{
  "success": "true",
  "action": "authorize",
  "merchant_code": "your_merchant_code",
  "merchant_operation_number": "2391645",
  "transaction": {
    "transaction_id": "5hk8rwa3h3cq9oyfs3a28v1ms",
    "channel": "ecommerce",
    "state": "PENDIENTE",
    "state_reason": "QR generado exitosamente",
    "amount": "15000",
    "currency": "604",
    "payment_method": {
      "method_name": "QR",
      "method_details": {
        "callback_url": "https://pay-me.com/callback"
      }
    },
    "expiration_date": {
      "utc_time": "2024-03-12T22:49:36.018Z",
      "unix_time": 1711585037
    },
    "processor_response": {
      "date": "2024-03-26 19:17:19.599715",
      "qr_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
      "qr_id": "6d5d1ffc79234991b5592b825d6ec097",
      "result_message": {
        "code": "0",
        "description": "Exito"
      }
    },
    "additional_fields": null,
    "lifecycle": [
      {
        "state": "REGISTRADO",
        "date": {
          "utc_time": "2024-03-12T22:49:36.018Z",
          "unix_time": 1710282940
        }
      },
      {
        "state": "PENDIENTE",
        "date": {
          "utc_time": "2024-03-12T22:49:36.018Z",
          "unix_time": 1710282940
        }
      }
    ]
  },
  "meta": {
    "status": {
      "code": "00",
      "message_ilgn": [
        {
          "locale": "es_PE",
          "value": "Procesado correctamente"
        }
      ]
    }
  }
}
```

***

## Buenas prácticas

* Confirma el resultado final por backend antes de actualizar la orden.
* Asegúrate de enviar un `merchant_operation_number` único por transacción.
* No asumas que un QR generado significa pago completado; interpreta `PENDIENTE` como un estado intermedio.
* Usa `callback_url` si tu operación necesita confirmación server to server.
* Conserva `transaction_id`, `merchant_operation_number`, `qr_id` y la fecha de expiración para seguimiento, soporte y conciliación.

***

## Errores comunes

<CardGroup cols={2}>
  <Card title="Pago asumido como exitoso" icon="triangle-exclamation">
    Generar el QR no equivale a autorizar el pago. El usuario todavía debe escanearlo y completar la operación.
  </Card>

  <Card title="QR expirado" icon="ban">
    Si el usuario intenta pagar después de `expiration_date`, deberás generar una nueva operación en lugar de reutilizar la anterior.
  </Card>
</CardGroup>

***

## Siguiente paso

<Card title="Api de Consulta con QR" icon="arrow-right" href="/payin/consulta-qr">
  Aprende a consultar el estado actualizado de una operación QR.
</Card>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.