Pular para o conteúdo principal

Tap On Phone (Early Access)

O Tap On Phone permite que smartphones Android comerciais (COTS) aceitem pagamentos por aproximação (NFC), sem a necessidade de um terminal de pagamento dedicado. Essa modalidade utiliza a tecnologia gTapp como processador de pagamentos.

Atenção

O Tap On Phone requer que o aplicativo gTapp esteja instalado no dispositivo. O SDK verificará automaticamente a presença do app e retornará um erro caso ele não esteja disponível.

Pré-requisitos
  • Dispositivo Android com suporte a NFC
  • Aplicativo gTapp instalado e atualizado
  • Token de ativação (solicitar ao time de integrações do SDK Único)
  • Dispositivo deve passar nas verificações de segurança (attestation)

Configuração

Passo 1 — Adicionar a flavor gsurf

Adicione a flavor gsurf ao bloco de flavors no build.gradle.kts:

val flavors = setOf(
// ... outras flavors
"gsurf" to 26,
)

Passo 2 — Dependências

Com Flavors

val sdkPayServicesVersion = "$SDK_VERSION"

implementation("SDKPayServices:core:$sdkPayServicesVersion")
implementation("SDKPayServices:config:$sdkPayServicesVersion")
implementation("SDKPayServices:common:$sdkPayServicesVersion")

Standalone (sem Flavors)

val sdkPayServicesVersion = "$SDK_VERSION"

implementation("SDKPayServices:core-gsurf:$sdkPayServicesVersion")
implementation("SDKPayServices:gsurf:$sdkPayServicesVersion")
implementation("SDKPayServices:config:$sdkPayServicesVersion")
implementation("SDKPayServices:common:$sdkPayServicesVersion")

Passo 3 — Permissões

Além das permissões padrão do SDK Único, o Tap On Phone requer permissão de NFC:

<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />

Diferenças em relação aos demais provedores

O Tap On Phone possui características específicas que o diferenciam dos provedores tradicionais (SmartPOS):

CaracterísticaTap On PhoneProvedores SmartPOS
DispositivoSmartphones Android comerciais (COTS)Terminais de pagamento dedicados
Captura do cartãoApenas NFC (contactless)Chip, tarja magnética, NFC
AtivaçãoToken de ativação (solicitar ao time de integrações)CNPJ + parâmetros do provedor
ProcessadorPaymentProcessor.GSURFSTONE, TEF, REDE, etc.
ImpressãoVia impressora externa (Bluetooth/USB)Impressora térmica integrada
Transações suportadasCrédito, Débito, CancelamentoTodas as modalidades
SegurançaAttestation do dispositivoCertificação PCI do terminal
Operações não suportadas

As seguintes operações não estão disponíveis no Tap On Phone: voucher, pix, wallet, qrCode, fleet, preAuthorize, capturePreAuthorization, cancelPreAuthorization, executeAdminOperation.

Ativação

A ativação do Tap On Phone utiliza o campo gsurf dos ActivationParameters. O token de ativação deve ser solicitado ao time de integrações do SDK Único.

GSurfActivationParameters

CampoTipoDescrição
tokenString?Token de ativação do terminal. Solicitar ao time de integrações do SDK Único. Obrigatório.
Atenção

Realize a operação de ativação apenas 1 (uma) vez no terminal. Após a ativação bem-sucedida, o dispositivo fica vinculado à loja.

Exemplo

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.linx.paykit.common.Callback
import com.linx.paykit.common.activation.ActivationParameters
import com.linx.paykit.common.activation.ActivationResult
import com.linx.paykit.common.activation.GSurfActivationParameters
import com.linx.paykit.common.builder.Parameters
import com.linx.paykit.common.parameter.PaykitId
import com.linx.paykit.core.Paykit
import com.linx.paykit.core.PaykitFactory

class MainActivity : AppCompatActivity() {

private lateinit var paykit: Paykit

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

paykit = PaykitFactory().build(Parameters(this, "TapOnPhone", PaykitId("PAYKIT_ID")))

val activationParams = ActivationParameters(
storeCnpj = "12345678000199",
gsurf = GSurfActivationParameters(
token = "SEU_TOKEN_DE_ATIVACAO"
)
)

paykit.activate(activationParams, object : Callback<ActivationResult> {
override fun execute(result: ActivationResult) {
if (result.success) {
Log.i("Activation", "Tap On Phone ativado: ${result.message}")
} else {
Log.e("Activation", "Erro: ${result.message}")
}
}
})
}
}

Erros de Ativação

O Tap On Phone valida a segurança do dispositivo durante a ativação. Os possíveis erros são:

