QvaPay API
Mini-apps

Catálogo

Listar las mini-apps publicadas, saber cuáles están destacadas y leer una por su slug. Es la API que usa la app móvil de QvaPay.

La app móvil de QvaPay construye su pantalla de mini-apps con estos endpoints. Son los mismos que puede usar cualquier cliente que se identifique como app móvil: devuelven el catálogo publicado, ordenado con las destacadas primero, y en cada mini-app si el usuario de la sesión ya le dio acceso a su identidad.

Estas rutas solo responden a las apps móviles. Hay que enviar el header x-qvapay-client-platform: ios o android; sin él, la ruta responde 404 como si no existiera. Desde un navegador, Postman o curl sin ese header nunca verás el catálogo.

  • Mini-apps publicadas cuya App está activa y habilitada. Una mini-app suspendida, o cuya App fue desactivada, desaparece del catálogo al instante.
  • Además, para su dueño, las que tiene en borrador o en revisión. Vienen con preview: true para que la app las marque como «Vista previa». Nadie más las ve.

Destacadas

No hay un endpoint aparte para las destacadas: vienen dentro del mismo listado con featured: true, y el listado ya llega ordenado así:

  1. Destacadas primero (featured descendente).
  2. Dentro de cada grupo, por sort ascendente. Es un número que fija QvaPay; cuanto más bajo, más arriba.
  3. En empate, por nombre.

Para pintar la fila de tarjetas grandes basta con filtrar featured === true y respetar el orden recibido. Destacar una mini-app y su posición lo decide QvaPay (ver Publicar); el dueño no puede cambiarlo. Si la destacada tiene cover, esa imagen es el fondo de la tarjeta; si viene null, la tarjeta usa el color de su category.

GET /miniapps

Catálogo completo, con los consentimientos del usuario de la sesión.

Autenticación

Bearer Token (Authorization: Bearer <token> en headers) más el header de canal.

Request

curl -X GET "https://api.qvapay.com/miniapps" \
  -H "Authorization: Bearer <token>" \
  -H "x-qvapay-client-platform: android"

Sin parámetros. El catálogo es corto y se devuelve entero, sin paginación ni filtros: la categoría y las destacadas se filtran en el cliente.

Response (200)

{
  "data": [
    {
      "uuid": "6382792f-701c-4e49-b668-36d4e50eb9d6",
      "slug": "qvasuerte",
      "name": "QvaSuerte",
      "tagline": "Sorteo diario gratis: entra cada día y cobra al momento",
      "icon": "https://www.qvapay.com/miniapps/qvasuerte.svg",
      "cover": null,
      "entry_url": "https://www.qvapay.com/raffle",
      "allowed_origins": ["https://www.qvapay.com"],
      "category": "games",
      "featured": true,
      "scopes": ["profile"],
      "app_uuid": "a6e89aea-9b27-4dea-a484-a8cbcd0dd65c",
      "merchant": { "name": "QvaSuerte", "logo": null },
      "granted": true,
      "granted_scopes": ["profile"],
      "preview": false
    },
    {
      "uuid": "…",
      "slug": "arena-logica",
      "name": "Arena Lógica",
      "tagline": "Retos de lógica contra reloj.",
      "icon": "https://media.qvapay.com/miniapps/arena-logica/icon.png",
      "cover": "https://media.qvapay.com/miniapps/arena-logica/cover.png",
      "entry_url": "https://arena.example.com/app",
      "allowed_origins": ["https://arena.example.com"],
      "category": "games",
      "featured": false,
      "scopes": ["profile", "kyc"],
      "app_uuid": "…",
      "merchant": { "name": "Arena Studio", "logo": null },
      "granted": false,
      "granted_scopes": [],
      "preview": false
    }
  ]
}
CampoTipoDescripción
uuidstringIdentificador de la mini-app.
slugstringIdentificador público y estable. Es el que llevan la página compartible https://www.qvapay.com/apps/<slug> y las rutas de identidad y cobros.
namestringNombre que se muestra.
taglinestring | nullDescripción corta (hasta 140 caracteres).
iconstring | nullURL absoluta del icono cuadrado.
coverstring | nullURL absoluta de la portada 16:9. Solo se usa en la tarjeta de destacadas.
entry_urlstringURL https que la app abre en el WebView.
allowed_originsstring[]Orígenes donde el WebView expone el objeto window.QvaPay. En cualquier otro origen el SDK no existe.
categorystringUna de shopping, games, finance, services, social, tools, other.
featuredbooleantrue si QvaPay la destacó. Ver Destacadas.
scopesstring[]Permisos que la mini-app puede pedir al usuario: subconjunto de profile y kyc.
app_uuidstring | nullUUID de la App a la que pertenece.
merchantobjectname y logo de la App que cobra.
grantedbooleantrue si el usuario de la sesión ya autorizó a esta mini-app a leer su identidad y no lo ha revocado.
granted_scopesstring[]Permisos concedidos vigentes. Vacío si granted es false.
previewbooleantrue solo para el dueño cuando la mini-app aún no está publicada (borrador o en revisión).

Errores

CódigoMotivo
401Token inválido o sesión caducada.
404La petición no viene de una app móvil (falta x-qvapay-client-platform).
500Error al cargar el catálogo.

GET /miniapps/{slug}

Una sola mini-app, con la misma forma que cada elemento del listado. Sirve para abrir una mini-app desde un enlace compartido (https://www.qvapay.com/apps/<slug>) o desde una notificación sin cargar el catálogo entero.

Request

curl -X GET "https://api.qvapay.com/miniapps/qvasuerte" \
  -H "Authorization: Bearer <token>" \
  -H "x-qvapay-client-platform: ios"
ParámetroTipoRequeridoDescripción
slugstringSíSlug de la mini-app. No distingue mayúsculas.

Response (200)

{
  "data": {
    "uuid": "6382792f-701c-4e49-b668-36d4e50eb9d6",
    "slug": "qvasuerte",
    "name": "QvaSuerte",
    "featured": true,
    "granted": true,
    "preview": false,
    "…": "mismos campos que en el listado"
  }
}

Errores

CódigoMotivo
404 con code: "NOT_FOUND"No existe, no está publicada o su App está desactivada. Para el dueño también vale su borrador.
404 sin codeLa petición no viene de una app móvil.

Accesos del usuario

La pantalla Ajustes → Mini-apps de la app lista a qué mini-apps dio acceso el usuario y le deja revocarlo:

  • GET /miniapps/grants devuelve data: [{ slug, name, icon, scopes, created_at, updated_at }], la última autorizada primero. Solo accesos vigentes.
  • DELETE /miniapps/grants/{slug} revoca el acceso. Es idempotente: revocar algo ya revocado responde igual. Responde 404 solo si el slug no existe (una mini-app suspendida sí se puede revocar).

Al revocar, el siguiente GET /miniapps devuelve esa mini-app con granted: false; la mini-app tendrá que volver a pedir el login la próxima vez.

  • Saldo ni datos del usuario. La identidad viaja solo cuando el usuario acepta el login dentro de la mini-app, firmada, como explica Identidad.
  • Mini-apps suspendidas ni, para quien no es su dueño, borradores o en revisión.
  • Un catálogo público en la web. La página https://www.qvapay.com/apps/<slug> existe para compartir y para que Google la indexe, pero no expone entry_url, allowed_origins ni scopes: la mini-app solo se abre dentro de la app.