5 - Motivo do Attestation
Entenda o processo de attestation do SDK Tap to Pay — verificação de segurança, configuração de credenciais e tratamento de erros.
O attestation é uma verificação de segurança que garante que o SDK está sendo executado em um dispositivo seguro e confiável.
Como funciona?
O attestation ocorre automaticamente antes de cada transação. Se a verificação falhar, o pagamento é interrompido.
pay() → Attestation → ✅ Aprovado → Transação inicia
→ ❌ Reprovado → Pagamento interrompido (onError)O que é verificado
| Verificação | Descrição |
|---|---|
| 🔒 Integridade do dispositivo | Dispositivo em modo seguro (sem root, sem debug). |
| 📦 Validação do aplicativo | Aplicativo instalado através da Google Play Store. |
| 🛡️ Verificação de segurança | Ambiente de execução confiável. |
| 🏷️ Validação de versão | Version code do aplicativo liberado e aprovado. |
Configuração das credenciais de Attestation
Para receber informações detalhadas sobre falhas de segurança, configure as credenciais de attestation no parâmetro attestation da classe Credentials durante o setConfig:
val credentials = Credentials(
clientId = "seu_client_id",
clientSecret = "seu_client_secret",
marketplace = "seu_marketplace",
seller = "seu_seller",
accessKey = "seu_access_key",
// Credenciais de attestation (opcionais)
attestation = Attestation(
clientId = "seu_client_id_attestation",
clientSecret = "seu_client_secret_attestation"
)
)
TapOnPhone.setConfig(
ConfigParameters(
context = context,
credentials = credentials,
sdkConfig = sdkConfig
)
)O campo
attestationé completamente opcional. Sem ele, o SDK funciona normalmente, mas não fornece detalhes específicos sobre erros de attestation. Preencha apenas se quiser receber informações detalhadas sobre falhas de segurança do dispositivo.
As credenciais de attestation são diferentes das credenciais principais do SDK. Elas são recebidas durante o onboarding e são específicas para a Cliente Role. Consulte a seção Onboarding para mais detalhes sobre os tipos de credenciais.
API de Status de Attestation
A API de Status de Attestation por Instance ID fornece informações sobre as verificações realizadas contra um identificador de instância específico, permitindo identificar e gerenciar rapidamente problemas de attestation.
Os dados de attestation ficam disponíveis por apenas 1 hora após a consulta.
Quando o Attestation falha
Quando o attestation falha, o SDK executa automaticamente os seguintes passos:
① Identifica o erro → ② Consulta a API → ③ Retorna detalhes no onError
DEVICE_STATE_FAILURE de attestation attestationStatus + integrityErrorCodeTratamento no código
O callback onError recebe os detalhes da falha de attestation:
TapOnPhone.pay(
request = PaymentRequest(
amount = 10000, // R$ 100,00
paymentType = PaymentType.CREDIT,
installments = 2,
referenceId = UUID.randomUUID().toString(),
metadata = """
{
"clientId": "1234",
"name": "John Doe"
}
"""
),
onSuccess = { result ->
println("Pagamento Aprovado! Id: ${result.transactionId}")
},
onError = { error ->
when (error.type) {
ErrorResponse.ErrorType.Payment -> {
val paymentError = error.error as? PaymentErrorResponse
paymentError?.let {
println("Pagamento negado - id: ${it.transactionId}")
println("Mensagem: ${it.message}")
println("Código: ${it.code}")
println("Descrição: ${it.description}")
// Informações de attestation (se disponíveis)
it.attestationStatus?.forEach { attestation ->
Log.d("status", attestation.status)
Log.d("timestamp", attestation.timestampUtc)
attestation.outcomes.forEach { outcome ->
Log.d(
"outcome",
"moniker[${outcome.moniker}] " +
"code[${outcome.statusCode}] " +
"reason[${outcome.reason}]"
)
}
}
// Código de erro da Google Play Integrity API
it.integrityErrorCode?.let { integrityError ->
Log.e("Payment", "Code: ${integrityError.code}")
Log.e("Payment", "Description: ${integrityError.description}")
}
}
}
else -> {
// Tratar outros tipos de erro
}
}
},
onEvent = { event ->
Log.d("Payment", "Evento: ${event.name}")
}
)Tabela de erros de Attestation
Códigos retornados no campo attestationStatus.outcomes:
| Código | Reason | Descrição |
|---|---|---|
| 100 | ERROR_UnableToDecode | Não foi possível decodificar a resposta. |
| 101 | RequestDetail_NameNotMatch | O nome na requisição não confere. |
| 102 | RequestDetail_NonceNotMatch | O nonce na requisição não confere. |
| 103 | RequestDetail_InvalidTimeStamp | Timestamp da requisição inválido. |
| 104 | AppIntegrity_Unevaluated | A integridade do app não foi avaliada. |
| 105 | AppIntegrity_UnrecognizedVersion | Versão do app não reconhecida pela Play Store. |
| 106 | AppIntegrity_PackageNameNotMatch | O packageName não confere com o esperado. |
| 107 | AppIntegrity_CertNotMatch | O certificado de assinatura não confere. |
| 108 | AppIntegrity_VersionCodeNotMatch | O versionCode não confere com o liberado. |
| 109 | AppIntegrity_UnsuccessfulResult | A verificação de integridade do app falhou. |
| 110 | DeviceIntegrity_NotMet | O dispositivo não atende aos requisitos de integridade. |
| 111 | DeviceIntegrity_NotStrong | O nível de integridade do dispositivo não é suficiente. |
| 112 | AccountDetails_Unlicensed | A conta Google não possui licença para o app. |
| 113 | AccountDetails_Unevaluated | Os detalhes da conta não foram avaliados. |
| 114 | AccountDetails_UnsuccessfulResult | A verificação da conta falhou. |
Integrity Error Codes
A Google Play Integrity API retorna códigos de erro quando não é possível verificar a integridade do dispositivo ou da aplicação. O SDK captura esses erros e os disponibiliza através do campo integrityErrorCode nos objetos SessionErrorResponse e PaymentErrorResponse.
Códigos de erro
| Código | Erro | Descrição |
|---|---|---|
| -1 | API_NOT_AVAILABLE | A Integrity API não está disponível. A Play Store pode estar desatualizada ou não instalada. |
| -2 | PLAY_STORE_NOT_FOUND | O app da Play Store não foi encontrado no dispositivo. |
| -3 | NETWORK_ERROR | Erro de conexão com a internet. Verifique a conexão do dispositivo. |
| -4 | PLAY_STORE_ACCOUNT_NOT_FOUND | Nenhuma conta Google encontrada no dispositivo. |
| -5 | APP_UID_MISMATCH | O UID da aplicação chamadora não corresponde ao UID do pacote. |
| -6 | TOO_MANY_REQUESTS | Muitas requisições feitas em curto período. Tente novamente mais tarde. |
| -7 | CANNOT_BIND_TO_SERVICE | Não foi possível conectar ao serviço da Play Store. Pode haver outra versão do serviço em execução. |
| -8 | GOOGLE_SERVER_UNAVAILABLE | Servidores do Google indisponíveis temporariamente. |
| -9 | PLAY_STORE_VERSION_OUTDATED | A versão da Play Store está desatualizada. Atualize a Play Store. |
| -10 | APP_NOT_INSTALLED | A aplicação não está instalada (pode ocorrer em emuladores ou ambientes de teste mal configurados). |
| -12 | CLIENT_TRANSIENT_ERROR | Erro transiente no cliente. Tente novamente com backoff exponencial. |
| -100 | INTERNAL_ERROR | Erro interno desconhecido. |
Como tratar
Trate esses erros exibindo mensagens apropriadas ao usuário. Os cenários mais comuns:
| Código | Cenário | Orientação ao usuário |
|---|---|---|
| -3 | Sem conexão | Solicite que o usuário verifique a internet. |
| -4 | Sem conta Google | Solicite que o usuário faça login com uma conta Google no dispositivo. |
| -9 | Play Store desatualizada | Solicite que o usuário atualize a Play Store. |
| -6 | Muitas requisições | Aguarde alguns minutos e tente novamente. |
| -8 | Servidores indisponíveis | Tente novamente mais tarde. |
Para erros internos ou desconhecidos (como
-100), oriente o usuário a tentar novamente mais tarde. Se o problema persistir, colete os logs do SDK e entre em contato com o suporte Zoop.
Updated about 3 hours ago
