Una fila ordenada delante de tu venta. Tu checkout no cambia.
Virtual Queue pone a tus visitantes en una fila, les da una posición y los deja pasar al ritmo que tu sistema soporta. Con los conectores en el borde, el pico ni siquiera llega a tu servidor. Aquí está todo lo que necesitas para integrarlo, operarlo y decidir si te sirve.
Actualizado el 12 de octubre de 2026. Esta página reemplaza a «Tipos de integración», «Verificación de token», «Seguridad» y «Legacy».
Cómo funciona
Tu sitio soporta hasta cierto punto. Servidores, base de datos, pasarela de pago: alguno de los tres cede cuando entra más gente de la que soporta, y la venta se cae con él. Virtual Queue se pone delante de las páginas que eliges proteger y deja pasar la cantidad de personas por minuto que tú fijas. El resto espera en una fila donde cada uno ve su posición y cuánto le falta.
- Llega a tu sitioentradas.tusitio.comAbre una página protegida, por ejemplo la compra de un show.
- Se evalúa la reglaconectorLa URL coincide con una regla y la persona no tiene pase. Va a la fila.
- Sala de esperatusitio.virtual-queue.comAntes de la hora de venta ve una cuenta regresiva.
- Filatusitio.virtual-queue.comVe su posición y tiempo estimado; avanza en tiempo real.
- Vuelve con token/checkout?token=…El token se verifica una vez. Después compra como siempre.
Tu sitioVirtual Queue
Las cuatro piezas
- Sitio
- Tu dominio de venta, por ejemplo
entradas.tusitio.com. Lo creas una vez en el panel. Define el logo y el favicon de la fila y el subdominio de Virtual Queue que la sirve. - Fila
- Un evento de venta, con su fecha y hora de inicio, sala de espera, diseño, URL de compra y mensaje de cierre. Un sitio puede tener muchas.
- Regla de acceso
- Qué URLs de tu sitio pasan por la fila y cuáles no. Cada regla apunta a una fila.
- Token
- El UUID de cada persona en la fila. Vuelve a tu sitio en
?token=y se canjea una sola vez por un pase.
El panel de administración está en clients.virtual-queue.com. La fila se muestra en https://<tu-subdominio>.virtual-queue.com/queue/<id-de-fila> con tu logo, tus colores y tus textos.
Elegir la integración
Hay seis formas de conectar tu sitio. Comparten la fila, el panel y el token. Lo que cambia es dónde se decide mandar a alguien a la fila. Tres preguntas alcanzan para elegir:
Comparación
| Integración | Dónde decide | Qué necesitas | Protección | ¿Se puede saltear? |
|---|---|---|---|---|
| Conector de Cloudflare | Red de Cloudflare, antes de tu servidor | 3 registros DNS | Manual o automática | No |
| Worker en tu cuenta de Cloudflare | Tu cuenta de Cloudflare, antes de tu servidor | Un clic de despliegue, tu clave privada y una ruta | Solo manual | No |
| AWS CloudFront Beta | Tu distribución de CloudFront | Un clic en CloudFormation y 2 asociaciones en CloudFront | Solo manual | No |
| Adaptador JavaScript | Navegador del visitante | Una etiqueta <script> | Solo manual | Sí, salvo que tu backend verifique el pase |
| Conector en tu backend PHP, .NET, Node.js | Tu servidor | Instalar el conector y tu clave privada | Solo manual | No |
| Enlace directo + verificación | Tu servidor, en la página de compra | Un enlace a la fila y una llamada a la API | No usa reglas: la fila se abre cuando envías a la gente | No, si verificas el token |
Protección manual: tú activas la regla y, mientras esté activa, todos los que no tengan pase pasan por la fila. Protección automática: el conector mide el tráfico y activa la fila cuando supera el umbral que configuras, y la apaga cuando baja. La automática solo está en el conector de Cloudflare con CNAME.
Con un plan mensual que depende de cuántas personas hay en la fila a la vez. Cada plan incluye una cantidad de ingresos a la fila por mes, y el excedente se cobra aparte. No se cobra por fila. Los precios los vemos en una llamada: escribe a info@virtual-queue.com.
Conector de Cloudflare
Con CNAME es el único conector con los dos modos de protección. Tu subdominio de venta apunta por CNAME a la red de Cloudflare que opera Virtual Queue, y cada solicitud se evalúa ahí antes de llegar a tu servidor. Tu servidor sigue sirviendo el sitio. Lo único que cambia es por dónde entra el tráfico. Del certificado SSL nos ocupamos nosotros.
Protección manual
Tú decides cuándo empieza. Mientras la regla de la venta esté activa, cualquiera sin pase que pida una URL protegida pasa por la sala de espera y la fila. La regla se prende y se apaga desde el panel o la API.
Shows, drops, preventas, inscripciones.
Protección automática
Para sitios con picos que no avisan. El conector mide el tráfico, activa la fila cuando supera el umbral que configuras y la apaga cuando el tráfico baja y la fila se vacía.
E-commerce, portales con tráfico variable, trámites.
Instalación
-
Crea el sitio en el panel
En Sitios → Nuevo elige el modo de protección, manual o automática, y completa:
- URL del sitio: el subdominio de venta con
https://, sin ruta. Por ejemplohttps://entradas.tusitio.com. No se admite el dominio raíz (tusitio.com) y no se puede cambiar después. - Origen: la IP pública (IPv4) de tu servidor o el nombre DNS de tu balanceador. Ahí va el tráfico que el conector deja pasar.
- Logo (obligatorio), favicon e imagen de pie para la fila.
- Tiempo de espera del botón: minutos que tiene una persona para hacer clic en «Comprar» cuando le llega el turno. Por defecto, 10.
- URL del sitio: el subdominio de venta con
-
Agrega los dos registros de validación
El panel muestra los valores exactos. Créalos en tu proveedor DNS:
Tipo Nombre Para qué TXT_cf-custom-hostname.entradas.tusitio.comDemuestra que el dominio es tuyo. CNAME_acme-challenge.entradas.tusitio.comPermite emitir y renovar el certificado SSL. Si tu dominio ya está en Cloudflare, el panel te pide un
TXTen lugar delCNAMEde_acme-challenge. Ese valor puede cambiar al renovarse el certificado. -
Espera a que ambos estén «activos»
Tarda unos minutos, según la propagación de tu DNS. Mientras tanto el sitio queda bloqueado y no puedes crear filas.
-
Apunta tu subdominio a Virtual Queue
Tipo Nombre Valor CNAMEentradasEl destino que indica el panel, bajo virtual-queue.comA partir de aquí el tráfico pasa por el conector. Sin reglas activas, todo sigue directo a tu servidor.
Antes de apuntar el CNAME con protección automática: si tu sitio usa un parámetro
tokenpropio en alguna URL (por ejemplo, para restablecer contraseñas), el conector automático lo toma como un token de la fila y, al volver, quita los demás parámetros de esa URL. Cambia ese nombre de parámetro o escríbenos antes de activar. Con protección manual no hace falta: untokenque Virtual Queue no reconoce llega a tu servidor sin cambios. -
Crea la fila y las reglas de acceso
Configura la fila (sección 13) y luego las reglas que indican qué URLs se protegen (sección 07).
-
Prueba de punta a punta
Abre una URL protegida en una ventana normal. Tienes que llegar a la fila, y al salir tienes que volver a tu URL de compra con
?token=y quedarte en tu sitio.
El conector verifica el token cuando la persona vuelve y le entrega un pase al navegador. Tu backend no tiene que llamar a la API de verificación. Si la llama pasado el primer minuto, recibe un error, porque el token ya se usó.
Parámetros de la protección automática
Solo aplican si eliges el modo automático. Se ajustan por fila en el panel, en la tarjeta «Sensor automático». Basta con superar uno de los dos límites para que la fila se active. Para desactivarse, los dos tienen que estar por debajo y la fila tiene que tener menos personas que el límite mínimo.
| Campo en el panel | Unidad | Qué controla |
|---|---|---|
| Umbral de activación | ingresos por segundo | Ritmo de llegada a partir del cual se activa la fila. |
| Carga máxima del servidor | personas | Cuántas personas comprando a la vez soporta tu sitio. |
| Margen de tolerancia | 50–100 % | Porcentaje de la carga máxima en el que se activa la fila. Con 80 % y 1000 personas, se activa en 800. |
| Tiempo promedio de compra | minutos | Ventana usada para contar personas activas en tu sitio. |
| Límite mínimo para la fila | personas | La protección no se desactiva mientras la fila tenga al menos esta cantidad. |
Instalarlo en tu propia cuenta de Cloudflare
Si prefieres que la fila corra dentro de tu cuenta de Cloudflare en vez de apuntar un CNAME a la nuestra, hay un Worker autoinstalable. Ofrece solo protección manual. Tu dominio tiene que pasar por Cloudflare (nube naranja).
- Despliega el Worker
Un clic lo copia a tu cuenta de Cloudflare.
- Completa dos valores
CLIENTes el subdominio de tu sitio en Virtual Queue.PRIVATE_KEYes tu clave privada: está en la ficha del sitio, como «Secreto de firma». Si no la ves, pídela a support@virtual-queue.com. Cloudflare la guarda como secreto de tu cuenta. - Asócialo a tu dominio
El despliegue no pone el Worker delante de tu sitio. En el panel de Cloudflare, abre tu dominio, entra en Workers Routes y agrega una ruta, por ejemplo
entradas.tusitio.com/*, con el Workervqueue-connector. - Crea la fila y las reglas
Igual que en las demás integraciones (sección 07). Sin reglas activas, todo pasa directo.
- Solo redirige solicitudes
GETyHEAD; unPOSTde pago nunca se pierde. - Recursos estáticos, rutas
/api/y WebSockets pasan sin evaluarse. - Tus propios
?token=no se tocan: solo actúa sobre tokens de la fila. - Si no puede leer las reglas o la clave, deja pasar el tráfico. Tu sitio sigue funcionando.
- Para rotar la clave, vuelve a cargar el secreto
PRIVATE_KEY. - No mide tráfico: la fila se activa y se apaga con la regla, no por umbral.
Código y guía: connector-js, carpeta cloudflare-worker.
AWS CloudFront (Lambda@Edge)
Si tu sitio ya sale por CloudFront, la fila se aplica dentro de tu cuenta de AWS, sin tocar DNS. Son dos funciones Lambda@Edge que corren en cada solicitud de tu distribución. Ofrecen solo protección manual: mientras una regla esté activa, quien no tenga pase va a la fila. Si necesitas que la fila se active sola cuando sube el tráfico, usa el conector de Cloudflare con CNAME.
Las funciones leen tus reglas desde Virtual Queue, con caché de 30 segundos, y comprueban el pase de cada visitante con tu clave privada. No consultan a Virtual Queue en cada solicitud.
- Lanza el stack de CloudFormation
Un clic abre la consola de AWS en
us-east-1, la única región donde Lambda@Edge permite crear funciones, con todo precargado. - Completa dos valores
Clientes el subdominio de tu sitio en Virtual Queue.PrivateKeyes tu clave privada: está en la ficha del sitio, como «Secreto de firma». Si no la ves, pídela a support@virtual-queue.com. El stack crea las dos funciones, su rol y un secreto en AWS Secrets Manager (vqueue/connector) que guarda la clave en tu cuenta. La clave no viaja dentro de ningún zip. - Asocia las funciones a tu distribución
CloudFormation no puede hacer este paso. En CloudFront, edita el comportamiento que quieres proteger: Viewer request con la primera función y Viewer response con la segunda. Los ARN de las dos versiones están en la pestaña Outputs del stack.
- No agregues las cookies
vq_pass_*a la clave de cachéLas funciones las ven siempre. Si las incluyes, cada visitante (cada pase es distinto) fragmenta la caché de CloudFront y nada se sirve desde ella. Tu origen tampoco las necesita.
- Crea la fila y las reglas
Igual que en las demás integraciones (sección 07).
- Solo redirige solicitudes
GETyHEAD; unPOSTde pago nunca se pierde. - Recursos estáticos, rutas
/api/y WebSockets pasan sin evaluarse. - Tus propios
?token=(restablecer contraseña, enlaces mágicos) no se tocan: solo actúa sobre tokens de la fila. - Si no puede leer las reglas, la clave o la API, deja pasar el tráfico. Tu sitio sigue funcionando.
- El primer visitante de un contenedor nuevo puede esperar hasta unos 2,5 segundos. Si algo tarda más de 4, el conector deja pasar al visitante.
- No mide tráfico: la fila se activa y se apaga con la regla, no por umbral.
Sin CloudFormation, rotar la clave o borrar el stack
Instalar a mano. Descarga viewer-request.zip y viewer-response.zip. Salen sin configurar: leen la clave del secreto vqueue/connector de Secrets Manager en us-east-1, con el formato {"client": "…", "privateKey": "…"}, y el rol de las funciones necesita el permiso secretsmanager:GetSecretValue. Sin eso dejan pasar todo y lo registran en los logs. También puedes generarlos con tus valores desde el repositorio. Crea dos funciones Lambda en us-east-1 con runtime Node.js 22, sube un zip a cada una, publica una versión de cada una (Lambda@Edge no acepta $LATEST) y asócialas al comportamiento como en el paso 3. Si generas los zips con tu clave dentro, trátalos como material sensible.
Rotar la clave. Edita el secreto vqueue/connector. Las funciones lo toman en unos 5 minutos.
Borrar el stack. Primero quita las dos asociaciones del comportamiento y espera a que la distribución termine de desplegarse. Lambda@Edge no se puede borrar mientras CloudFront la use, y sus réplicas tardan en liberarse. Después borra el stack. El secreto queda programado para eliminarse y su nombre no se puede reutilizar durante ese período.
Adaptador JavaScript
Para cuando no controlas el DNS ni el servidor: tiendas alojadas, WordPress gestionado, sitios detrás de otra CDN. Agregas una etiqueta <script> y el navegador del visitante aplica las mismas reglas que los conectores.
<script src="https://cdn.virtual-queue.com/vq.js"
data-vq-client="tusitio"></script>
data-vq-client es el subdominio de tu sitio en Virtual Queue, el mismo de la URL de la fila. Carga el script sin async ni defer, para que empiece lo antes posible. Si no quieres que la página se vea un instante antes de redirigir, usa data-vq-hide="true".
El script se sirve desde https://cdn.virtual-queue.com/vq.js. La dirección anterior, https://tusitio.virtual-queue.com/adapter/vq.js, sigue respondiendo con el mismo archivo: las integraciones que ya la usan no necesitan cambios.
Qué hace en cada página
- Lee tus reglas de acceso (caché de 30 segundos en el navegador).
- Si la URL trae
?token=, lo verifica, guarda el pase en la cookievq_pass_<id-de-fila>, limpia la URL y devuelve al visitante a la página que había pedido. - Si la ruta coincide con una regla «Redirigir a la fila» y no hay pase, recuerda la página pedida y envía al visitante a la fila.
- En aplicaciones de una sola página (SPA) se vuelve a evaluar en cada cambio de ruta.
Opciones
| Atributo | Por defecto | Uso |
|---|---|---|
data-vq-client | obligatorio | Subdominio de tu sitio en Virtual Queue. |
data-vq-cookie-domain | solo el host actual | Usa .tusitio.com si las páginas protegidas y la URL de compra están en subdominios distintos. |
data-vq-target | la URL actual | URL fija a la que volver después de la fila. |
data-vq-hide | false | true oculta la página hasta decidir (máximo 3 segundos), para que no se vea un instante antes de redirigir. |
data-vq-spa | true | false desactiva la reevaluación en cambios de ruta. |
data-vq-debug | false | Muestra cada decisión en la consola. También con ?vqdebug en la URL. |
Con Google Tag Manager, usa window.vqConfig = { client: "tusitio" } o un evento de dataLayer con vqClient. Si quieres reaccionar a la decisión, define window.vqOnComplete = (resultado) => { … } antes del script. Recibe no_match, bypass, passed, redirecting, returning o error.
- Corre en el navegador. Alguien con JavaScript apagado, o que fabrique la cookie, se salta la fila. Para cerrar esa puerta, instala el conector de tu backend o comprueba el pase firmado antes de vender.
- Deja la URL de compra fuera de las reglas «Redirigir a la fila». Si no, un token rechazado manda al visitante otra vez a la fila.
- No lo instales en un dominio que ya usa el conector de Cloudflare o el de AWS. El visitante pasaría la fila y volvería a entrar.
- Si no consigue las reglas en 5 segundos, la página carga normal.
Tu backend: conector o enlace directo
Dos formas de proteger tu venta desde tu propio servidor. El conector aplica las reglas de acceso como el adaptador JavaScript, pero en el servidor: nadie lo saltea apagando JavaScript. El enlace directo no usa reglas y es la opción con menos piezas.
Conector en tu backend
Hay conector para PHP, .NET y Node.js. Necesita dos datos: el subdominio de tu sitio y tu clave privada, que va en una variable de entorno y nunca en el código. Solo ofrece protección manual.
PHP 8.1 o superior
use VQueue\Connector\Guard;
$guard = new Guard(
client: 'tusitio', // tu subdominio en Virtual Queue
privateKey: getenv('VQUEUE_PRIVATE_KEY'), // nunca en el código
);
$decision = $guard->decide([
'path' => parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH),
'query' => $_GET,
'cookies' => $_COOKIE,
'method' => $_SERVER['REQUEST_METHOD'],
]);
if ($decision['type'] === 'redirect') {
foreach ($decision['cookies'] ?? [] as $c) {
setcookie($c['name'], $c['value'], [
'expires' => time() + $c['maxAge'],
'path' => '/',
'httponly' => true,
'secure' => true,
'samesite' => 'Lax',
]);
}
header('Location: ' . $decision['location'], true, 302);
header('Cache-Control: no-store');
exit;
}
if (isset($decision['renew'])) {
$r = $decision['renew'];
setcookie($r['name'], $r['value'], [
'expires' => time() + $r['maxAge'], 'path' => '/',
'httponly' => true, 'secure' => true, 'samesite' => 'Lax',
]);
}ASP.NET Core
builder.Services.AddSingleton(new QueueGuard(new QueueGuardOptions
{
// tu subdominio en Virtual Queue
Client = "tusitio",
// nunca en el código
PrivateKey = builder.Configuration["VQueue:PrivateKey"]!,
}));
var app = builder.Build();
app.UseVQueue(); // antes de los endpoints que quieres protegerExpress, Fastify o http plano
import express from "express";
import { createQueueGuard } from "@vqueue/connector-node";
const app = express();
const guard = createQueueGuard({
client: "tusitio", // tu subdominio en Virtual Queue
privateKey: process.env.VQUEUE_PRIVATE_KEY, // nunca en el código
});
// Protege todo lo que coincida con una regla «Redirigir a la fila».
app.use(guard.express());
// Fastify: fastify.addHook("onRequest", guard.fastify());Todavía no están publicados en npm, Packagist ni NuGet: se instalan desde el código de cada repositorio, que trae la guía: PHP, .NET y Node.js.
- No evalúa recursos estáticos, rutas
/api/, WebSockets ni métodos distintos deGETyHEAD. - Al volver de la fila con
?vq_token=o?token=, intercambia el token, emite la cookievq_pass_<id-de-fila>y devuelve al visitante a su destino. Si el token no es de la fila, la solicitud sigue: tus propios?token=no se tocan. - Comprueba el pase sin llamar a Virtual Queue en cada solicitud, y lo renueva mientras el visitante navega.
- Si no puede leer las reglas o la API, deja pasar al visitante.
- En PHP, activa APCu. Sin APCu el conector guarda las reglas en un archivo temporal, que funciona pero es más lento.
Enlace directo + verificación del token
La opción con menos piezas. No hay reglas: mandas a tu público a la URL de la fila desde un botón, un mail o una publicación, y tu página de compra verifica el token antes de vender.
- Publica el enlace de la fila
Lo copias del panel. Tiene esta forma:
https://tusitio.virtual-queue.com/queue/<id-de-fila>. - Configura la URL de compra
En la fila, paso Checkout, campo «URL para compra». Es la ruta de tu página de compra, por ejemplo
/checkout/show-123, y se agrega a la URL del sitio. - Verifica el token en esa página
Con un SDK o una llamada a la API de verificación. Si responde bien, guarda tu propia sesión y deja comprar. Si no, muestra un mensaje con el enlace a la fila.
Cualquiera que conozca la URL de tu página de compra puede intentar entrar sin hacer fila. Lo único que lo frena es la verificación del token. Ponla en cada página desde la que se pueda comprar.
Reglas de acceso
Las reglas deciden qué rutas de tu sitio pasan por la fila. Se editan en el panel, en Reglas de acceso, y valen para todas las integraciones salvo el enlace directo: el conector de Cloudflare (por CNAME o en tu cuenta), AWS CloudFront, el adaptador JavaScript y los conectores de backend. Se comparan con la ruta de la URL, sin dominio ni parámetros.
| Campo | Valores | Detalle |
|---|---|---|
| Patrón URL | texto | Por ejemplo /eventos/show-123. |
| Tipo de patrón | Prefijo · Exacto · Contiene · Glob | Prefijo: la ruta empieza con el patrón. Exacto: es igual. Contiene: lo incluye. Glob: * equivale a cualquier texto. |
| Acción | Bypass · Redirigir a la fila | Bypass deja pasar. Redirigir envía a la fila indicada a quien no tenga pase. |
| Prioridad | 0, 1, 2… | Se recorren de menor a mayor número, como en un firewall: la regla 0 se evalúa primero y pisa a la 1. La primera que coincide decide. Si ninguna coincide, la solicitud pasa. |
| Activa | sí / no | En protección manual, activar la regla abre la protección de esa venta. |
Ejemplo: proteger una venta y dejar libre el resto
| Prioridad | Patrón | Tipo | Acción | Efecto |
|---|---|---|---|---|
| 0 | /eventos/show-123/checkout | Prefijo | Bypass | La página de compra nunca reenvía a la fila. |
| 1 | /eventos/show-123 | Prefijo | Redirigir a la fila | La venta del show pasa por la fila. |
| 2 | /eventos/*/entradas | Glob | Redirigir a la fila | Todas las páginas de entradas de cualquier evento. |
- En Glob usa un solo
*por tramo:/eventos/*/entradas. Los patrones con**no se aceptan. - Protege las páginas donde empieza la compra y deja libre la portada. La gente se informa sin hacer fila.
- Imágenes, hojas de estilo, scripts y rutas
/api/nunca se envían a la fila. - Un cambio de regla llega a los visitantes en alrededor de un minuto; con el adaptador JavaScript, AWS y los conectores de backend, hasta unos 90 segundos.
- Un patrón Glob no puede empezar con
*, y cada regla necesita una prioridad distinta. - Las reglas cubren la navegación: con AWS, el Worker en tu cuenta, los conectores de backend y la protección automática, las solicitudes que no son
GEToHEADy las rutas/api/pasan sin comprobar el pase. Si tu compra se confirma con unPOST, verifica el pase o el token en ese endpoint.
El regreso a tu sitio
Cuando a alguien le llega el turno ve «¡Ya es tu turno!» y un botón con el texto que configuraste. Al hacer clic, Virtual Queue lo manda a:
https://entradas.tusitio.com/checkout/show-123?token=76dcad75-257e-4134-a6bd-8fb7ba305fd4
Si tu URL de compra ya tiene parámetros, Virtual Queue los conserva y suma token. El conector por CNAME con protección automática los quita al verificar el token; los demás, incluido el CNAME con protección manual, los conservan. Desde ahí, cada integración verifica una sola vez:
| Integración | Quién verifica el token | Qué recibe el navegador | Qué hace tu backend |
|---|---|---|---|
| Conector de Cloudflare | El conector | Cookie de pase firmada, HttpOnly, válida 10 minutos | Nada |
| Worker en tu cuenta de Cloudflare | El Worker | Cookie vq_pass_<id-de-fila> (HttpOnly) | Opcional: comprobar el pase |
| AWS CloudFront | La función Lambda@Edge | Cookie vq_pass_<id-de-fila> (HttpOnly) | Opcional: comprobar el pase |
| Adaptador JavaScript | El script | Cookie vq_pass_<id-de-fila> | Recomendado: comprobar el pase |
| Conector en tu backend | El conector | Cookie vq_pass_<id-de-fila> | Nada |
| Enlace directo | Tu backend | Lo que tu sesión defina | Verificar el token |
El token se usa una vez. Durante el minuto siguiente a la primera verificación, repetirla devuelve el mismo pase (por si tu sistema reintenta); después, falla, aunque la primera la haya hecho otro componente. Por eso no combines un conector o el adaptador con una verificación del token en tu backend: usa el pase.
API de verificación
Confirma que un token pertenece a alguien que completó la fila y lo marca como usado. No pide credenciales. Se puede llamar desde un servidor o desde el navegador, con CORS abierto.
También responde en https://<tu-subdominio>.virtual-queue.com.
Respuesta exitosa · 200
{
"success": true,
"message": "Token succesfully verified",
"data": {
"token": "76dcad75-257e-4134-a6bd-8fb7ba305fd4",
"event_id": "1a732df6-6798-4c08-ba61-8b44a77c49f1",
"pass": "eyJ0Ijoi….Qm9zc2li…",
"pass_ttl": 3600,
"finished_line": {
"ingressed_at": "2026-05-26T16:20:18Z",
"finished_at": "2026-05-26T16:30:28Z"
}
}
}
- token
- El token verificado.
- event_id
- La fila a la que pertenece. Compara este valor con la fila que esperas. La API no lo hace por ti.
- pass
- Pase firmado con tu clave privada. Vale
pass_ttlsegundos, una hora. Detalle en la sección 10. Vienenullsi tu sitio no tiene clave privada. - ingressed_at
- Momento en que la persona entró a la sala de espera o a la fila (UTC).
- finished_at
- Momento en que le llegó el turno (UTC). Si la persona recargó la página dentro de su tiempo para comprar, es la hora de esa recarga.
Errores · 400
{ "success": false, "message": "Invalid queue ID", "error_code": "400" }
Es la misma respuesta para todos los casos, y es intencional. Cubre un token que no es UUID, que no existe, que se verificó hace más de un minuto, o cuya fila se eliminó o terminó hace más de una hora. Si falta el parámetro, el mensaje es Missing parameters. Required: token.
| Regla | Detalle |
|---|---|
| Un solo uso | La primera verificación exitosa quema el token. Durante 60 segundos, repetirla devuelve el mismo pase, para que un reintento de tu sistema no deje a nadie afuera. Después, falla. |
| Vigencia | Se puede verificar mientras la fila exista, hasta cerca de una hora después de finalizarla. |
| Una llamada por token | No llames una vez para «consultar» y otra para «confirmar». Pasado el primer minuto, la segunda falla. |
curl "https://app.virtual-queue.com/api/v1/queue/verify?token=76dcad75-257e-4134-a6bd-8fb7ba305fd4" \
-H "Accept: application/json"
Pase firmado
El pase prueba que una persona completó la fila, y está firmado con tu clave privada. Tu backend lo comprueba sin llamar a Virtual Queue y sin gastar el token. Lo recibes en data.pass de la verificación y, con el adaptador JavaScript, el Worker de tu cuenta de Cloudflare, el conector de AWS o los de backend, en la cookie vq_pass_<id-de-fila>.
| Parte | Contenido |
|---|---|
| Formato | base64url(json) + . + base64url(HMAC-SHA256(clave_privada, base64url(json))), sin relleno = |
| Clave | Tu clave privada tal cual, como texto (no la decodifiques) |
| Datos | t token · e id de fila · iat emisión · exp vencimiento (segundos Unix, exp = iat + 3600) |
Acéptalo solo si la firma coincide (compara en tiempo constante), e es tu fila y exp todavía no pasó.
import crypto from "node:crypto";
// Devuelve los datos del pase o null.
export function verifyPass(pass, privateKey, eventId) {
const [payload, sig] = (pass || "").split(".");
if (!payload || !sig) return null;
const expected = crypto.createHmac("sha256", privateKey).update(payload).digest("base64url");
if (sig.length !== expected.length ||
!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) return null;
const data = JSON.parse(Buffer.from(payload, "base64url").toString());
return data.e === eventId && data.exp > Date.now() / 1000 ? data : null;
}
// Uso: el pase llega en la cookie vq_pass_<id-de-fila>
const pass = req.cookies[`vq_pass_${EVENT_ID}`];
if (!verifyPass(pass, process.env.VQUEUE_PRIVATE_KEY, EVENT_ID)) {
return res.redirect(`https://tusitio.virtual-queue.com/queue/${EVENT_ID}`);
}function vq_verify_pass(?string $pass, string $privateKey, string $eventId): ?array
{
if (!$pass || substr_count($pass, '.') !== 1) return null;
[$payload, $sig] = explode('.', $pass, 2);
$raw = hash_hmac('sha256', $payload, $privateKey, true);
$expected = rtrim(strtr(base64_encode($raw), '+/', '-_'), '=');
if (!hash_equals($expected, $sig)) return null;
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
if (!is_array($data) || ($data['e'] ?? null) !== $eventId) return null;
return ($data['exp'] ?? 0) > time() ? $data : null;
}
// Uso
$pass = $_COOKIE['vq_pass_' . EVENT_ID] ?? null;
if (!vq_verify_pass($pass, getenv('VQUEUE_PRIVATE_KEY'), EVENT_ID)) {
header('Location: https://tusitio.virtual-queue.com/queue/' . EVENT_ID);
exit;
}import base64, hashlib, hmac, json, time
def _b64url(raw: bytes) -> str:
return base64.urlsafe_b64encode(raw).rstrip(b"=").decode()
def verify_pass(pass_value, private_key: str, event_id: str):
"""Devuelve los datos del pase o None."""
try:
payload, sig = pass_value.split(".", 1)
except (AttributeError, ValueError):
return None
expected = _b64url(hmac.new(private_key.encode(), payload.encode(), hashlib.sha256).digest())
if not hmac.compare_digest(expected, sig):
return None
data = json.loads(base64.urlsafe_b64decode(payload + "=" * (-len(payload) % 4)))
if data.get("e") != event_id or data.get("exp", 0) <= time.time():
return None
return dataCada sitio tiene una clave pública y una privada. Si tu sitio se instala en tu infraestructura, el panel las muestra en la ficha del sitio («Clave de API» y «Secreto de firma»); si no las ves, pídelas a support@virtual-queue.com. La privada va solo en tu backend, porque con ella se firman los pases y las llamadas a la API de gestión.
SDKs
Los SDKs llaman a la API de verificación por ti. Van en la página de compra cuando tu backend es el que verifica el token (enlace directo). Todos apuntan a https://app.virtual-queue.com por defecto.
composer require virtual-queue/token-verifier:dev-main · PHP 7.4 o superior
use VirtualQueue\TokenVerifier\TokenVerifier;
use VirtualQueue\TokenVerifier\Exception\ApiException;
use VirtualQueue\TokenVerifier\Exception\NetworkException;
use VirtualQueue\TokenVerifier\Exception\SdkException;
$verifier = new TokenVerifier(); // o new TokenVerifier($baseUrl, ['timeout' => 10])
try {
$data = $verifier->verifyToken($_GET['token'] ?? '');
// $data['event_id'], $data['finished_line']['finished_at'], $data['pass']…
} catch (ApiException $e) {
// Token inválido o ya usado (código 400)
} catch (NetworkException $e) {
// No se pudo contactar a Virtual Queue
} catch (SdkException $e) {
// Llegó sin token
}composer require virtual-queue/token-verifier-laravel · variables VIRTUAL_QUEUE_BASE_URL y VIRTUAL_QUEUE_TIMEOUT (opcionales)
use VirtualQueue\TokenVerifier\TokenVerifier;
class CheckoutController extends Controller
{
public function show(Request $request, TokenVerifier $verifier)
{
$result = $verifier->verifyToken((string) $request->query('token'));
if (!$result['success']) {
return redirect('https://tusitio.virtual-queue.com/queue/' . config('vqueue.event_id'));
}
session(['vq_verified' => true]);
return view('checkout');
}
}
// En Laravel, verifyToken() no lanza excepciones: devuelve ['success' => bool, 'data' | 'message' => …].
// También disponible como Facade: \TokenVerifier::verifyToken($token)npm i @vqueue/sdk
import { safeVerifyToken } from "@vqueue/sdk";
app.get("/checkout", async (req, res) => {
// safeVerifyToken nunca lanza: ante cualquier error devuelve { success: false, message }.
// verifyToken lanza VQueueInvalidUUID, VQueueNetworkError o VQueueError.
const result = await safeVerifyToken(String(req.query.token || ""));
if (!result.success) return res.redirect(QUEUE_URL);
req.session.vqVerified = true;
res.render("checkout");
});pip install vqueue-sdk
from vqueue import TokenVerifier
from vqueue.exceptions import VQueueApiError, VQueueNetworkError, VQueueError
verifier = TokenVerifier() # reutiliza la instancia; mantiene la conexión abierta
def checkout(request):
try:
result = verifier.verify_token(request.GET.get("token", ""))
except ValueError: # no es un UUID
return redirect(QUEUE_URL)
except VQueueApiError: # inválido o ya usado
return redirect(QUEUE_URL)
except (VQueueNetworkError, VQueueError):
return render(request, "reintentar.html")
...| SDK | Paquete | Métodos |
|---|---|---|
| PHP | virtual-queue/token-verifier | verifyToken() lanza excepción si falla · isTokenValid() devuelve bool · getFinishedLineDetails() |
| Laravel | virtual-queue/token-verifier-laravel | verifyToken() devuelve un array con success · isTokenValid() |
| Node.js | @vqueue/sdk | verifyToken() devuelve success: false si el token no vale; lanza solo ante un UUID inválido, un error de red o una respuesta inesperada · safeVerifyToken() nunca lanza |
| Python | vqueue-sdk | TokenVerifier.verify_token() lanza excepción si falla |
isTokenValid() y verifyToken() consumen el token. Usa uno solo: pasado el primer minuto, una segunda llamada falla. Instala el paquete de PHP o el de Laravel, no los dos, porque comparten namespace.
API de gestión
Casi todo lo que haces con tus filas en el panel se puede hacer desde tu backend: crear filas, iniciarlas y cerrarlas, cambiar el ritmo de salida, mandar mensajes, actualizar entradas disponibles, manejar reglas. Pensada para que tu ticketera opere la fila sin entrar al panel.
Autenticación
Cada solicitud lleva tres encabezados. Con la firma, nadie puede alterar una llamada, y una llamada capturada solo se puede repetir dentro de los 5 minutos de su marca de tiempo.
- X-API-Key
- Tu clave pública (empieza con
vq_). - X-Timestamp
- Hora actual en segundos Unix. Se acepta una diferencia de hasta 5 minutos.
- X-Signature
- HMAC-SHA256 en hexadecimal minúscula de
timestamp \n MÉTODO \n ruta?query \n cuerpo. La clave es tu clave privada decodificada de Base64.
import crypto from "node:crypto";
const base = "https://clients.virtual-queue.com";
const path = `/api/v1/headless/events/${eventId}/release`;
const body = JSON.stringify({ release_amount: 25 }); // 25 cada 15 s = 100 por minuto
const timestamp = String(Math.floor(Date.now() / 1000));
const secret = Buffer.from(process.env.VQUEUE_PRIVATE_KEY, "base64");
const signature = crypto.createHmac("sha256", secret)
.update([timestamp, "PATCH", path, body].join("\n"))
.digest("hex");
await fetch(base + path, {
method: "PATCH",
headers: {
"content-type": "application/json",
"x-api-key": process.env.VQUEUE_PUBLIC_KEY,
"x-timestamp": timestamp,
"x-signature": signature,
},
body, // exactamente los mismos bytes que firmaste
});
Operaciones
| Área | Método y ruta | Uso |
|---|---|---|
| Filas | GET /events · POST /eventsGET PATCH DELETE /events/{id} | Listar (paginado, filtro status=active|inactive), crear, leer, editar, eliminar. |
| Plantillas | POST /events/{id}/duplicate | Copiar una fila existente. |
| Ciclo de vida | POST /events/{id}/startPOST /events/{id}/finish | Iniciar. Finalizar con { title, message, redirect_people }. |
| Ritmo de salida | PATCH /events/{id}/releasePOST /events/{id}/releaser/pause · /resume | { release_amount } = personas cada 15 segundos. Pausar y reanudar. |
| Mensajes | PATCH /events/{id}/messagePATCH /events/{id}/messages/enable · /disable | Aviso en vivo a toda la fila: { title, body }. |
| Entradas | PATCH /events/{id}/ticketsPATCH /events/{id}/tickets/show · /hide | Mostrar en la fila cuántas entradas quedan. |
| Visibilidad | PATCH /events/{id}/visibility | show_people_in_line, show_left_time. |
| Protección | PATCH /events/{id}/protection | Parámetros de la protección automática. |
| Reglas | /acl-rules · POST /acl-rules/{id}/toggle | Crear, editar, borrar, activar y desactivar reglas. |
| Datos | GET /events/{id}/stats · /logs | Métricas y registro de la fila. |
Las respuestas tienen la forma { "success": true, "message": "…", "data": {…} }. Errores: 401 credenciales o firma inválidas, 404 la fila no existe o no es tuya, 422 datos inválidos. El contrato OpenAPI completo está en el panel, con sesión iniciada: clients.virtual-queue.com/api/docs/headless.
API anterior, con usuario y contraseña
Sigue disponible para las integraciones que ya la usan. Para una integración nueva, usa la API de arriba. Esta solo opera sobre filas activas.
curl -X POST "https://clients.virtual-queue.com/api/v1/users/login" \
-H "Content-Type: application/json" \
-d '{"username": "operaciones@tuticketera.com", "password": "…"}'
# → { "success": true, "message": "Auth ok", "data": { "token": "eyJhbGciOi…" } }
| Método y ruta | Cuerpo |
|---|---|
PATCH /api/v1/event/finish | event_id, title, message, redirect_people |
PATCH /api/v1/messenger/send_message | event_id, title, message |
PATCH /api/v1/messenger/enable · /disable | event_id |
PATCH /api/v1/event/tickets/update | event_id, tickets_name, available_tickets |
PATCH /api/v1/event/tickets/enable · /disable | event_id |
Encabezado Authorization: Bearer <token>. Una fila inexistente o inactiva devuelve 404; una fila de otro cliente, 403.
Configurar una fila
En el panel, Filas → Nueva. Son cuatro pasos y la vista previa se actualiza mientras completas los campos. En sitios con protección automática son dos (Fila virtual y Checkout): no hay sala de espera ni fin del evento.
-
Fila virtual
Título, subtítulo y descripción · idioma de la fila (español, inglés, portugués, francés, alemán, italiano o valenciano) · zona horaria y fecha y hora de inicio de la venta · imagen principal, logo, color de fondo, degradado opcional y color de acento. El botón «Sugerir colores desde la imagen» propone una paleta a partir de tu imagen.
También eliges qué ve la gente: el tiempo restante estimado, con un tope configurable del tipo «más de 120 minutos», la cantidad de personas en la fila y un iframe opcional con tu contenido.
-
Sala de espera
Abrir sala de espera: cuántos minutos antes de la venta se abre. Con 0 no hay sala.
Tipo de estrategia: Ordenado respeta el orden de llegada. Aleatorio sortea las posiciones entre todos los que estén en la sala cuando arranca la venta, así que llegar primero no da ventaja y un bot no gana nada por apurarse. En los dos casos, quien llega después del inicio queda detrás de toda la sala. La pantalla de espera le explica a la gente cuál de las dos aplica.
-
Checkout
Texto del botón de compra, por ejemplo «Comprar entradas», y URL para compra: la ruta de tu sitio a la que vuelve la persona con el token. Se agrega a la URL del sitio.
-
Fin del evento
Título y texto que verá la fila cuando cierres la venta, por ejemplo «Entradas agotadas».
Cada fila puede pedir una verificación anti-bots (Cloudflare Turnstile) antes de entrar. Viene activa y casi nadie la nota. Si necesitas apagarla, pídeselo a soporte.
Durante el evento
El tablero muestra en vivo cuánta gente hay en la fila, ingresos, presencia, filas completadas, clics en el botón de compra, conversión, abandono, espera máxima y bots bloqueados.
Ritmo de salida
«Control de salida de la fila» fija cuántas personas por minuto pasan a tu sitio. La salida va en tandas cada 15 segundos, por eso el valor se mueve de 4 en 4: 40 por minuto son 10 personas cada 15 segundos. Antes de cada tanda, Virtual Queue descarta a los que se desconectaron para que no ocupen lugar.
personas por minuto ≈ compras simultáneas que soporta tu sitio ÷ minutos que dura una compra
Si tu checkout soporta 600 compras a la vez y una compra lleva 5 minutos: 600 ÷ 5 = 120 por minuto. Arranca un 20 % por debajo y sube mientras tu sitio responda bien.
Pausar y reanudar
«Liberador automático» frena la salida sin cerrar la fila. Sirve cuando tu sitio necesita un momento para recuperarse.
Mensajes a la fila
«Enviar mensaje» muestra un aviso en vivo a toda la fila. Un cambio de horario, una fecha nueva, un recordatorio de qué documento tener a mano.
Entradas disponibles
Desde la API puedes mostrar «N entradas disponibles» e ir actualizando el número mientras vendes.
Seguimiento de una persona
En «Actividad» buscas por token y ves el recorrido completo: llegada, posición, salida y verificación. Es lo que vas a usar para responder un reclamo.
Cerrar la venta
| Opción en el panel | Qué pasa con quienes siguen esperando | Cuándo usarla |
|---|---|---|
| Finalizar evento y mostrar mensaje | Ven el título y el texto de fin del evento. Nadie más pasa a tu sitio. | Se agotó el stock. |
| Liberar usuarios y cerrar evento | Todos los que siguen esperando reciben el botón para ir a comprar (quienes estaban en la sala de espera, al recargar la página). | Queda stock y tu sitio puede recibir a todos. |
Después del cierre tienes el reporte de la fila, exportable en PDF, y un análisis generado con IA. Los tokens y las posiciones se borran alrededor de una hora después de finalizar. La fila y su reporte siguen en el panel.
Experiencia del visitante
Para cuando el público te escribe. La fila funciona en computadoras y teléfonos y se actualiza sola. Nadie tiene que recargar.
| Situación | Resultado |
|---|---|
| Llega antes de que abra la sala | Ve «La venta no ha comenzado aún». |
| Llega con la sala abierta | Ve la cuenta regresiva. Al iniciar la venta pasa a la fila con su posición. |
| Cierra la pestaña o se queda sin conexión | Conserva su lugar. Al volver con el mismo navegador sigue donde estaba. |
| Cambia de navegador o de dispositivo, o usa modo incógnito y lo cierra | Empieza de nuevo. El lugar vive en el navegador, y la fila lo avisa en pantalla. |
| Le llega el turno | Escucha un sonido y ve «¡Ya es tu turno!» con el botón de compra y los minutos que tiene para usarlo (por defecto 10). |
| Le llegó el turno mientras estaba ausente | Si vuelve dentro de su tiempo, ve el botón. Si no, ve un aviso y puede volver a la fila. |
| Usa el botón vencido o ya utilizado | Ve «Tu tiempo expiró» o un aviso de que el acceso ya se usó. |
| Abre muchas pestañas | En el mismo navegador conserva un único lugar. Cada navegador distinto cuenta como otra persona. |
El tiempo estimado sale de la posición y del ritmo de salida vigente, y se recalcula si cambias el ritmo. Al pie de la fila se aclara que completarla no asegura que queden entradas.
Checklist del evento
Puedes marcar los puntos aquí mismo. Quedan guardados en tu navegador.
Antes 48 h antes
Durante venta en curso
Al cerrar fin de la venta
Seguridad y garantías
Lo que puedes dar por hecho en una venta con Virtual Queue.
- Nadie se adelantaLa posición se asigna y se guarda en los servidores de Virtual Queue. El navegador solo muestra el número. Editarlo no cambia nada.
- Un enlace compartido no sirveCada token se canjea una vez. Si alguien comparte su URL de compra, pasado un minuto ya no le sirve a nadie.
- El pase no se puede falsificarLos pases van firmados y vencen. Con el conector por CNAME, además, quedan atados al navegador que completó la fila. Con los demás conectores, el pase sirve a quien tenga la cookie hasta que vence.
- La decisión ocurre antes de tu servidorCon el conector de Cloudflare y con AWS CloudFront, el control se aplica en la red antes de llegar a tu origen. No hay forma de saltearlo desde el navegador, siempre que tu servidor no acepte pedidos directos a su IP (ver Cerrar el acceso directo a tu origen). Las reglas cubren la navegación: si tu compra se confirma con un
POSTo bajo/api/, verifica también el pase en ese endpoint. - Bots filtradosHay verificación anti-bots antes de entrar. Y con la estrategia aleatoria, llegar primero con un script no da ventaja.
- Trazabilidad ante reclamosCada persona tiene un identificador único. Su recorrido (llegada, posición, salida, verificación) se consulta en el panel.
- Si el conector falla, tu sitio sigueEl conector por CNAME con protección manual, los de AWS, el Worker en tu cuenta de Cloudflare y los de backend dejan pasar el tráfico si no pueden leer tus reglas o hablar con Virtual Queue. Si la fila no responde mientras una regla está activa, las páginas protegidas no cargan; el resto de tu sitio sigue funcionando.
- Tus claves no salen de tu backendLa clave privada se usa solo en tu servidor, para comprobar pases y firmar llamadas. Una llamada firmada vence a los 5 minutos.
Cerrar el acceso directo a tu origen
Los conectores de Cloudflare y de AWS controlan el tráfico que entra por tu dominio. Si tu servidor acepta conexiones desde cualquier IP, alguien que la conozca puede pedirle la página directo, con el encabezado Host de tu sitio, y no pasa por la fila. Es el atajo que usaría un bot. Hay dos formas de cerrarlo:
- Firewall por rangos de IP. En los puertos 80 y 443 de tu servidor, permite solo los rangos de tu CDN. Cloudflare los publica en cloudflare.com/ips. En AWS, agrega al grupo de seguridad la lista de prefijos administrada
com.amazonaws.global.cloudfront.origin-facing. Con el conector por CNAME, esta es la opción: los pedidos llegan desde los rangos de Cloudflare. - Encabezado secreto. En CloudFront, agrega un encabezado personalizado al origen (Origin custom headers) con un valor que solo conozcas tú, y configura tu servidor para rechazar los pedidos que no lo traigan. Con el Worker en tu cuenta de Cloudflare, el encabezado se agrega con una regla de transformación de la solicitud.
Si tu backend comprueba el pase en las páginas de compra, el acceso directo no lo saltea: esas páginas piden el pase igual.
Nivel de control por integración
| Integración | Dónde se aplica | Para un control completo |
|---|---|---|
| Conector de Cloudflare | Red, antes de tu servidor | Cerrar el acceso directo a tu origen |
| Worker en tu cuenta de Cloudflare | Tu cuenta de Cloudflare, antes de tu servidor | Cerrar el acceso directo a tu origen |
| AWS CloudFront | Tu CDN, antes de tu servidor | Cerrar el acceso directo a tu origen |
| Conector en tu backend | Tu servidor | Nada más |
| Enlace directo | Tu servidor | Verificar el token en cada página de compra |
| Adaptador JavaScript | Navegador | Comprobar el pase en tu backend |
Probarnos sin apostar tu evento
Cambiar algo que ya funciona da miedo, y con razón. Virtual Queue tiene un año y medio de vida. Aquí está lo que pasó en ese tiempo y cómo puedes probarnos sin poner en juego tu venta más importante.
Eventos reales
| Evento | Qué pasó |
|---|---|
| Juegos Sudamericanos con MuchTicket | Una semana de filas, con 1.600.000 ingresos a las filas. Ni la fila ni la ticketera dejaron de funcionar. El pico fue de 4.434 personas a la vez. La protección frenó 27.946 intentos de bots. De quienes llegaron al botón de compra, el 93,4 % hizo clic. |
| Otra venta | La fila llegó a acumular 80.000 personas esperando a la vez. |
El 93,4 % es la proporción de clics sobre las veces que se mostró el botón de compra. No mide compras completadas.
Pruebas de carga
Casi 1.000.000 de personas simuladas con k6. No es un evento real. Cada fila está dimensionada para 500.000 personas conectadas a la vez, y tu contrato no fija un tope de personas.
Cómo probarnos sin riesgo
- Un evento, no una migración. Apuntas una sola venta y el resto de tu sitio no cambia. Sin permanencia.
- Se deshace en minutos. Con cualquier integración, desactivar las reglas en el panel deja pasar a todos en alrededor de un minuto. Con el conector por CNAME, además, revertir el registro DNS devuelve el tráfico directo a tu servidor.
- Si algo falla, tu sitio sigue en pie. Lo que no está protegido nunca depende de la fila. El conector por CNAME con protección manual y los que instalas en tu infraestructura dejan pasar el tráfico si no pueden leer las reglas.
- Pagas un plan por mes, no por cada fila. El plan depende del pico de personas a la vez. Los precios los vemos en una llamada.
- Alguien responde durante tu venta. Un grupo compartido el día del evento, una persona de guardia con nombre y respuesta en 15 minutos mientras dure la venta.
Cinco preguntas para cualquier proveedor
1. ¿Cuánto cuesta si creo muchas filas, o varias a la vez?
Un plan por mes según el pico de personas en la fila a la vez, no por cada fila. Crear más filas, o tener varias abiertas a la vez, no cambia el precio.
2. ¿Qué le pasa a mi sitio si la sala de espera falla?
Lo que no está protegido sigue funcionando. Si la fila no responde mientras una regla está activa, las páginas protegidas no cargan hasta que vuelva. El conector por CNAME con protección manual y los que instalas en tu infraestructura dejan pasar el tráfico si no pueden leer las reglas.
3. ¿Cuánto tardo en volver atrás?
Desactivar las reglas en el panel deja pasar a todos en alrededor de un minuto, con cualquier integración. Con el conector por CNAME, también puedes revertir el registro DNS.
4. ¿Quién me responde durante mi venta, y en cuánto tiempo?
Una persona de guardia, en un grupo compartido, en 15 minutos.
5. ¿Puedo ver cómo se verifica quién entra, antes de contratar?
Sí. Esta página muestra cada contrato, con ejemplos de código.
Somos jóvenes. Por eso todo está a la vista y puedes empezar con una sola venta.
Preguntas frecuentes
¿Cómo se cobra?
Con un plan mensual. El plan sale del pico de personas en la fila a la vez durante el mes, con 10 % de tolerancia. Cada plan incluye una cantidad de ingresos a la fila, y lo que la supere se cobra aparte. Crear más filas, o varias a la vez, no cambia el cobro. Los precios los vemos en una llamada: escribe a info@virtual-queue.com.
Mi backend recibe «Invalid queue ID». ¿Por qué?
El token se verificó hace más de un minuto, no existe o su fila se borró. Lo más común:
- Un conector o el adaptador ya lo verificó: usa el pase en lugar de volver a verificar.
- Tu código llama a
isTokenValid()y luego averifyToken(). - La persona recargó la página de compra y tu código verifica en cada carga. Guarda tu propia sesión después de la primera verificación.
- La fila finalizó hace más de una hora.
Después de pasar la fila, la persona vuelve a la fila.
Con el adaptador JavaScript, revisa que la URL de compra no caiga dentro de una regla «Redirigir a la fila». Si las páginas protegidas y la de compra están en subdominios distintos, configura data-vq-cookie-domain. Y no instales el adaptador en un dominio que ya usa un conector.
¿Puedo usar mi dominio raíz (tusitio.com)?
No. El panel pide la URL del sitio con un subdominio, porque el conector por CNAME lo necesita: la mayoría de los proveedores no permite CNAME en el dominio raíz. Usa un subdominio, como entradas.tusitio.com o tienda.tusitio.com.
La validación DNS no avanza.
Revisa que los nombres sean exactos. Algunos proveedores agregan tu dominio al final por su cuenta; ahí escribe solo _cf-custom-hostname.entradas. Si tu dominio está en Cloudflare, el registro de SSL es un TXT, no un CNAME. Y la propagación tarda lo que diga el TTL de tu DNS.
¿La fila se muestra con mi marca?
Sí. Tu logo, favicon, imagen, colores y textos, en el idioma que elijas. La dirección es tusitio.virtual-queue.com.
¿Cuánto tarda en aplicarse un cambio de regla?
Alrededor de un minuto con el conector por CNAME. Con el adaptador JavaScript, AWS y los conectores de backend, hasta unos 90 segundos, por la caché de las reglas.
¿Qué pasa con un POST de pago si la fila se activa en medio de una compra?
Quien ya pasó la fila conserva su pase. Para no cortarle la compra a nadie, deja la página de compra y las rutas que reciben el pago en una regla «Bypass». AWS, el Worker en tu cuenta, los conectores de backend y la protección automática solo redirigen GET y HEAD; el conector por CNAME en modo manual redirige también los POST.
¿Puedo probar antes del evento real?
Sí. Crea una fila de prueba con fecha cercana y una regla sobre una ruta de prueba, por ejemplo /prueba-fila. Recórrela entera y bórrala después.
¿Hay aviso por email cuando se acerca el turno?
No. La persona tiene que dejar la página abierta o volver con el mismo navegador. Cuando le llega el turno escucha un sonido y tiene el tiempo configurado para hacer clic.
Glosario
- Sitio
- Tu dominio de venta registrado en el panel, con su subdominio de Virtual Queue y sus claves.
- Fila
- Un evento de venta. En la API se llama
event. - Sala de espera
- Etapa previa al inicio de la venta, con cuenta regresiva.
- Ritmo de salida
- Personas por minuto que pasan a tu sitio; se libera en tandas cada 15 segundos.
- Regla de acceso
- Patrón de URL con acción «Bypass» o «Redirigir a la fila». En la API,
acl-rules. - Conector
- Componente que evalúa las reglas de acceso: el de Cloudflare (con CNAME o instalado en tu cuenta) o el de AWS CloudFront, antes de tu servidor, o el de tu backend (PHP, .NET, Node.js).
- Token
- UUID de cada persona en la fila. Vuelve en
?token=y se canjea una vez por un pase. - Pase
- Prueba firmada de que la persona completó la fila. La cookie dura 10 minutos desde la última página protegida que visitas, con un tope de 1 hora; con el conector por CNAME en modo manual, son 10 minutos fijos.
- Clave pública / privada
- Credenciales del sitio. La pública identifica; la privada firma y nunca sale de tu backend.
- Tiempo de espera del botón
- Minutos que tiene una persona para hacer clic en comprar cuando le llega el turno.
Credenciales, el conector de AWS, pruebas de carga, dudas de integración: support@virtual-queue.com. Manda el subdominio de tu sitio y, si viene al caso, el id de la fila o el token.