Desarrolladores
Flujos de integración
Pago con QR

Pago con QR

El pago QR interbancario es el método más simple: generas el QR, lo muestras y esperas la confirmación en tiempo real por SSE.

1POST /qr/generatebackend2Mostrar la imagen del QR al clientebrowser3EventSource /qr/stream/:referencebrowser · sin keyconfirmed → pagadoexpired → regenerar QRinvalid → inválidoFallback sin SSE: polling GET /qr/status/:numero_referencia cada 5 s

Genera el QR (backend)

const qr = await wpay.generateQR({
  order_id: 'ORD-1042',
  name: 'Pedido #1042',
  description: 'Compra online',
  amount: 350.0,
  id_currency: 1,       // opcional, default 1 (BOB)
  moneda: 'BOB',        // moneda que muestra el QR (default BOB)
  metadata: { cart_id: 88 },
})

Respuesta:

{
  "reference": "WP-1784169095747-578AFA46",
  "qr": {
    "numero_referencia": 9509574123,
    "imagen": "iVBORw0KGgoAAAANSUhEUgAA...",
    "monto": 350.0,
    "moneda": "BOB",
    "estado": "00"
  }
}
  • qr.imagen es un PNG en base64 — muéstralo con <img src={"data:image/png;base64," + imagen} />.
  • El QR expira a los 10 minutos.
  • numero_referencia es el id del QR en la red bancaria (para el polling); reference es tu transacción WizPay (para el stream y el estado).

Escucha la confirmación en tiempo real (browser)

/qr/stream/:reference es un endpoint público (sin key) pensado para conectarse directo desde el navegador con EventSource:

const es = new EventSource(`https://api.wizpay.app/qr/stream/${reference}`)
 
es.addEventListener('confirmed', (e) => {
  es.close()
  location.href = `/payment/success?reference=${reference}`
})
 
es.addEventListener('expired', () => {
  es.close()
  showRegenerateButton()   // el QR venció — genera otro
})
 
es.addEventListener('invalid', () => {
  es.close()
  showError('El pago no pudo validarse')
})
 
// Mensajes sin nombre de evento: "connected" al abrir y "heartbeat" cada 30 s
es.onmessage = (e) => {
  const data = JSON.parse(e.data)
  // { type: 'connected' | 'heartbeat', ... }
}

El stream envía un heartbeat cada 30 segundos y se cierra solo a los 10 minutos.

Fallback: polling (por si SSE no está disponible)

const poll = setInterval(async () => {
  const st = await fetch(`https://api.wizpay.app/qr/status/${numeroReferencia}`).then(r => r.json())
  if (st.estado === 'PAGADO') {
    clearInterval(poll)
    location.href = `/payment/success?reference=${reference}`
  }
}, 5000)

También puedes consultar GET /status/:reference (el estado WizPay: PENDIENTEAPROBADO). La confirmación llega cuando la red bancaria notifica el pago a WizPay.

Confirma en tu backend

Como siempre, la fuente de verdad es el estado servidor a servidor o el webhook:

const st = await wpay.getStatus(reference)   // status: 'APROBADO'

Webhooks del flujo QR: payment.qr.success, payment.qr.failed, transaction.success.

Referencia de endpoints usados