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.
Qué sale en 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: truepara 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í:
- Destacadas primero (
featureddescendente). - Dentro de cada grupo, por
sortascendente. Es un número que fija QvaPay; cuanto más bajo, más arriba. - 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
}
]
}| Campo | Tipo | Descripción |
|---|---|---|
uuid | string | Identificador de la mini-app. |
slug | string | Identificador 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. |
name | string | Nombre que se muestra. |
tagline | string | null | Descripción corta (hasta 140 caracteres). |
icon | string | null | URL absoluta del icono cuadrado. |
cover | string | null | URL absoluta de la portada 16:9. Solo se usa en la tarjeta de destacadas. |
entry_url | string | URL https que la app abre en el WebView. |
allowed_origins | string[] | Orígenes donde el WebView expone el objeto window.QvaPay. En cualquier otro origen el SDK no existe. |
category | string | Una de shopping, games, finance, services, social, tools, other. |
featured | boolean | true si QvaPay la destacó. Ver Destacadas. |
scopes | string[] | Permisos que la mini-app puede pedir al usuario: subconjunto de profile y kyc. |
app_uuid | string | null | UUID de la App a la que pertenece. |
merchant | object | name y logo de la App que cobra. |
granted | boolean | true si el usuario de la sesión ya autorizó a esta mini-app a leer su identidad y no lo ha revocado. |
granted_scopes | string[] | Permisos concedidos vigentes. Vacío si granted es false. |
preview | boolean | true solo para el dueño cuando la mini-app aún no está publicada (borrador o en revisión). |
Errores
| Código | Motivo |
|---|---|
401 | Token inválido o sesión caducada. |
404 | La petición no viene de una app móvil (falta x-qvapay-client-platform). |
500 | Error 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ámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
slug | string | Sí | 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ódigo | Motivo |
|---|---|
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 code | La 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/grantsdevuelvedata: [{ 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. Responde404solo 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.
Lo que NO devuelve el catálogo
- 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 exponeentry_url,allowed_originsniscopes: la mini-app solo se abre dentro de la app.