Requisitos de calidad para la revisión de apps
Stripe revisa todas las apps que se envían al marketplace conforme a un conjunto exhaustivo de requisitos de calidad. Conocer estos estándares antes de empezar a desarrollar te ahorra tiempo y reduce el número de iteraciones de revisión.
Resumen
La revisión de una Stripe App evalúa tu app en seis áreas clave:
- Precios transparentes, comunicación clara de los costes
- Funcionalidad de la app, fiabilidad y grado de acabado
- Estándares de desarrollo, calidad del código y uso de la API
- Calidad de la UX, estándares de interfaz y de experiencia
- Seguridad, protección de datos y prácticas seguras
- Cumplimiento legal, privacidad y requisitos normativos
Precios transparentes
Tu app debe comunicar con claridad todos los costes:
- Divulgación de precios: todos los precios deben indicarse por adelantado en la ficha del marketplace
- Sin cargos ocultos: nadie debe encontrarse con cargos inesperados tras la instalación
- Condiciones de la prueba: si ofreces una prueba gratuita, indica con claridad su duración y qué pasa cuando termina
- Flujos de mejora de plan: cualquier mensaje de venta adicional o de mejora de plan debe ser discreto y claramente opcional
- Moneda: muestra los precios en la moneda local del usuario siempre que sea posible
Caution
Las apps que ocultan sus precios o cobran sin un consentimiento claro se rechazan de inmediato.
Formato de fechas y horas
Todas las fechas y horas que muestre tu app deben seguir las convenciones del panel de Stripe:
- Usa la configuración regional del usuario para dar formato a las fechas cuando esté disponible
- Muestra las horas en la zona horaria local del usuario
- Usa marcas de tiempo relativas para los eventos recientes (por ejemplo, “hace 2 horas”)
- Usa marcas de tiempo absolutas, con fecha y hora completas, para los eventos antiguos
- Sigue ISO 8601 en cualquier campo de fecha que llegue a la API
// Good: Use Stripe's date formatting utilitiesimport { formatDate, formatRelativeTime } from '@stripe/ui-extension-sdk/utils';
const formattedDate = formatDate(timestamp); // Locale-awareconst relativeTime = formatRelativeTime(timestamp); // "2 hours ago"Ajustes de la app
Si tu app necesita configurarse:
- Ofrece una vista de ajustes específica, accesible desde el viewport de la app
- Rellena de antemano unos valores por defecto razonables siempre que puedas
- Valida todo lo que introduzca el usuario y muestra mensajes de error claros
- Permite actualizar los ajustes sin reinstalar la app
- Conserva los ajustes entre sesiones con la Secret Store API de Stripe
Compatibilidad con sandbox
Tu app debe funcionar correctamente en el modo sandbox (de prueba) de Stripe:
- Compatibilidad con el modo de prueba: todas las funciones deben funcionar en modo de prueba
- Datos de prueba: usa datos de prueba realistas que demuestren lo que hace la app
- Nada de datos reales en sandbox: nunca expongas datos de producción en el modo de prueba
- Degradación elegante: si una función no está disponible en sandbox, muestra un mensaje claro que explique por qué
- Pon
sandbox_install_compatible: trueen tu manifiesto
{ "sandbox_install_compatible": true}Funcionalidad de la app
Fiabilidad
- La app no debe fallar ni bloquearse durante el uso normal
- Todas las funciones anunciadas deben funcionar tal como se describen
- Los errores de red deben gestionarse con elegancia y ofrecer opciones de reintento
- La app debe seguir respondiendo mientras se ejecutan operaciones en segundo plano
Grado de acabado
- Nada de contenido de relleno, funciones “próximamente” ni enlaces rotos
- Todos los elementos de la interfaz deben funcionar, sin botones muertos ni controles inactivos
- Los textos de ayuda y los enlaces a la documentación deben llevar a páginas válidas
- La desinstalación debe eliminar por completo todos los datos y webhooks de la app
Rendimiento
- La interfaz debe renderizarse en menos de 3 segundos con una conexión estándar
- Las sincronizaciones en segundo plano no deben bloquear la interfaz
- Los conjuntos de datos grandes deben usar paginación o carga diferida
- Reduce al mínimo las llamadas a la API para evitar los límites de frecuencia
Estándares de desarrollo
Uso de la API
- Usa la última versión estable de la API de Stripe
- Sigue las buenas prácticas de la API de Stripe en paginación, gestión de errores e idempotencia
- No superes los límites de frecuencia, implementa un retroceso exponencial para los reintentos
- Usa webhooks para las actualizaciones basadas en eventos en lugar de hacer sondeos
Calidad del código
- Sin errores ni advertencias de consola en las compilaciones de producción
- Elimina todos los registros de depuración antes de enviar la app
- Contempla todos los casos límite (estados vacíos, datos ausentes, fallos de red)
- Sigue los patrones de la biblioteca de componentes de Stripe para lograr una interfaz coherente
Versionado
- Usa versionado semántico (MAJOR.MINOR.PATCH)
- Documenta los cambios incompatibles en cada actualización de versión
- Mantén la compatibilidad con versiones anteriores siempre que puedas
Calidad de la UX
Publicidad
- Sin anuncios: tu app no debe mostrar publicidad de ningún tipo
- Sin promoción cruzada: no promociones otros productos o servicios dentro de la interfaz de la app
- Contenido de marca: muestra únicamente tu propia identidad de marca, no marcas de terceros (salvo socios de integración como Brevo)
Lenguaje y contenido
- Terminología coherente: usa la misma terminología en toda la app
- Tono profesional: acompasa el estilo de comunicación profesional y conciso del panel de Stripe
- Sin jerga: evita el vocabulario técnico que los comercios quizá no entiendan
- Corrección ortográfica: asegúrate de que todos los textos están libres de faltas de ortografía y gramática
- Solo en inglés: todo el texto visible para el usuario debe estar en inglés en las apps del marketplace
Diálogos de confirmación
Pide confirmación al usuario antes de las acciones destructivas o importantes:
// Good: Confirm before destructive actionsconst handleDisconnect = async () => { const confirmed = await showConfirmation({ title: 'Disconnect Brevo Integration', message: 'This will stop syncing customer data to Brevo. You can reconnect at any time.', confirmLabel: 'Disconnect', cancelLabel: 'Cancel', destructive: true, });
if (confirmed) { await disconnectIntegration(); }};Acciones que requieren confirmación:
- Desconectar integraciones
- Eliminar datos sincronizados
- Cambiar ajustes que afectan al flujo de datos
- Restablecer la configuración a sus valores por defecto
Estados de carga
Muestra siempre indicadores de carga en las operaciones asíncronas:
// Good: Show loading state during data fetchconst CustomerSyncStatus = () => { const { data, isLoading, error } = useSyncStatus();
if (isLoading) { return <Spinner label="Loading sync status..." />; }
if (error) { return <Banner type="critical" title="Failed to load sync status"> {error.message} </Banner>; }
return <SyncStatusDisplay data={data} />;};Requisitos:
- Muestra indicadores de progreso o pantallas esqueleto mientras se cargan los datos
- Desactiva los botones mientras se envía un formulario
- Muestra indicadores de progreso en las operaciones largas
- Nunca muestres una pantalla en blanco durante la carga
Mensajes de error
Ofrece mensajes de error claros y accionables:
// Bad: Generic error"Something went wrong"
// Good: Specific and actionable"Unable to sync customer data to Brevo. Please verify your Brevo API keyin Settings and try again."Pautas para los mensajes de error:
- Explica qué ha pasado en lenguaje llano
- Sugiere una acción concreta que el usuario pueda tomar para resolverlo
- Ofrece una forma de reintentar la operación fallida
- Registra información detallada del error para depurar (sin mostrarla al usuario)
- Incluye códigos de error como referencia para el soporte cuando proceda
Seguridad
Secret Store API
Usa la Secret Store API de Stripe para almacenar todos los datos sensibles:
import { createHttpClient, STRIPE_API_KEY } from '@stripe/ui-extension-sdk/http_client';
// Good: Store secrets using the Secret Store APIconst storeBrevoApiKey = async (apiKey: string) => { const stripe = createHttpClient(STRIPE_API_KEY); await stripe.apps.secrets.create({ name: 'brevo_api_key', payload: apiKey, scope: { type: 'account' }, });};
// Good: Retrieve secrets from the Secret Storeconst getBrevoApiKey = async () => { const stripe = createHttpClient(STRIPE_API_KEY); const secret = await stripe.apps.secrets.find({ name: 'brevo_api_key', scope: { type: 'account' }, }); return secret.payload;};Nunca guardes datos sensibles en:
- El almacenamiento local o el almacenamiento de sesión
- Las cookies
- Los parámetros de la URL
- Valores fijos en el código fuente
- Archivos de configuración en texto plano
Criptografía
- Nada de criptografía propia: no implementes tus propios algoritmos de cifrado
- Usa las primitivas de seguridad integradas de Stripe (Secret Store, secretos de firma)
- Usa HTTPS en todas las llamadas a APIs externas
- Valida todas las firmas de webhook antes de procesarlas
Tratamiento de datos
- Solicita únicamente los permisos que tu app necesita de verdad
- No almacenes datos de Stripe más allá de lo necesario para que la app funcione
- Aplica políticas de retención de datos alineadas con tu política de privacidad
- Ofrece un mecanismo para que los usuarios soliciten la eliminación de sus datos
Cumplimiento legal
Política de privacidad
Tu app debe contar con una política de privacidad de acceso público que cubra:
- Qué datos recopila tu app desde Stripe
- Cómo se almacenan, procesan y comparten esos datos
- Las políticas de retención y eliminación de datos
- Los derechos de los usuarios sobre sus datos
- Los datos de contacto para consultas sobre privacidad
- El cumplimiento de la normativa aplicable (RGPD, CCPA, etc.)
Términos del servicio
- Ofrece unos términos del servicio claros para tu app
- No incluyas términos que entren en conflicto con los Términos del servicio de Stripe
- Indica con claridad cualquier límite o restricción de uso
Cumplimiento normativo
- Cumple toda la normativa de protección de datos que te aplique
- Firma los acuerdos de tratamiento de datos que correspondan
- Admite las solicitudes de portabilidad y de eliminación de datos
- Mantén registros de auditoría del acceso y el tratamiento de los datos
Plazos del proceso de revisión
| Etapa | Duración |
|---|---|
| Envío inicial | De 5 a 10 días laborables |
| Revisión de las correcciones | De 3 a 7 días laborables |
| Aprobación final | De 1 a 2 días laborables |
| Publicación | Inmediata tras la aprobación |
Tip
Resuelve todos los comentarios de la revisión en una sola corrección para evitar varios ciclos de revisión. El equipo de Stripe da comentarios concretos y accionables sobre cada problema que encuentra.
Motivos de rechazo más habituales
- Falta gestión de errores, la app falla ante errores de red o datos inesperados
- Estados de carga insuficientes, pantallas en blanco mientras se cargan los datos
- Precios poco claros, los precios no se detallan por completo en la ficha
- Permisos excesivos, se solicitan permisos que la app no necesita
- Modo sandbox roto, la app no funciona en modo de prueba
- Problemas de seguridad, se guardan secretos fuera de la Secret Store API
- Falta la política de privacidad, no hay una URL de política de privacidad accesible
- Funcionalidad incompleta, funciones “próximamente” o contenido de relleno