QvaPay API
P2P

Feed del mercado (stream)

Los mismos eventos del P2P por SSE, sin montar un endpoint público.

La alternativa al webhook si tu integración ya es un proceso que corre de continuo: abres una conexión y lees. Sin servidor público, sin URL, sin verificar firmas.

Va incluido en la misma suscripción de $10 / 30 días, y puedes usar los dos canales a la vez.

Conectar

curl -N "https://api.qvapay.com/v2/p2p/stream" \
  -H "app-id: tu-app-id" \
  -H "app-secret: tu-app-secret"
retry: 10000
event: init
data: {"ok":true,"expires_at":"2026-10-20T18:00:00Z"}

event: p2p.created
data: {"event":"p2p.created","sent_at":"2026-09-20T18:00:01Z","data":{"uuid":"7c9e…","type":"sell","coin":"USDT","amount":"100.00","receive":"39500.00","status":"open"}}

: keepalive 1758391226000

Los eventos y el data son exactamente los mismos que en el webhook. Los comentarios : keepalive llegan cada 25 segundos para que ningún proxy dé la conexión por muerta; ignóralos.

const es = new EventSource(url)   // en Node, usa una librería que permita cabeceras
es.addEventListener('p2p.created', (e) => {
	const { data } = JSON.parse(e.data)
	console.log('nueva oferta', data.uuid, data.coin, data.amount)
})

Reconexión

Da por hecho que la conexión se corta cada pocos minutos. No es un fallo: las funciones donde corre el stream tienen un tiempo máximo de vida, así que se cierra y hay que volver a conectar. Por eso mandamos retry: 10000, que le dice al cliente que reintente a los 10 segundos.

Un EventSource de navegador reconecta solo. Si lo implementas tú, reconecta con backoff y no des por hecho que la conexión dura.

Mientras estás desconectado no se acumulan eventos: el stream es en vivo, no una cola. Si no puedes permitirte perder ninguno, usa el webhook — ese sí tiene cola y reintentos.

Cuándo se cierra

EventoQué significa
initConectado. Trae tu expires_at
subscription_expiredTu suscripción venció; la conexión se cierra a continuación
event: subscription_expired
data: {"reason":"expired","renew":"https://www.qvapay.com/dev"}

Errores

CódigocodeDescripción
401APP_AUTH_REQUIREDEl stream solo acepta app-id / app-secret
402FEED_SUBSCRIPTION_REQUIREDSin suscripción activa. La respuesta trae reason

¿Stream o webhook?

  • Stream si ya tienes un proceso corriendo. Es lo más simple: nada que exponer a internet, nada que firmar.
  • Webhook si no quieres mantener nada vivo, o si perder un evento te importa. Es el único con cola y reintentos.

Muchos integradores usan el stream para reaccionar rápido y el webhook como red de seguridad.