ErroDescrição
TOKEN_NOT_INFORMEDToken de ativação não foi informado.
APP_NOT_INSTALLEDAplicativo gTapp não está instalado no dispositivo.
INCOMPATIBLE_DEVICEDispositivo não é compatível com Tap On Phone (sem suporte a NFC ou hardware insuficiente).
ACTIVATION_FAILEDFalha na ativação — token inválido, expirado ou já utilizado em outro dispositivo.
DEVICE_NOT_SECUREDispositivo não passou na verificação de segurança (root, bootloader desbloqueado, etc.).
DEVICE_NOT_AUTHENTICATEDDispositivo não possui autenticação obrigatória configurada (PIN, senha ou biometria).

Verificação de Segurança (Attestation)

O Tap On Phone valida continuamente a integridade do dispositivo antes e durante as transações. Quando o dispositivo é considerado inseguro, o SDK retorna o erro DEVICE_NOT_SECURE com um reason_code no campo rawData do resultado.

Códigos de Dispositivo Não Seguro

O campo rawData do resultado contém as chaves reason_code e reason_description:

CódigoNomeDescriçãoSolução
1NO_SCREEN_LOCKDispositivo sem bloqueio de tela configurado.Configurar bloqueio de tela (PIN, senha ou biometria) nas configurações do dispositivo.
2DEBUG_MODE_ENABLEDModo de depuração USB ou desenvolvedor habilitado.Desabilitar as "Opções do desenvolvedor" e a "Depuração USB" nas configurações do dispositivo.
3CRITICAL_ATTESTATION_THREATAmeaça crítica de segurança detectada no dispositivo.Realizar restauração de fábrica ou utilizar outro dispositivo. Consulte a tabela de ameaças abaixo para detalhes.
4CAMERA_IN_USE_BY_OTHER_APPOutro aplicativo está utilizando a câmera do dispositivo.Fechar todos os aplicativos que utilizam a câmera antes de iniciar a transação.
5POSSIBLE_SECURITY_VULNERABILITIESPossíveis vulnerabilidades de segurança detectadas.Atualizar o sistema operacional e o patch de segurança para a versão mais recente. Se persistir, realizar restauração de fábrica.
6APP_LOST_FOCUSA aplicação perdeu o foco durante a operação.Não minimizar ou alternar entre aplicativos durante a transação. Tentar novamente mantendo o app em primeiro plano.

Ameaças Críticas de Attestation

Quando o reason_code é 3 (CRITICAL_ATTESTATION_THREAT), significa que o sistema de attestation detectou uma ameaça no dispositivo. As ameaças são agrupadas por categoria:

Ameaças do Dispositivo

AmeaçaDescriçãoSoluçãoRecuperável?
Dispositivo com rootAcesso privilegiado não autorizado ao sistema operacional.Restauração de fábrica ou utilizar outro dispositivo.
Adulteração do sistemaRemoção das limitações de segurança do fabricante.Restauração de fábrica ou utilizar outro dispositivo.
EmuladorApp executando em ambiente emulado (não é um dispositivo físico).O Tap On Phone requer um dispositivo Android físico.
Bootloader desbloqueadoO bootloader do dispositivo não é seguro.Restauração de fábrica ou utilizar outro dispositivo.
SELinux desabilitadoRecurso de segurança do sistema desativado.Restauração de fábrica ou utilizar outro dispositivo.
Modo depuração USBOpção de desenvolvimento habilitada no dispositivo.Desabilitar "Opções do desenvolvedor" nas configurações.
ADB Wi-Fi habilitadoDepuração sem fio habilitada no dispositivo.Desabilitar "Opções do desenvolvedor" nas configurações.
Horário do dispositivo inválidoRelógio do dispositivo desatualizado ou incorreto.Ajustar data e hora para automático nas configurações.

Ameaças de Aplicativo

AmeaçaDescriçãoSoluçãoRecuperável?
App malicioso detectadoAplicativo malicioso instalado no dispositivo.Desinstalar o app identificado. Se persistir, restauração de fábrica.⚠️
Malware via sideloadMalware instalado por loja não oficial.Desinstalar o app malicioso e instalar apps apenas via Google Play.⚠️
App com depuração habilitadaUm app com modo debug pode ser explorado.Desinstalar o app identificado. Se persistir, restauração de fábrica.⚠️
Adulteração de appBibliotecas do app foram modificadas ou injetadas.Restauração de fábrica ou utilizar outro dispositivo.
App gTapp não reconhecidoVersão do gTapp não corresponde ao registrado no Google Play.Desinstalar o gTapp e reinstalar via Google Play Store.
Rollback de versãoTentativa de reverter o app para uma versão anterior.Restauração de fábrica ou utilizar outro dispositivo.
App não licenciadoO gTapp não foi obtido pelo Google Play.Desinstalar e reinstalar via Google Play Store. Verificar conta Google.
Assinatura de app inválidaCertificado do app não corresponde ao esperado.Atualizar o SO e o patch de segurança. Reinstalar o gTapp via Google Play.⚠️

