Skip to main content
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.
POST /charges
endpoint
Este flujo utiliza el mismo endpoint base de autorización. Revisa los ambientes y la configuración general en el Overview.

Características del flujo

Tipo de flujo

Asíncrono.

Método de pago

Permite generar un código QR para que el usuario complete el pago desde su app bancaria o billetera compatible.

Generación del QR

El API devuelve la imagen del QR en base 64 dentro de transaction.processor_response.qr_image.

Validación final

El resultado final debe confirmarse por backend con notificación o consulta.

Consideraciones

Este flujo permite enviar callback_url para recibir una notificación host to host cuando el estado de la operación cambie.
QR no utiliza redirect_url ni retorno del navegador al comercio. El código QR se obtiene en la respuesta inicial del POST /charges.
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 o con Consulta.
No marques la orden como pagada solo porque el QR fue generado correctamente. Confirma siempre el estado final con Notificaciones o con Consulta.

Request

Antes de consumir este endpoint, solicita tu Access Token en Autenticación.

Headers

CampoDescripciónValorTipoObligatorio
AuthorizationToken Bearer obtenido desde autenticaciónBearer {access_token}StringSI
Content-TypeFormato del requestapplication/jsonStringSI
ALG-API-VERSIONVersión del API1709847567StringSI
Authorization: Bearer {access_token}
Content-Type: application/json
ALG-API-VERSION: 1709847567

Body

Objeto raíz del request

CampoDescripciónEjemploTipoObligatorio
actionAcción a ejecutarauthorizeStringSI
channelCanal de la operaciónecommerceStringSI
merchant_codeCódigo del comercioyour_merchant_codeStringSI
merchant_operation_numberIdentificador único de la operación en el comercio. Debe ser diferente en cada transacción.5733813StringSI
payment_methodObjeto con la información del método de pagoObjectObjectSI
payment_detailsObjeto con el detalle del pago y datos del clienteObjectObjectSI

Objeto payment_method

CampoDescripciónEjemploTipoObligatorio
method_nameNombre del método de pagoQRStringSI
method_detailsObjeto con la información específica del pago con QRObjectObjectSI

Objeto payment_method.method_details

CampoDescripciónEjemploTipoObligatorio
callback_urlURL donde se realizará la notificación host to host (server to server)https://pay-me.com/callbackStringNO
Si envías callback_url, asegúrate de que sea una URL backend accesible para recibir confirmaciones server to server.

Objeto payment_details

CampoDescripciónEjemploTipoObligatorio
amountMonto de la operación en centavos15000StringSI
currencyCódigo de la moneda604StringSI
billingDatos de facturaciónObjectObjectSI
shippingDatos de envíoObjectObjectSI
customerDatos del clienteObjectObjectSI
product_detailsLista de productos asociados a la operación[]ArraySI
Para billing, shipping y customer, usa la estructura ecommerce estándar con first_name, last_name, email, phone y location.

Ejemplo de request

{
  "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

CampoDescripciónEjemploTipoObligatorio
transaction_idIdentificador único de la transacción5hk8rwa3h3cq9oyfs3a28v1msStringSI
channelCanal por el cual se realizó la transacciónecommerceStringSI
stateEstado actual de la transacciónPENDIENTEStringSI
state_reasonObservación o descripción del estado actualQR generado exitosamenteStringSI
amountMonto de la transacción15000StringSI
currencyCódigo de la moneda de la operación604StringSI
payment_methodObjeto con información del método de pago usado en la transacciónObjectObjectSI
expiration_dateFecha en la que expirará la transacciónObjectObjectNO
processor_responseResultado devuelto por la procesadora con información del QR generadoObjectObjectNO
additional_fieldsDatos adicionales enviados en el requestObjectObjectNO
lifecycleHistorial de estados por los que pasó la transacciónArrayArraySI
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.

Objeto transaction.payment_method

CampoDescripciónEjemploTipoObligatorio
method_nameNombre del método de pago usado en la transacciónQRStringSI
method_detailsObjeto que contiene el detalle del método de pago usado en la transacciónObjectObjectNO

Objeto transaction.payment_method.method_details

CampoDescripciónEjemploTipoObligatorio
callback_urlURL de callback enviada en el requesthttps://pay-me.com/callbackStringNO

Objeto transaction.expiration_date

CampoDescripciónEjemploTipoObligatorio
utc_timeFecha de expiración en UTC2024-03-12T22:49:36.018ZStringNO
unix_timeFecha de expiración en unix time1711585037IntegerNO

Objeto transaction.processor_response

CampoDescripciónEjemploTipoObligatorio
dateFecha devuelta por la procesadora2024-03-26 19:17:19.599715StringNO
qr_imageImagen del QR en base 64data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...StringNO
qr_idID del QR6d5d1ffc79234991b5592b825d6ec097StringNO
result_messageMensaje del resultado de la autorizaciónObjectObjectNO

Objeto transaction.processor_response.result_message

CampoDescripciónEjemploTipoObligatorio
codeCódigo del resultado de la autorización0StringNO
descriptionDescripción del resultado de la autorizaciónExitoStringNO

Objeto transaction.lifecycle

CampoDescripciónEjemploTipoObligatorio
stateEstado registrado en el historialPENDIENTEStringSI
dateFecha del cambio de estadoObjectObjectSI
En lifecycle puedes recibir estados como REGISTRADO, PENDIENTE e INVALIDO.

Objeto transaction.lifecycle[].date

CampoDescripciónEjemploTipoObligatorio
utc_timeFecha en UTC2024-03-12T22:49:36.018ZStringSI
unix_timeFecha en unix time1710282940IntegerSI

Ejemplo de response

{
  "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

Pago asumido como exitoso

Generar el QR no equivale a autorizar el pago. El usuario todavía debe escanearlo y completar la operación.

QR expirado

Si el usuario intenta pagar después de expiration_date, deberás generar una nueva operación en lugar de reutilizar la anterior.

Siguiente paso

Api de Consulta con QR

Aprende a consultar el estado actualizado de una operación QR.