Referencia del manifiesto de la app
El archivo de manifiesto stripe-app.json es la configuración central de tu Stripe App. Declara la identidad de la app, sus permisos, sus vistas de interfaz, sus políticas de seguridad y su comportamiento tras la instalación.
Ejemplo de manifiesto completo
{ "id": "com.tajo.brevo-integration", "version": "1.2.0", "name": "Tajo for Brevo", "icon": "./assets/icon.png", "distribution_type": "public", "sandbox_install_compatible": true, "stripe_api_access_type": "oauth", "allowed_redirect_uris": [ "https://tajo.io/stripe/callback", "https://tajo.io/stripe/oauth/complete" ], "permissions": [ { "permission": "customer_read", "purpose": "Read customer profiles to sync with Brevo contacts" }, { "permission": "customer_write", "purpose": "Update customer metadata with Brevo sync status" }, { "permission": "charge_read", "purpose": "Access payment history for Brevo event tracking" }, { "permission": "product_read", "purpose": "Sync product catalog to Brevo for personalized campaigns" }, { "permission": "event_read", "purpose": "Subscribe to real-time events for Brevo automation triggers" }, { "permission": "invoice_read", "purpose": "Track invoice lifecycle events in Brevo" } ], "ui_extension": { "views": [ { "viewport": "stripe.dashboard.customer.detail", "component": "CustomerDetailView" }, { "viewport": "stripe.dashboard.customer.list", "component": "CustomerListView" }, { "viewport": "stripe.dashboard.home.overview", "component": "OverviewView" }, { "viewport": "stripe.dashboard.drawer.default", "component": "DrawerView" }, { "viewport": "stripe.dashboard.settings", "component": "SettingsView" }, { "viewport": "stripe.dashboard.onboarding", "component": "OnboardingView" } ], "content_security_policy": { "connect-src": [ "https://api.tajo.io", "https://api.brevo.com" ], "image-src": [ "https://cdn.tajo.io", "https://assets.brevo.com" ], "purpose": "Connect to Tajo API for data sync and Brevo API for contact management" } }, "post_install_action": { "type": "onboarding" }, "constants": { "API_BASE_URL": "https://api.tajo.io/v1", "SYNC_INTERVAL_SECONDS": "300" }}Referencia del esquema
Campos de nivel superior
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | string | Sí | Identificador único de la app en notación de dominio inverso (formato slug) |
version | string | Sí | Cadena de versión semántica (por ejemplo, "1.2.0") |
name | string | Sí | Nombre que se muestra en el marketplace (máximo 35 caracteres) |
icon | string | Sí | Ruta relativa al archivo de icono de la app (PNG o SVG de 300x300) |
distribution_type | string | Sí | "public" para el marketplace o "private" para uso interno |
sandbox_install_compatible | boolean | No | Indica si la app se puede instalar en modo sandbox o de prueba |
stripe_api_access_type | string | No | Método de acceso a la API: "oauth" o "api_key" |
allowed_redirect_uris | string[] | No | URIs de redirección de OAuth permitidas en el flujo de instalación |
permissions | PermissionRequest[] | Sí | Array de solicitudes de permisos |
ui_extension | UIExtensionManifest | No | Configuración de la extensión de interfaz |
post_install_action | PostInstallAction | No | Acción que se ejecuta después de instalar la app |
constants | object | No | Pares clave-valor accesibles en la app en tiempo de ejecución |
id
El identificador de la app es una cadena con formato slug, normalmente en notación de dominio inverso:
"id": "com.tajo.brevo-integration"- Debe ser único en todas las Stripe Apps
- Usa solo letras minúsculas, números, guiones y puntos
- No se puede cambiar una vez creada la app
- Determina la URL de la app en el marketplace
version
Sigue el versionado semántico:
"version": "1.2.0"- MAJOR: cambios incompatibles o incorporaciones importantes de funcionalidad
- MINOR: funciones nuevas, compatibles con versiones anteriores
- PATCH: correcciones de errores y mejoras menores
- Debe incrementarse en cada subida
distribution_type
Controla quién puede instalar tu app:
| Valor | Descripción |
|---|---|
"public" | Disponible para todos los usuarios en el Stripe App Marketplace |
"private" | Solo se puede instalar en tu propia cuenta de Stripe |
stripe_api_access_type
Determina cómo se autentica tu app con la API de Stripe:
| Valor | Descripción |
|---|---|
"oauth" | Usa el flujo de OAuth 2.0 para autenticarse (recomendado para apps públicas) |
"api_key" | Usa claves de API restringidas (adecuado para apps privadas) |
PermissionRequest
Cada solicitud de permiso declara un permiso concreto de la API de Stripe que tu app necesita:
{ "permission": "customer_read", "purpose": "Read customer profiles to sync with Brevo contacts"}| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
permission | string | Sí | Identificador del permiso (consulta la referencia de permisos) |
purpose | string | Sí | Explicación legible que justifica por qué se necesita este permiso |
Pautas para el campo purpose:
- Escribe explicaciones claras y concretas que el comercio pueda entender
- Explica para qué se usa el permiso, no solo qué concede
- Mantén las descripciones breves (una sola frase)
- Evita la jerga técnica
UIExtensionManifest
Configura los componentes de interfaz de tu app:
{ "ui_extension": { "views": [...], "content_security_policy": {...} }}| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
views | ViewManifest[] | Sí | Array de declaraciones de vistas |
content_security_policy | CSPRequest | No | Content Security Policy para los recursos externos |
ViewManifest
Cada vista asocia un componente de React a un viewport del Dashboard de Stripe:
{ "viewport": "stripe.dashboard.customer.detail", "component": "CustomerDetailView"}| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
viewport | string | Sí | Ubicación del Dashboard donde se renderiza esta vista (consulta la referencia de viewports) |
component | string | Sí | Nombre del componente de React que se renderiza (debe coincidir con el nombre del componente exportado) |
Una misma app puede declarar varias vistas para distintos viewports:
"views": [ { "viewport": "stripe.dashboard.customer.detail", "component": "CustomerDetailView" }, { "viewport": "stripe.dashboard.payment.detail", "component": "PaymentDetailView" }, { "viewport": "stripe.dashboard.home.overview", "component": "OverviewView" }]CSPRequest
La Content Security Policy controla a qué dominios externos puede conectarse tu app:
{ "content_security_policy": { "connect-src": [ "https://api.tajo.io", "https://api.brevo.com" ], "image-src": [ "https://cdn.tajo.io" ], "purpose": "Connect to Tajo API for data sync and load images from CDN" }}| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
connect-src | string[] | No | Dominios a los que la app puede hacer peticiones de red |
image-src | string[] | No | Dominios desde los que la app puede cargar imágenes |
purpose | string | Sí | Explicación de por qué son necesarias estas conexiones externas |
Caution
Incluye solo los dominios a los que tu app necesita conectarse de verdad. Un exceso de entradas en la CSP puede provocar una revisión más estricta.
PostInstallAction
Configura qué ocurre justo después de que alguien instale tu app:
{ "post_install_action": { "type": "onboarding" }}| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
type | string | Sí | Tipo de acción (ver más abajo) |
url | string | Condicional | URL para las acciones de tipo external |
Tipos de acción
| Tipo | Comportamiento |
|---|---|
"onboarding" | Abre la vista de onboarding de la app en el Dashboard |
"settings" | Abre la vista de ajustes de la app en el Dashboard |
"external" | Redirige a la persona usuaria a una URL externa (requiere el campo url) |
Ejemplos:
// Open onboarding flow{ "post_install_action": { "type": "onboarding" }}
// Open settings page{ "post_install_action": { "type": "settings" }}
// Redirect to external setup{ "post_install_action": { "type": "external", "url": "https://app.tajo.io/stripe/setup" }}Consulta la guía de acciones posteriores a la instalación para ver patrones de implementación detallados.
Constants
Define pares clave-valor estáticos accesibles en tiempo de ejecución dentro de tu app:
{ "constants": { "API_BASE_URL": "https://api.tajo.io/v1", "SYNC_INTERVAL_SECONDS": "300", "MAX_BATCH_SIZE": "100" }}- Todos los valores deben ser cadenas
- Las constantes se incrustan en la app en tiempo de compilación
- Usa constantes para la configuración que cambia entre entornos
- Nunca guardes secretos ni claves de API como constantes, usa la Secret Store API en su lugar
Accede a las constantes desde el código de tu app:
import { constants } from '@stripe/ui-extension-sdk/constants';
const apiUrl = constants.API_BASE_URL;Manifiesto ampliado para desarrollo
Durante el desarrollo local tienes campos adicionales disponibles:
{ "id": "com.tajo.brevo-integration", "version": "0.1.0", "name": "Tajo for Brevo (Dev)", "icon": "./assets/icon-dev.png", "distribution_type": "private", "sandbox_install_compatible": true, "dev": { "hot_reload": true, "port": 4242 }}La sección dev se elimina en las compilaciones de producción y al subir la app. Úsala solo para ajustes que te faciliten el desarrollo local.
Validación
Valida tu manifiesto antes de subirlo:
# Validate manifest syntax and schemastripe apps validate
# Check for common issuesstripe apps checkErrores de validación habituales:
| Error | Causa | Solución |
|---|---|---|
Invalid permission | Identificador de permiso desconocido | Consulta la referencia de permisos |
Invalid viewport | Identificador de viewport desconocido | Consulta la referencia de viewports |
Missing purpose | Permiso sin campo purpose | Añade una cadena purpose a cada permiso |
Invalid version | Cadena de versión que no sigue semver | Usa el formato MAJOR.MINOR.PATCH |
Icon not found | La ruta del icono no se resuelve | Comprueba que el archivo del icono existe en la ruta indicada |