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