Pular para o conteúdo principal

Segurança e compatibilidade

Segurança​

A confiança é mútua: o app host valida quem chama pelo pacote e pelo certificado de assinatura, e o seu app valida o host com verifyHost. Uma metade sozinha não protege a loja. As regras abaixo são obrigatórias para homologação.

RegraPor quê
Intent sempre explícita (setPackage("com.tupifintech.pos.service"))Com uma Intent implícita ou broadcast, qualquer app instalado poderia capturar o payload de pagamento. O PosIntegrationClient já monta a Intent assim
Valide o host antes da primeira operaçãoSem verifyHost, um APK falso com o mesmo pacote pode responder approved com um cupom plausível
Dados de cartão nunca cruzam a fronteira entre os appsNúmero completo, trilhas, bloco de senha e criptogramas ficam no terminal. O comprovante expõe só bandeira, 6 primeiros e 4 últimos dígitos
Senhas nunca trafegam na IntentAs senhas de usuários locais e de Supervisor são digitadas na tela do terminal
Não envie dado de portador em metadataO campo é gravado no terminal e segue para o backend
Operações administrativas exigem alguém no aparelhoO seu app pode pedir o credenciamento, a ativação e a gestão de usuários, mas quem conclui é a pessoa no terminal: aprova o app, digita o cadastro do estabelecimento ou a senha de Supervisor. Nenhum desses dados viaja na Intent
A ativação não troca o cadastroNum terminal já vinculado a um estabelecimento, activate_terminal não abre formulário. Trocar o cadastro por Intent permitiria desviar os recebimentos para outro CNPJ; isso só é feito no app do terminal
Cada desfecho tem donoRecuperação, idempotência e reimpressão só enxergam o que o seu pacote executou. Outro app credenciado não lê a sua venda pelo id, nem pelo id do gateway impresso no cupom
Guarde o HOST_SHA256 no seu appAtualize-o quando a Tupi anunciar uma rotação de chave do host. Numa rotação pelo esquema de assinatura v3, verifyHost continua reconhecendo a chave anterior

Compatibilidade entre versões​

O app host e o seu app são atualizados de forma independente, então em algum momento um falará uma versão diferente do outro. O protocolo usa JSON, e não objetos Android serializados, justamente para tolerar esse descompasso.

SituaçãoComportamento
Campo novo que a outra ponta não conheceIgnorado
Valor de enum novo (status, erro, meio de pagamento)Vira unknown; a message é preservada
Campo opcional ausenteAssume o valor padrão
Campo obrigatório ausente (por exemplo, clientTransactionId, amountInCents de venda e Pix, transactionId de reimpressão e consulta)Recusa com malformed_request
protocolVersion que o host não suportaRecusa com unsupported_protocol_version
Operação que o host não conheceRecusa com unsupported_operation
Bloco de impressão ou alinhamento que o host não conheceRecusa com malformed_request

Recomendações:

  • Trate unknown como "não sei tratar": mostre error.message e não tome decisão de negócio. O código unknown também aparece quando o host recebe uma falha sem código classificado, não só entre versões diferentes.
  • Use terminal_status para ler hostVersionName e supportedProtocolVersions e esconder funções que o host instalado não executa.
  • Atualize o contrato quando a Tupi publicar uma versão nova. Uma versão de contrato mais antiga continua funcionando: campos e valores novos são tratados como na tabela acima.