Requisitos de qualidade da revisão de apps
O Stripe revisa todo app enviado ao marketplace de acordo com um conjunto abrangente de requisitos de qualidade. Entender esses padrões antes do desenvolvimento economiza tempo e reduz o número de idas e vindas na revisão.
Visão geral
A revisão de um Stripe App avalia o seu app em seis áreas principais:
- Preços transparentes, comunicação clara dos custos
- Funcionamento do app, confiabilidade e integridade
- Padrões de desenvolvimento, qualidade do código e uso da API
- Qualidade de UX, padrões de interface e de experiência
- Segurança, proteção de dados e práticas seguras
- Conformidade legal, requisitos de privacidade e regulatórios
Preços transparentes
Seu app precisa comunicar com clareza todos os custos para os usuários:
- Divulgação de preços: todos os preços precisam ser informados de antemão na listagem do marketplace
- Sem taxas ocultas: os usuários não podem se deparar com cobranças inesperadas depois da instalação
- Condições do teste grátis: se você oferecer um teste, informe com clareza a duração e o que acontece quando ele termina
- Fluxos de upgrade: qualquer sugestão de upsell ou de upgrade precisa ser discreta e claramente opcional
- Moeda: exiba os preços na moeda local do usuário sempre que possível
Caution
Apps que escondem preços ou cobram dos usuários sem consentimento claro são rejeitados de imediato.
Formatação de data e hora
Todas as datas e horas exibidas no seu app precisam seguir as convenções do Stripe Dashboard:
- Use o idioma e a região do usuário para formatar datas quando essa informação estiver disponível
- Exiba os horários no fuso horário local do usuário
- Use marcações de tempo relativas para eventos recentes (por exemplo, “2 hours ago”)
- Use marcações de tempo absolutas para eventos antigos, com data e hora completas
- Siga o padrão ISO 8601 em qualquer campo de data exposto pela 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"Configurações do app
Se o seu app exigir configuração:
- Ofereça uma visão de configurações dedicada, acessível a partir do viewport do app
- Preencha valores padrão sensatos sempre que possível
- Valide todas as entradas do usuário com mensagens de erro claras
- Permita que os usuários atualizem as configurações sem reinstalar o app
- Mantenha as configurações entre sessões usando a API do Stripe Secret Store
Suporte a sandbox
Seu app precisa funcionar corretamente no modo sandbox (de teste) do Stripe:
- Compatibilidade com o modo de teste: todos os recursos precisam funcionar no modo de teste
- Dados de teste: use dados de teste realistas que demonstrem o funcionamento do app
- Sem dados reais no sandbox: nunca exponha dados de produção no modo de teste
- Tratamento elegante: se um recurso não estiver disponível no sandbox, exiba uma mensagem clara explicando o motivo
- Defina
sandbox_install_compatible: trueno seu manifesto
{ "sandbox_install_compatible": true}Funcionamento do app
Confiabilidade
- O app não pode travar nem congelar no uso normal
- Todos os recursos anunciados precisam funcionar como descrito
- Erros de rede precisam ser tratados com elegância, com opções de nova tentativa
- O app precisa continuar responsivo durante operações em segundo plano
Integridade
- Nada de conteúdo temporário, recursos “coming soon” ou links quebrados
- Todos os elementos da interface precisam funcionar, sem botões mortos nem controles inativos
- Os textos de ajuda e os links de documentação precisam levar a páginas válidas
- A desinstalação precisa remover por completo todos os dados e webhooks do app
Desempenho
- A interface precisa ser renderizada em até 3 segundos em uma conexão comum
- As operações de sincronização em segundo plano não podem bloquear a interface
- Conjuntos de dados grandes precisam usar paginação ou carregamento sob demanda
- Reduza ao mínimo as chamadas de API para evitar limites de taxa
Padrões de desenvolvimento
Uso da API
- Use a versão estável mais recente da API do Stripe
- Siga as boas práticas da API do Stripe para paginação, tratamento de erros e idempotência
- Não ultrapasse os limites de taxa, implemente backoff exponencial nas novas tentativas
- Use webhooks para atualizações orientadas a eventos em vez de polling
Qualidade do código
- Sem erros ou avisos de console nos builds de produção
- Remova todos os logs de depuração antes do envio
- Trate todos os casos de borda (estados vazios, dados ausentes, falhas de rede)
- Siga os padrões da biblioteca de componentes do Stripe para manter a interface consistente
Versionamento
- Use versionamento semântico (MAJOR.MINOR.PATCH)
- Documente as mudanças incompatíveis nas atualizações de versão
- Mantenha a compatibilidade com versões anteriores sempre que possível
Qualidade de UX
Publicidade
- Sem anúncios: seu app não pode exibir publicidade de nenhum tipo
- Sem promoção cruzada: não divulgue outros produtos ou serviços dentro da interface do app
- Conteúdo de marca: exiba apenas a sua própria identidade de marca, não marcas de terceiros (exceto parceiros de integração, como a Brevo)
Linguagem e conteúdo
- Linguagem consistente: use a mesma terminologia em todo o app
- Tom profissional: acompanhe o estilo de comunicação profissional e conciso do Stripe Dashboard
- Sem jargão: evite jargão técnico que os lojistas talvez não entendam
- Revisão ortográfica: garanta que todos os textos estejam livres de erros de ortografia e gramática
- Somente em inglês: todo o texto visível ao usuário precisa estar em inglês nos apps do marketplace
Diálogos de confirmação
Exija a confirmação do usuário em ações destrutivas ou relevantes:
// 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(); }};Ações que exigem confirmação:
- Desconectar integrações
- Excluir dados sincronizados
- Alterar configurações que afetam o fluxo de dados
- Restaurar a configuração para os valores padrão
Estados de carregamento
Sempre mostre indicadores de carregamento nas operações assí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:
- Mostre spinners ou telas de esqueleto durante o carregamento dos dados
- Desative os botões durante o envio de formulários
- Exiba indicadores de progresso em operações demoradas
- Nunca mostre uma tela em branco durante o carregamento
Mensagens de erro
Ofereça mensagens de erro claras e acionáveis:
// 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."Diretrizes para mensagens de erro:
- Explique o que aconteceu em linguagem simples
- Sugira uma ação específica que o usuário pode tomar para resolver o problema
- Ofereça uma forma de repetir a operação que falhou
- Registre informações detalhadas do erro para depuração (sem mostrá-las ao usuário)
- Inclua códigos de erro como referência para o suporte quando fizer sentido
Segurança
API do Secret Store
Use a API do Secret Store do Stripe para armazenar todos os dados sensíveis:
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 armazene dados sensíveis em:
- Local storage ou session storage
- Cookies
- Parâmetros de URL
- Valores fixos no código-fonte
- Arquivos de configuração em texto puro
Criptografia
- Sem criptografia própria: não implemente os seus próprios algoritmos de criptografia
- Use as primitivas de segurança nativas do Stripe (Secret Store, signing secrets)
- Use HTTPS em todas as chamadas de API externas
- Valide todas as assinaturas de webhook antes de processá-las
Tratamento de dados
- Solicite apenas as permissões de que o seu app realmente precisa
- Não armazene dados do Stripe além do necessário para o funcionamento
- Implemente políticas de retenção de dados alinhadas com a sua política de privacidade
- Ofereça um meio para os usuários solicitarem a exclusão dos dados
Conformidade legal
Política de privacidade
Seu app precisa ter uma política de privacidade publicamente acessível que cubra:
- Quais dados o seu app coleta do Stripe
- Como os dados são armazenados, processados e compartilhados
- Políticas de retenção e de exclusão de dados
- Os direitos dos usuários sobre os próprios dados
- Informações de contato para dúvidas sobre privacidade
- A conformidade com as regulamentações aplicáveis (GDPR, CCPA etc.)
Termos de serviço
- Ofereça termos de serviço claros para o seu app
- Não inclua termos que entrem em conflito com os Termos de Serviço do Stripe
- Informe com clareza quaisquer limitações ou restrições de uso
Conformidade regulatória
- Cumpra todas as regulamentações de proteção de dados aplicáveis
- Implemente os acordos de processamento de dados adequados
- Atenda a pedidos de portabilidade e de exclusão de dados
- Mantenha logs de auditoria de acesso e de processamento de dados
Prazos do processo de revisão
| Etapa | Duração |
|---|---|
| Envio inicial | 5 a 10 dias úteis |
| Revisão da correção | 3 a 7 dias úteis |
| Aprovação final | 1 a 2 dias úteis |
| Publicação | Imediata após a aprovação |
Tip
Trate todo o retorno da revisão em uma única correção para evitar vários ciclos de revisão. O time do Stripe dá um retorno específico e acionável para cada problema encontrado.
Motivos comuns de rejeição
- Falta de tratamento de erros, o app trava com erros de rede ou dados inesperados
- Estados de carregamento insuficientes, telas em branco durante a busca de dados
- Preços pouco claros, preços não divulgados por completo na listagem
- Permissões em excesso, solicitação de permissões que o app não precisa
- Modo sandbox quebrado, o app não funciona no modo de teste
- Problemas de segurança, segredos armazenados fora da API do Secret Store
- Falta de política de privacidade, nenhuma URL de política de privacidade acessível
- Funcionamento incompleto, recursos “coming soon” ou conteúdo temporário