Ameaças de Rede

AmeaçaDescriçãoSoluçãoRecuperável?
Man-in-the-Middle (SSL Strip)Ataque interceptando tráfego HTTPS.Restauração de fábrica ou utilizar outro dispositivo.
Ponto de acesso falsoRede Wi-Fi mascarando redes conhecidas.Remover todas as redes Wi-Fi salvas e conectar apenas em redes confiáveis.
Rede comprometidaDados podem estar sendo interceptados.Remover todas as redes Wi-Fi salvas e conectar apenas em redes confiáveis.
Link de phishing visitadoUsuário acessou URL potencialmente maliciosa.Restauração de fábrica ou utilizar outro dispositivo.

Ameaças de PIN (Tela de Senha)

AmeaçaDescriçãoSoluçãoBloqueante?
Modo desenvolvedor ativoImpede transações que exigem digitação de senha.Desabilitar "Opções do desenvolvedor" nas configurações.Não bloqueia o dispositivo
Acessibilidade habilitadaServiço de acessibilidade ativo impede digitação de PIN.Desabilitar serviços de acessibilidade nas configurações.Não bloqueia o dispositivo
Captura de tela habilitadaServiço com capacidade de screenshot detectado.Desabilitar serviços de acessibilidade.Não bloqueia o dispositivo
Gravação de tela detectadaAplicativo gravando a tela durante transação.Parar gravação de tela antes de usar o Tap On Phone.Não bloqueia o dispositivo
Tela obscurecidaOutra janela sobrepondo a tela de PIN.Fechar todos os apps sobrepostos (bolhas de chat, etc.).Não bloqueia o dispositivo
Perda de foco no PINUsuário saiu da tela de PIN durante transação.Não alternar entre apps durante digitação de senha.Não bloqueia o dispositivo

Ameaças de Integridade (Google Play Integrity / Key Attestation)

AmeaçaDescriçãoSoluçãoRecuperável?
Integridade básicaVersão não reconhecida do Android.Restauração de fábrica ou utilizar outro dispositivo.
Integridade virtualDispositivo executando em emulador.Utilizar um dispositivo Android físico.
Nível de segurança do keystoreDispositivo sem keystore fortemente seguro.Utilizar outro dispositivo compatível.
Versão do SO desatualizadaAndroid não atende os requisitos mínimos.Atualizar o sistema operacional. Se não houver atualização, utilizar outro dispositivo.⚠️
Patch de segurança desatualizadoPatch de segurança não atende os requisitos.Atualizar o patch de segurança. Se não houver atualização, utilizar outro dispositivo.⚠️
Cadeia de certificados inválidaCertificados do keystore expirados ou malformados.Atualizar o SO. Se persistir, restauração de fábrica ou utilizar outro dispositivo.⚠️
Atenção — Erros de Attestation invalidam a ativação

Quando o dispositivo falha na verificação de segurança (attestation), os dados de ativação persistidos no dispositivo são removidos automaticamente. Isso significa que, após resolver o problema de segurança, será necessário realizar uma nova ativação com o token antes de processar transações novamente.

Legenda
  • Recuperável — O problema pode ser resolvido com ações simples no dispositivo.
  • ⚠️ Parcialmente recuperável — Pode ser resolvido, mas se as ações sugeridas não funcionarem, será necessário restauração de fábrica ou outro dispositivo.
  • Não recuperável — Requer restauração de fábrica ou substituição do dispositivo.
  • Em caso de dúvidas, consulte o time de integrações do SDK Único.

Transações

Crédito

O Tap On Phone suporta crédito à vista e parcelado (loja e emissor). O valor é enviado em centavos internamente pelo SDK.

val creditParams = CreditParameters(
amount = BigDecimal("150.00"),
installments = 3, // Parcelado em 3x (omitir para à vista)
externalId = "ORDER_123456"
)

paykit.credit(creditParams, object : Callback<PaymentResult> {
override fun execute(result: PaymentResult) {
if (result.status == TransactionStatus.APPROVED) {
Log.i("Payment", "Crédito aprovado: ${result.id}")
Log.i("Payment", "NSU: ${result.nsuInfo?.hostNsu}")
} else {
Log.e("Payment", "Negado: ${result.message}")
}
}
})

Débito

val debitParams = DebitParameters(
amount = BigDecimal("50.00"),
externalId = "ORDER_789012"
)

paykit.debit(debitParams, object : Callback<PaymentResult> {
override fun execute(result: PaymentResult) {
if (result.status == TransactionStatus.APPROVED) {
Log.i("Payment", "Débito aprovado: ${result.id}")
} else {
Log.e("Payment", "Negado: ${result.message}")
}
}
})

Cancelamento

