Cobrar con QR en punto de venta (monto variable)
Con un QR estático de monto cerrado tenés un único QR impreso por caja y cobrás un monto distinto en cada venta. El monto no está en el QR: lo guarda PAGOS360. Antes de cada cobro, activás un monto con un tiempo de vigencia. Cuando el cliente escanea el QR con cualquier billetera o app bancaria, ve ese monto y lo paga.
En esta guía vas a ver el flujo completo: crear el QR de la caja una sola vez, activar un monto por venta, confirmar el pago y pasar a la venta siguiente.
todas las llamadas al módulo QR usan tu API Key (Authorization: Bearer <API Key>). Hacelas siempre desde tu servidor, nunca desde el navegador ni desde la app de la caja. Más información sobre el QR interoperable (el QR que se paga con cualquier billetera o app bancaria) en QR Interoperable.
Cómo funciona
Un QR por caja. Lo creás una vez y lo imprimís o lo mostrás en una pantalla. La imagen no cambia nunca.
Cada monto es un cobro nuevo. Cada vez que activás un monto se genera un cobro con su propio
qr_id. El QR impreso es el mismo.El monto vence. Cada monto tiene una vigencia en minutos. Cuando vence, activá otro monto para volver a cobrar.
Siempre vale el último monto. Si activás un monto nuevo, los próximos escaneos ven ese monto y ya no el anterior.
Los ejemplos usan el entorno de pruebas: https://qr.sandbox.pagos360.com. En producción, el host es https://qr.pagos360.com.
Paso 1: crear el QR de la caja
Hacelo una sola vez por caja o punto de venta, con POST /create-qr y qr_type: static_closed_amount. No lleva monto: el monto lo activás en cada venta.
Qué valida el módulo:
Campo | Regla |
|---|---|
| Obligatorio. Hasta 25 caracteres y tiene que empezar con el ID de tu cuenta seguido de un guion ( |
|
|
| Obligatorio en QR estáticos. Solo letras y números, de 1 a 15 caracteres. |
| Obligatorio, hasta 15 caracteres. Se guarda en mayúsculas. |
| Obligatorio, exactamente 8 caracteres. |
| Obligatorio, booleano. |
| Obligatorio, de 2 a 500 caracteres. |
| Obligatorio, hasta 255 caracteres. |
| Opcionales. |
Enviá solo los campos documentados, sin strings vacíos.
usá un qr_name distinto para cada caja. El contenido del QR estático se arma con el CUIT de la cuenta, el qr_name y la ciudad, pero no con el id. Si dos QR de la misma cuenta tienen el mismo qr_name y la misma ciudad, generan el mismo contenido y son el mismo QR.
Respuesta. Si el pedido es correcto, la respuesta es HTML (no JSON) con la imagen del QR en un <img>. Si enviás "add_template": true, devuelve la imagen dentro de una plantilla lista para imprimir.
Errores posibles:
HTTP | Cuerpo | Motivo |
|---|---|---|
400 |
| Algún campo no pasó la validación. |
400 |
| Ya existe un QR con ese |
200 |
| API Key inválida o ausente. |
Paso 2: obtener el contenido del QR
Para activar montos necesitás el string del QR: el contenido codificado en la imagen, en formato EMVCo (el estándar internacional de pagos con QR). Consultalo con GET /status/{qr_id} y guardalo junto a la caja. No cambia.
podés usar la imagen que devuelve create-qr o generar la tuya a partir del string con cualquier librería de códigos QR. El contenido es el mismo, así que la imagen impresa sirve para siempre.
Paso 3: activar el monto de cada venta
Cuando la caja tiene el total de la venta, tu servidor llama a PUT /new-transaction con el string del QR en el parámetro data (codificado para URL) y el monto en el cuerpo.
--url-query codifica el string por vos (curl 7.87 o posterior). Si usás otra herramienta, codificá el valor de data para URL: el string puede traer espacios u otros caracteres del nombre del comercio.
Campo | Tipo | Regla |
|---|---|---|
| Número | Obligatorio. Mínimo 10, hasta 2 decimales y hasta 8 dígitos enteros. Envialo como número, no como texto. |
| Número | Opcional. Minutos de vigencia del monto, de 1 a 90. Si no lo enviás, son 2 minutos. |
| String | Opcional, de 1 a 255 caracteres. Si no lo enviás, se usa la referencia del QR de la caja. |
Respuesta:
El qr_id que devuelve identifica este cobro, no la caja. Guardalo junto a la venta: lo vas a usar para consultar el estado.
Errores posibles:
HTTP | Cuerpo | Motivo |
|---|---|---|
400 |
| Falta |
404 |
| No existe un QR con ese string. |
409 |
| El QR no es |
401 |
| El QR es de otra cuenta. |
200 |
| API Key inválida o ausente. |
Más detalle en Generar nueva transacción.
Paso 4: el cliente escanea y paga
El cliente escanea el QR de la caja con cualquier billetera o app bancaria compatible con QR interoperable. La billetera le muestra el monto activo y el cliente confirma el pago. Este paso lo resuelven el cliente y su billetera: tu sistema espera la confirmación.
Qué ve el cliente según el momento en que escanea:
Situación | Resultado |
|---|---|
Hay un monto activo y no venció | La billetera muestra el monto y permite pagarlo. |
Todavía no activaste ningún monto | El QR no se puede pagar. |
El monto venció | El QR no se puede pagar hasta que actives otro. |
El último monto ya se pagó | El QR no se puede pagar hasta que actives otro. |
Paso 5: confirmar el pago
Tenés dos formas de enterarte. Usá las dos.
Webhook
Cuando se aprueba el pago, PAGOS360 registra una solicitud de pago pagada y envía el webhook paid de la entidad payment_request a la URL que configuraste. Ver Webhooks.
Enviá en cada new-transaction un external_reference único para la venta (por ejemplo, caja + número de ticket). El webhook trae ese external_reference, pero no el qr_id del cobro: con la referencia identificás qué venta se pagó.
Consulta de estado
Consultá el cobro con su qr_id (el que devolvió new-transaction, no el de la caja):
Estados posibles: Pending, Paid, Refunded y Deleted. paid_at trae solo la fecha (DD-MM-AAAA), sin hora. Si el qr_id no existe, la respuesta es [{"code": "F004", ...}]. Ver Consultar QR estático.
controlá el vencimiento desde tu sistema. El monto vence active_period minutos después de la llamada a new-transaction. No existe un estado "vencido": un cobro cuyo monto venció, o que fue reemplazado por un monto nuevo, sigue figurando como Pending.
Si consultás el estado periódicamente mientras la caja espera, hacelo cada pocos segundos. Cortá cuando pase el vencimiento (con un margen) o cuando llegue el webhook.
Paso 6: la venta siguiente
Para cobrar otra venta, volvé al paso 3 con el nuevo monto. El QR impreso es el mismo: cambia el cobro que tiene detrás.
Si activás un monto nuevo antes de que se pague el anterior, el nuevo lo reemplaza para los próximos escaneos. El cobro anterior no se cancela: queda en Pending en la consulta de estado. Conciliá siempre por external_reference o qr_id, sin asumir que el cobro pagado es el último: un cliente que escaneó el QR antes del reemplazo puede pagar el cobro anterior.
Si el cliente desiste y querés anular el monto activo antes de que venza, eliminá ese cobro con DELETE /delete-qr/{qr_id del cobro}. Podés eliminarlo mientras esté en Pending.
Si el cobro no está en Pending, la respuesta es [{"code": "F005", ...}]. Ver Eliminar QR.
Buenas prácticas
La API Key, solo en tu servidor. La caja o el navegador hablan con tu backend; tu backend habla con PAGOS360.
Creá el QR una vez por caja y guardá su
idy sustring. No crees un QR nuevo por venta.Una referencia única por venta. Enviá
external_referenceen cadanew-transactionpara cruzar el webhook con la venta.Ante un timeout, verificá antes de reintentar. La operación puede haberse completado igual. Si
create-qrda timeout, consultáGET /status/{id}antes de reintentar (un reintento con el mismoidresponde "ID must be unique."). Sinew-transactionda timeout y reintentás, el reintento genera otro cobro que reemplaza al anterior, y elqr_iddel primero se pierde. Ahí la referencia única te permite identificar la venta.El reloj que manda es el de PAGOS360. Un contador en la pantalla de la caja sirve de guía, pero la vigencia real la controla el módulo.
Limpieza. Los QR y los cobros no se borran solos. Eliminá los QR de prueba que ya no uses con
DELETE /delete-qr/{qr_id}(funciona con los que están enPending).
Probar en sandbox
Usá https://qr.sandbox.pagos360.com (el entorno de pruebas) con la API Key de tu cuenta de sandbox. Para simular el pago sin una billetera real, usá el endpoint Pagar QR (solo para homologación), disponible solo en sandbox.