2 - Realizar Pagamento
Realize pagamentos por aproximação (Tap to Pay) utilizando o SDK Android da Zoop.
Realize pagamentos por aproximação (Tap to Pay) utilizando o SDK Android da Zoop. Esta página cobre as 3 etapas necessárias para processar um pagamento:
① Inicialização do Kernel → ② Configuração do SDK → ③ Pagamento
kernelInitialize() setConfig() pay()Inicialização do Kernel
O kernelInitialize() é o primeiro método obrigatório a ser chamado antes de usar qualquer funcionalidade do SDK. Implemente-o na classe Application do seu app, dentro do onCreate().
Chame
kernelInitialize()logo apóssuper.onCreate(). Caso contrário, os processos internos do SDK podem não funcionar corretamente.
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// Garante que o código abaixo só execute no processo da sua aplicação
if (!TapOnPhone.kernelInitialize(this))
return
// Restante da inicialização do seu app...
}
}Por que o if (!kernelInitialize()) return é necessário?
✅ Retornotrue
O processo pertence à sua aplicação (Host Application). O código deve continuar executando normalmente.
⛔ Retornofalse
O processo pertence ao SDK (Crypto Process). O código deve retornar imediatamente com return para evitar inicialização duplicada.
Durante a inicialização, o SDK cria um processo criptográfico (Crypto Process) em background, fazendo com que o onCreate() seja chamado mais de uma vez. O retorno booleano permite distinguir o processo:
✅ Retorno true — Processo da sua aplicação. Continue normalmente.
⛔ Retorno false — Processo do SDK (Crypto). Retorne imediatamente.
Application.onCreate()
│
├─ super.onCreate()
│
├─ TapOnPhone.kernelInitialize(this)
│ │
│ ├─ retorna true → Host Application → continua a inicialização do app
│ │
│ └─ retorna false → Crypto Process → return (encerra imediatamente)
│
└─ Restante da inicialização do app (só executa se true)Sem essa verificação, o onCreate() executaria duas vezes — uma para cada processo — causando erros e comportamento inconsistente.
Definir configurações do SDK
O método TapOnPhone.setConfig() permite configurar credenciais, timeout, volume do beep, tema e comportamento de telas de erro em uma única chamada.
Chame
TapOnPhone.setConfig()apósTapOnPhone.kernelInitialize()e antes da inicialização do terminal. Sem essa chamada, o SDK não funcionará corretamente.
Estrutura
data class ConfigParameters(
val context: Context,
val credentials: Credentials,
val sdkConfig: SdkConfig
)data class SdkConfig(
val theme: TapOnPhoneTheme? = null,
val timeout: TimeoutConfig? = null,
val beepVolume: BeepVolumeConfig? = null,
val showErrorScreen: Boolean? = null
)Configurações disponíveis
| Parâmetro | Descrição | Valores |
|---|---|---|
timeout | Tempos de timeout para cada etapa da transação | Vide Configurações de timeout |
beepVolume | Volume do beep do dispositivo durante a transação | Vide Volume do Beep |
theme | Cores e aparência da interface do SDK | Vide Configurações de tema |
showErrorScreen | Exibir telas de erro quando ocorrerem falhas | true (padrão) ou false |
Exemplo completo de configuração
// Credenciais
val credentials = Credentials(
clientId = "seu_client_id",
clientSecret = "seu_client_secret",
marketplace = "seu_marketplace",
seller = "seu_seller",
accessKey = "seu_access_key",
attestation = Attestation(
clientId = "seu_client_id_attestation",
clientSecret = "seu_client_secret_attestation"
)
)
// Timeout
val timeoutConfig = TimeoutConfig(
discoveryTimeout = 30_000, // Tempo para detectar o cartão (ms)
processingTimeout = 20_000, // Tempo de processamento do kernel (ms)
networkTimeout = 30_000, // Tempo de comunicação com o servidor (ms)
totalElapsedTimeout = 180_000 // Tempo total máximo da transação (ms)
)
// Tema
val theme = TapOnPhoneTheme(
backgroundColor = Color.parseColor("#FFFFFFFF"),
amountTextColor = Color.parseColor("#000000"),
paymentTypeTextColor = Color.parseColor("#FFFF0000"),
statusTextColor = Color.parseColor("#FF000000"),
statusBarColor = Color.parseColor("#FF7300")
)
// Aplicar configurações
TapOnPhone.setConfig(
ConfigParameters(
context = context,
credentials = credentials,
sdkConfig = SdkConfig(
timeout = timeoutConfig,
theme = theme,
beepVolume = BeepVolumeConfig(beepVolume = 0.5f),
showErrorScreen = true
)
)
)Nunca inclua credenciais diretamente no código-fonte. Armazene-as em variáveis de ambiente ou em um serviço de gerenciamento de segredos no backend e injete-as em tempo de execução.
Pagamento
Utilize o método TapOnPhone.pay() para realizar pagamentos por aproximação.
Se o dispositivo ainda não estiver inicializado, o SDK executará
initialize()eactivateSession()automaticamente antes do pagamento — o que pode adicionar alguns segundos de espera. Para evitar esse tempo, chame-os previamente.
Parâmetros do pagamento
O método pay() recebe um objeto PaymentRequest:
data class PaymentRequest(
val amount: Long,
val paymentType: PaymentType,
val installments: Int? = null,
val referenceId: String? = null,
val metadata: String? = null
)| Parâmetro | Tipo | Descrição | Exemplo |
|---|---|---|---|
amount | Long | Valor da transação em centavos. | 10000 (R$ 100,00) |
paymentType | PaymentType | Tipo do pagamento. | PaymentType.CREDIT |
installments | Int? | Quantidade de parcelas (opcional). | 2 |
referenceId | String? | Identificador próprio do parceiro (opcional, máx. 50 caracteres). | "237ab31-g99c-..." |
metadata | String? | Metadados em JSON fornecidos pelo parceiro (opcional, máx. 512 caracteres). | Vide Metadados |
Tipos de pagamento e metadados
PaymentType
enum class PaymentType {
CREDIT, // Crédito
DEBIT, // Débito
PIX // Pix
}Metadados em JsonObject
val metadata = buildJsonObject {
put("clientId", "1234")
put("name", "John Doe")
}Exemplo completo
Chamada do pay() com tratamento de sucesso, erro e eventos:
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}")
println("Bandeira: ${result.cardBrand}")
println("Bin: ${result.binNumber}")
result.paymentDevice?.let {
println("Dispositivo: $it")
}
},
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 (se disponível)
it.integrityErrorCode?.let { integrityError ->
Log.e("Payment", "Integrity Error Code: ${integrityError.code}")
Log.e("Payment", "Integrity Error Description: ${integrityError.description}")
}
}
}
ErrorResponse.ErrorType.Session -> {
val sessionError = error.error as? SessionErrorResponse
sessionError?.let {
println("Erro de sessão: ${it.message}")
it.integrityErrorCode?.let { integrityError ->
Log.e("Payment", "Integrity Error Code: ${integrityError.code}")
}
}
}
else -> {
// Tratar outros tipos de erro
}
}
},
onEvent = { event ->
Log.d("Payment", "Evento: ${event.name}")
}
)Respostas
Sucesso — PaymentApprovedResponse
PaymentApprovedResponsedata class PaymentApprovedResponse(
val transactionId: String, // ID da transação na Zoop
val referenceId: String, // Seu ID para a transação, se fornecido no request
val cardBrand: CardBrand, // Bandeira do cartão
val binNumber: String, // Primeiros dígitos do cartão
val paymentDevice: String? // Tipo de dispositivo (CARD, WATCH), se disponível
)Erro — Tratamento por tipo
O callback onError recebe um ErrorResponse unificado. Verifique o type para acessar detalhes específicos:
onError = { error ->
when (error.type) {
ErrorResponse.ErrorType.Payment -> {
val paymentError = error.error as? PaymentErrorResponse
// Detalhes do erro de pagamento
}
ErrorResponse.ErrorType.Session -> {
val sessionError = error.error as? SessionErrorResponse
// Detalhes do erro de sessão
}
else -> {
// Outros tipos de erro
}
}
}Detalhes do erro — PaymentErrorResponse
PaymentErrorResponseContém informações detalhadas sobre a falha:
data class PaymentErrorResponse(
val transactionId: String?, // ID da transação na Zoop (null se falhou antes do envio)
val referenceId: String?, // Seu ID para a transação
val message: String?, // Mensagem de erro para o usuário
val code: Int?, // Código de erro
val source: String?, // Onde ocorreu o erro
val description: String?, // Descrição detalhada do erro
val errorSource: String?, // Origem: sdk, backend, kernel, acquirer
val operationType: String?, // Tipo de operação: pay, activation
val kernel: KernelError?, // Detalhes do erro do kernel
val attestationStatus: Array<AttestationStatus>, // Informações de attestation
val binNumber: String?, // Primeiros dígitos do cartão
val paymentDevice: String?, // Tipo de dispositivo (CARD, WATCH)
val integrityErrorCode: IntegrityErrorCode?, // Erro da Google Play Integrity API
val zoopDescription: String? // Descrição do erro retornada pela Zoop
)Objetos aninhados de PaymentErrorResponse
data class KernelError(
val code: Int, // Código do erro kernel
val name: String, // Nome do erro kernel
val description: String // Descrição do erro kernel
)data class AttestationStatus(
val outcomes: Array<Outcome>,
val status: String,
val timestampUtc: String
) {
data class Outcome(
val moniker: String,
val reason: String,
val statusCode: Int
)
}| Campo | Descrição |
|---|---|
transactionId | ID da transação na Zoop. Será null se a falha ocorreu antes do envio ao servidor. |
code | Código numérico do erro. Consulte a referência de erros para detalhes. |
errorSource | Indica a origem do erro: sdk, backend, kernel ou acquirer. |
kernel | Presente quando o erro é do kernel. Contém código, nome e descrição da falha. |
attestationStatus | Informações de attestation quando o erro está relacionado à segurança do dispositivo. |
integrityErrorCode | Código de erro da Google Play Integrity API, quando disponível. |
Updated about 4 hours ago