O cancelamento no Tap On Phone requer paymentId, originalPaymentType (CREDIT ou DEBIT) e o valor a ser cancelado (cancelAmount ou amount).

Importante

O campo originalPaymentType é obrigatório no Tap On Phone e deve ser PaymentType.CREDIT ou PaymentType.DEBIT. Outros tipos serão rejeitados.

val cancelParams = CancelParameter(
paymentId = "TRANSACTION_ID_ORIGINAL",
amount = BigDecimal("150.00"),
originalPaymentType = PaymentType.CREDIT,
cancelAmount = BigDecimal("50.00") // Para cancelamento parcial
)

paykit.cancel(cancelParams, object : Callback<CancelResult> {
override fun execute(result: CancelResult) {
if (result.status == TransactionStatus.APPROVED) {
Log.i("Cancel", "Cancelamento aprovado: ${result.id}")
} else {
Log.e("Cancel", "Erro: ${result.message}")
}
}
})

Erros de Transação

Além dos erros padrão do SDK, o Tap On Phone pode retornar os seguintes erros específicos:

ErroDescrição
TERMINAL_NOT_ACTIVETerminal não ativado — execute activate antes
TERMINAL_EXPIREDAutenticação do terminal expirou — reative o terminal
ATTESTATION_FAILEDFalha no attestation do dispositivo
ACCESSIBILITY_ENABLEDServiços de acessibilidade ativos impedem a transação
TRANSACTION_CANCELLED_BY_USERUsuário cancelou a transação na tela do gTapp
TRANSACTION_TIMEOUTTempo limite para aproximação do cartão excedido

Customização Visual

O Tap On Phone permite customizar a aparência das telas de pagamento exibidas pelo gTapp. A customização é configurada via Parameter Manager através do parâmetro config_gsurf_customization.

Campos de Customização

CampoTipoDescrição
backgroundStartColorStringCor inicial do gradiente de fundo (hex #RRGGBB)
backgroundEndColorStringCor final do gradiente de fundo (hex #RRGGBB)
logoUrlStringURL HTTPS do logotipo exibido na tela de pagamento
currencySymbolTextColorStringCor do símbolo da moeda (R$)
amountTextColorStringCor do valor da transação
paymentTypeTextColorStringCor do texto do tipo de pagamento
cancelButtonColorStringCor do botão de cancelar
cancelButtonIconColorStringCor do ícone do botão de cancelar
contactlessLogoColorStringCor do ícone de contactless
titleTextColorStringCor do título
subtitleTextColorStringCor do subtítulo
mainProgressBarColorStringCor da barra de progresso principal
timerBarColorStringCor da barra de tempo
initialProgressBarColorStringCor da barra de progresso inicial
cardHintBottomSheetButtonColorStringCor do botão de dica do cartão
cardHintBottomSheetButtonTextColorStringCor do texto do botão de dica do cartão

Formato do JSON

{
"backgroundStartColor": "#59366D",
"backgroundEndColor": "#9A6FB4",
"logoUrl": "https://exemplo.com/logo.png",
"currencySymbolTextColor": "#FFFFFF",
"amountTextColor": "#FFFFFF",
"paymentTypeTextColor": "#FFFFFF",
"cancelButtonColor": "#B388CD",
"cancelButtonIconColor": "#FFFFFF",
"contactlessLogoColor": "#FFFFFF",
"titleTextColor": "#FFFFFF",
"subtitleTextColor": "#FFFFFF",
"mainProgressBarColor": "#B388CD",
"timerBarColor": "#B388CD",
"initialProgressBarColor": "#9A6FB4",
"cardHintBottomSheetButtonColor": "#59366D",
"cardHintBottomSheetButtonTextColor": "#FFFFFF"
}
dica

Todos os campos são opcionais. Apenas os campos informados serão aplicados; os demais mantêm o visual padrão do gTapp. Caso o parâmetro config_gsurf_customization não esteja configurado ou esteja vazio, o SDK aplica o fallback com as cores do tema padrão.

Impressão

Por ser executado em smartphones comerciais (sem impressora térmica integrada), o Tap On Phone utiliza impressoras externas via Bluetooth ou USB. O SDK detecta automaticamente a impressora disponível através do PrinterManager.

val bitmap: Bitmap = // Bitmap do comprovante

paykit.print(bitmap, object : Callback<PrintResult> {
override fun execute(result: PrintResult) {
if (result.success) {
Log.i("Print", "Comprovante impresso")
} else {
Log.e("Print", "Erro: ${result.message} - Status: ${result.status}")
}
}
})

Consulta da Última Transação

O Tap On Phone permite consultar os dados da última transação realizada:

paykit.getLastTransaction(object : Callback<TransactionQueryResult> {
override fun execute(result: TransactionQueryResult) {
Log.i("Query", "Última transação: ${result.id} - ${result.status}")
}
})

Este conteúdo foi útil para você?