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çãoDescrição
🔒 Integridade do dispositivoDispositivo em modo seguro (sem root, sem debug).
📦 Validação do aplicativoAplicativo instalado através da Google Play Store.
🛡️ Verificação de segurançaAmbiente de execução confiável.
🏷️ Validação de versãoVersion 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 + integrityErrorCode

Tratamento 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ódigoReasonDescrição
100ERROR_UnableToDecodeNão foi possível decodificar a resposta.
101RequestDetail_NameNotMatchO nome na requisição não confere.
102RequestDetail_NonceNotMatchO nonce na requisição não confere.
103RequestDetail_InvalidTimeStampTimestamp da requisição inválido.
104AppIntegrity_UnevaluatedA integridade do app não foi avaliada.
105AppIntegrity_UnrecognizedVersionVersão do app não reconhecida pela Play Store.
106AppIntegrity_PackageNameNotMatchO packageName não confere com o esperado.
107AppIntegrity_CertNotMatchO certificado de assinatura não confere.
108AppIntegrity_VersionCodeNotMatchO versionCode não confere com o liberado.
109AppIntegrity_UnsuccessfulResultA verificação de integridade do app falhou.
110DeviceIntegrity_NotMetO dispositivo não atende aos requisitos de integridade.
111DeviceIntegrity_NotStrongO nível de integridade do dispositivo não é suficiente.
112AccountDetails_UnlicensedA conta Google não possui licença para o app.
113AccountDetails_UnevaluatedOs detalhes da conta não foram avaliados.
114AccountDetails_UnsuccessfulResultA 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ódigoErroDescrição
-1API_NOT_AVAILABLEA Integrity API não está disponível. A Play Store pode estar desatualizada ou não instalada.
-2PLAY_STORE_NOT_FOUNDO app da Play Store não foi encontrado no dispositivo.
-3NETWORK_ERRORErro de conexão com a internet. Verifique a conexão do dispositivo.
-4PLAY_STORE_ACCOUNT_NOT_FOUNDNenhuma conta Google encontrada no dispositivo.
-5APP_UID_MISMATCHO UID da aplicação chamadora não corresponde ao UID do pacote.
-6TOO_MANY_REQUESTSMuitas requisições feitas em curto período. Tente novamente mais tarde.
-7CANNOT_BIND_TO_SERVICENão foi possível conectar ao serviço da Play Store. Pode haver outra versão do serviço em execução.
-8GOOGLE_SERVER_UNAVAILABLEServidores do Google indisponíveis temporariamente.
-9PLAY_STORE_VERSION_OUTDATEDA versão da Play Store está desatualizada. Atualize a Play Store.
-10APP_NOT_INSTALLEDA aplicação não está instalada (pode ocorrer em emuladores ou ambientes de teste mal configurados).
-12CLIENT_TRANSIENT_ERRORErro transiente no cliente. Tente novamente com backoff exponencial.
-100INTERNAL_ERRORErro interno desconhecido.

Como tratar

Trate esses erros exibindo mensagens apropriadas ao usuário. Os cenários mais comuns:

CódigoCenárioOrientação ao usuário
-3Sem conexãoSolicite que o usuário verifique a internet.
-4Sem conta GoogleSolicite que o usuário faça login com uma conta Google no dispositivo.
-9Play Store desatualizadaSolicite que o usuário atualize a Play Store.
-6Muitas requisiçõesAguarde alguns minutos e tente novamente.
-8Servidores indisponíveisTente 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.