Pular para o conteúdo principal

Integração App-to-App

No modo app-to-app, o seu aplicativo de PDV, ERP ou autoatendimento aciona o terminal de pagamento por Intents Android e recebe o desfecho de volta, sem embutir o SDK. Toda a parte de hardware, telas de pagamento e comunicação com o autorizador fica no app host, um aplicativo da Tupi instalado no terminal.

Você depende apenas de um artefato de contrato, pequeno e sem dependências do fabricante. Não há callbacks a implementar: cada operação é uma chamada com resultado.

Quando usar​

ModoIndicado para
App-to-app (este guia)Apps que já existem e querem cobrar no terminal sem assumir telas de pagamento, leitura de cartão, senha nem certificação EMV. As telas são do terminal, com a marca do parceiro cadastrada no portal
Biblioteca (guia do SDK)Apps que querem controlar toda a experiência e o layout de pagamento e embutem o SDK, implementando PosPinpadCallback

Arquitetura​

┌────────────────────────────┐
│ Seu app (PDV / ERP) │ depende só do contrato
└────────────────────────────┘
│ requisição ▲ resposta
▼ │
┌────────────────────────────┐
│ App host (Tupi) │ ◀──▶ Operador e portador
│ telas, cartão e senha; │ cartão, senha, Cancelar
│ valida quem chama │
└────────────────────────────┘
│ autorização ▲ desfecho
▼ │
┌────────────────────────────┐
│ Gateway Tupi │
│ e adquirentes │
└────────────────────────────┘
ParticipanteResponsabilidade
Seu appMontar a requisição, disparar a Intent, guardar o identificador da operação e decidir pelo status da resposta
App host (com.tupifintech.pos.service)Validar quem chamou, executar a operação no hardware, desenhar as telas de pagamento e devolver o desfecho
Operador e portadorApresentar o cartão, digitar a senha, cancelar quando o terminal permitir, aprovar o credenciamento do seu app e preencher o cadastro do estabelecimento na ativação

Dados de cartão nunca saem do terminal: o seu app recebe só bandeira, 6 primeiros e 4 últimos dígitos.

Telas de pagamento​

Durante a operação, quem aparece para o portador são as telas do app host, por cima do seu app: espera do cartão, senha, CVV, seleção de aplicação, QR Code do Pix e processamento. Elas usam a marca do parceiro cadastrada no portal: o logo (ou o nome) no topo e a cor primária nos botões e no teclado de senha. As telas de senha, de credenciamento e de ativação ficam sem o cabeçalho e recebem só a cor; a de senha mantém sempre o mesmo layout, para o portador reconhecer a tela legítima.

A marca é a do parceiro para o qual o app host foi gerado. O host a guarda no aparelho, então as telas funcionam também sem rede. Para mudar logo, cor ou nome, atualize o cadastro do parceiro no portal: o terminal busca a versão mais recente quando o app host é iniciado e quando a tela local do terminal é aberta; sem rede, mantém a última marca guardada.

Regras do cadastro da marca:

  • Logo: só por https:// e com até 512 KB. Logo em SVG não é exibido: o host usa o logo de impressão (bitmap) e, sem ele, mostra só o nome.
  • Cor primária: #RRGGBB ou #AARRGGBB. Valor inválido mantém a cor padrão do host. A cor do texto sobre ela (preto ou branco) é escolhida automaticamente pelo contraste.
  • A marca muda só a aparência: nenhuma resposta do protocolo depende dela.

Pré-requisitos​

ItemValor
Dependênciacom.tupifintech:pos-integration-contract
RepositórioGitHub Packages da Tupi (credenciais fornecidas pela Tupi)
minSdk21
Dependências transitivaskotlin-stdlib e kotlinx-serialization-json
Pacote do app hostcom.tupifintech.pos.service
Versão do protocolo1
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven {
url = uri("https://maven.pkg.github.com/tupi-fintech/yby-android-mobile-pos-sdk")
credentials {
username = providers.gradleProperty("gpr.user").get()
password = providers.gradleProperty("gpr.token").get()
}
}
}
}

// app/build.gradle.kts
dependencies {
implementation("com.tupifintech:pos-integration-contract:<versão>")
}

O que você não precisa:

  • AARs do fabricante do terminal, chave de plataforma ou o SDK de pagamento.
  • Declarar <queries> no manifest. O contrato já traz a visibilidade do app host, obrigatória a partir do Android 11; sem ela a Intent falharia com ActivityNotFoundException mesmo com o host instalado.
  • Implementar callbacks ou serviços.
  • Escrever regras de R8/ProGuard para o contrato. Ele já traz as suas, e o app com minify ligado as herda.

O que você recebe da Tupi junto com o APK do app host:

  • O SHA-256 do certificado de assinatura do host, usado em verifyHost (Preparação).
  • O cadastro do estabelecimento (por exemplo, CNPJ e código de verificação), que é digitado no terminal na ativação.

Início rápido​

class CaixaActivity : ComponentActivity() {

private val pos = registerForActivityResult(StartActivityForResult()) { result ->
val response = PosIntegrationClient.parseResponse(result.resultCode, result.data)
marcarComoRespondido(response.clientTransactionId)
when (response.status) {
PosStatus.APPROVED -> concluirVenda(response.receipt!!)
PosStatus.DECLINED -> mostrarRecusa(response.error?.message)
PosStatus.CANCELLED -> voltarAoCarrinho()
PosStatus.BUSY -> avisarTerminalOcupado()
else -> tratarFalha(response.error) // ERROR e UNKNOWN
}
}

fun cobrar(valorEmCentavos: Long) {
val request = PosIntegrationClient.sale(
SalePayload(amountInCents = valorEmCentavos, paymentMethod = PaymentMethod.CREDIT)
)
persistir(request.clientTransactionId) // antes do launch
pos.launch(request.intent)
}
}

Quatro regras que evitam a maioria dos problemas​

  1. Dispare sempre esperando resultado, com ActivityResultLauncher ou startActivityForResult. Com startActivity o host não identifica quem chamou e recusa a operação, mas o seu app não recebe resposta nenhuma.
  2. Decida pelo status, nunca pelo resultCode. O host devolve RESULT_OK sempre que há resposta estruturada, inclusive em recusa e terminal ocupado.
  3. Persista o clientTransactionId antes do launch. Se o Android encerrar o seu app durante a venda, esse id é a única forma de descobrir o desfecho.
  4. Confira o host antes da primeira operação com verifyHost.

Documentação​

  1. Preparação do terminal: verificação do host, credenciamento do seu app e ativação do terminal
  2. Operações: ciclo de uma operação, formato das Intents e catálogo de operações
  3. Respostas e erros: status, comprovante e códigos de erro
  4. Cancelamento e recuperação: timeout, recuperação do desfecho e idempotência
  5. Segurança e compatibilidade: regras obrigatórias e convivência entre versões
  6. Homologação: checklist de testes e problemas comuns

A Tupi mantém um app cliente de referência que demonstra o ciclo inteiro, inclusive a persistência do id e a recuperação, usando apenas o contrato. Solicite o acesso ao time de integração.