Implementação
1) Instanciando a TapOnPhoneSdk
Obtendo a instância da SDK:
private val tapOnPhoneSdkInstance = TapOnPhoneSdk.instanceMétodos públicos expostos pela TapOnPhoneSdk:
class TapOnPhoneSdk {
fun configure(context: Context, license: String)
fun activateDevice(
params: ActivateDeviceModel,
listener: ActivateDeviceListener
)
fun isDeviceActive(listener: IsDeviceActiveListener)
fun deactivateDevice(listener: DeactivateDeviceListener)
fun checkDeviceStatus(listener: DeviceStatusListener)
fun getActiveEstablishmentDetails(listener: ActiveEstablishmentDetailsListener)
fun makeTransaction(
params: TransactionParamsModel,
listener: MakeTransactionListener
)
fun nullifyTransaction(
transactionId: String,
listener: NullifyTransactionListener
)
fun listTransactions(listener: ListTransactionsListener)
fun getTransaction(
transactionId: String,
listener: GetTransactionListener
)
fun isNFCSupported(): Boolean
fun isNFCEnabled(): Boolean
fun goToNfcSetting(): Boolean
fun isMockCardTransactionsEnabled(): Boolean
}Pacotes utilizados:
import com.paytime.taponphonesdk.TapOnPhoneSdk
import com.paytime.taponphonesdk.external.listeners.* // listeners
import com.paytime.taponphonesdk.external.model.activation.ActivateDeviceModel
import com.paytime.taponphonesdk.external.model.auth.EstablishmentModel
import com.paytime.taponphonesdk.external.model.device.DeviceStatusModel
import com.paytime.taponphonesdk.external.model.transaction.* // transações
CallbacksTodos os métodos com
listenersão assíncronos. Os callbacks dolistenersão sempre chamados na main thread.A maioria dos listeners segue o mesmo padrão:
onMessage(type: String, message: String): mensagens informativas sobre o andamento da operação (ex.:type = "INFO");onApproved(result): sucesso da operação;onError(code: String, messages: List<String>, httpStatusCode: Int?): erro da operação. Veja os códigos na seção 7) Códigos de erro.
Operações simultâneasAs operações
activateDevice,deactivateDevice,makeTransactionenullifyTransactionnão podem ser executadas ao mesmo tempo. Se uma delas for chamada enquanto outra estiver em andamento, oonErroré chamado com o códigoINTERNAL_ERRORe a mensagem "Há uma operação em andamento. Aguarde a conclusão.".
1.1) Configuração
Para começar, é necessário chamar o método de configuração. O funcionamento de todos os outros métodos está atrelado à configuração, já que o context da aplicação é utilizado por todo o SDK. Se qualquer outro método for chamado antes do configure, será lançada uma IllegalStateException.
É necessário que este método seja chamado apenas uma vez. Recomenda-se chamá-lo no lifecycle de onCreate da aplicação. Chamadas seguintes não reconfiguram a SDK.
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
TapOnPhoneSdk.instance.configure(this, license)
}
}
LicençaO campo
licensedeve ser obtido junto com a Paytime. Uma licença vazia lança umaIllegalArgumentException.
1.2) Ativação do dispositivo
Para habilitar o uso da TapOnPhoneSdk, é necessário chamar o método de ativação do dispositivo. ActivateDeviceModel recebe o código de ativação do estabelecimento (disponível no cadastro do estabelecimento no portal), que deve ter no mínimo 8 caracteres.
val params = ActivateDeviceModel(activationCode)
tapOnPhoneSdkInstance.activateDevice(params, listener)listener é uma instância da interface ActivateDeviceListener, que é usada para tratar as respostas da ativação.
val listener = object : ActivateDeviceListener {
override fun onMessage(type: String, message: String) {
// Andamento da ativação (ex.: "Ativando dispositivo...")
}
override fun onApproved(result: Any?) {
// Dispositivo ativado com sucesso (result = true)
}
override fun onError(code: String, messages: List<String>, httpStatusCode: Int?) {
// Erros
}
}
Persistência da ativaçãoA ativação é persistida e continua válida após o app ser fechado e reaberto. Não é necessário ativar o dispositivo a cada inicialização. Use
isDeviceActiveoucheckDeviceStatuspara verificar o estado atual.
2) Realizar transação
Transações são realizadas através do método makeTransaction. O dispositivo precisa estar ativo; caso contrário, o onError é chamado com o código LOGON_NOT_PERFORMED.
O método makeTransaction recebe dois parâmetros: params e listener.
params é uma instância da classe TransactionParamsModel, que contém os detalhes da transação:
| Campo | Tipo | Descrição |
|---|---|---|
amount | Long | Valor da transação, em centavos. |
typeTransaction | TransactionTypeModel | Tipo da transação: CREDIT ou DEBIT. |
installment | Int? | Quantidade de parcelas. null ou 1 = à vista; maior que 1 = parcelado (apenas CREDIT). |
listener é uma instância da interface MakeTransactionListener, que é usada para tratar as respostas da transação.
Sobre valores monetáriosTodos os valores monetários são tratados pela SDK como centavos. Por exemplo, uma transação de R$ 10,99 deve informar o parâmetro amount = 1099.
2.1) Realizar transação CREDIT ou DEBIT
val params = TransactionParamsModel(
amount = 1000,
typeTransaction = TransactionTypeModel.CREDIT,
installment = null // ou um inteiro (ex.: 3 para crédito parcelado em 3x)
)
tapOnPhoneSdkInstance.makeTransaction(params, listener)No callback de onApproved, o parâmetro retornado é o resultado da transação (TransactionResultModel). A transação também é salva localmente (veja 4) Listagem de transações).
val listener = object : MakeTransactionListener {
override fun onMessage(type: String, message: String) {
// Andamento da transação (ex.: "Iniciando transação...")
}
override fun onApproved(result: TransactionResultModel) {
// Transação realizada com sucesso
val transactionId = result.paymentData.gatewayKey
}
override fun onError(code: String, messages: List<String>, httpStatusCode: Int?) {
// Erros
}
}TransactionResultModel:
data class TransactionResultModel(
val status: String,
val errorCode: String,
val errorSource: String?,
val errorDescription: String?,
val paymentData: TransactionPaymentDataModel,
)
data class TransactionPaymentDataModel(
val amount: Long,
val currencyCode: String,
val originalTransactionId: Long?, // apenas no cancelamento: transactionId da venda cancelada
val transactionId: Long,
val transactionType: String,
val transactionDate: String,
val applicationId: String,
val authorizationId: String,
val rrn: String,
val additionalData: String,
val ballot: Int,
val brand: String,
val cardFirstNumbers: String,
val cardLastDigits: String,
val dynamicBankData: String,
val gatewayKey: String,
val mid: String,
val cvmMethod: String,
val arqc: String,
val date: String,
val time: String,
)Quando o usuário cancela a transação ou o tempo expira, o onMessage é chamado com type = "PAYMENT_CANCEL" ou type = "PAYMENT_TIME_EXPIRED", seguido do onError.
Fluxo de senhaPara testar o fluxo de pedido de senha, basta criar uma transação com valor maior que o CVM Limit (R$ 200,00). Ao tentar pagar por aproximação, a SDK exibirá a opção de fornecer a senha. O limite por transação é de R$ 500,00.
3) Cancelamento/estorno de transação
Transações são estornadas através do método nullifyTransaction.
O método nullifyTransaction recebe dois parâmetros: transactionId e listener.
transactionId é um campo do tipo String. Pode ser informado o gatewayKey ou o transactionId retornados no paymentData da transação (ou no TransactionStoreModel da listagem local).
listener é uma instância da interface NullifyTransactionListener, que é usada para tratar as respostas do cancelamento. No onApproved, o retorno é um TransactionResultModel com os dados do cancelamento (paymentData.originalTransactionId contém o transactionId da venda cancelada).
tapOnPhoneSdkInstance.nullifyTransaction(transactionId, listener)val listener = object : NullifyTransactionListener {
override fun onMessage(type: String, message: String) {
// Andamento do cancelamento (ex.: "Iniciando cancelamento...")
}
override fun onApproved(result: TransactionResultModel) {
// Transação cancelada com sucesso
}
override fun onError(code: String, messages: List<String>, httpStatusCode: Int?) {
// Erros
}
}
Observações:
- Apenas transações do mesmo dia podem ser canceladas/estornadas;
- Apenas transações com status
PAIDpodem ser canceladas/estornadas;- A transação precisa existir na base local do dispositivo;
- O cancelamento precisa estar habilitado para o estabelecimento. Caso contrário, o
onErroré chamado com a mensagem "Permissão para cancelar a transação negada.";- Após o cancelamento, a transação local passa a ter o status
REFUNDED.
4) Listagem de transações (local)
Lista as transações executadas no dispositivo, ordenadas da mais recente para a mais antiga. O onApproved do ListTransactionsListener retorna uma Lista de TransactionStoreModel. No momento, nenhuma opção de filtros é oferecida.
tapOnPhoneSdkInstance.listTransactions(listener)val listener = object : ListTransactionsListener {
override fun onMessage(type: String, message: String) {}
override fun onApproved(result: List<TransactionStoreModel>) {
// Transações locais
}
override fun onError(code: String, messages: List<String>, httpStatusCode: Int?) {}
}TransactionStoreModel:
data class TransactionStoreModel(
val paymentMethod: TransactionPaymentMethodModel, // DEBIT, CREDIT_FULL, CREDIT_INSTALLMENT, UNKNOWN
val transactionStatus: TransactionStatusModel, // PAID, REFUNDED
val transactionId: Long,
val gatewayKey: String,
val mid: String,
val cvmMethod: String,
val arqc: String,
val amount: Long,
val netAmount: Long,
val installments: Int,
val installmentAmount: Long,
val ballot: Int,
val authorizationId: String,
val currencyCode: String,
val transactionDate: String,
val transactionDatetime: Long, // epoch em milissegundos
val brand: String,
val cardFirstNumbers: String,
val cardLastDigits: String,
val additionalData: String,
val rrn: String,
val time: String,
val date: String,
val transactionType: String,
val dynamicBankData: String,
val applicationId: String,
val createdAt: Long, // epoch em segundos
val syncedToBackendAt: Long?, // epoch em segundos
val annulmentAt: Long?, // epoch em segundos
)
Histórico localA base local mantém as transações das últimas 72 horas. Transações mais antigas são removidas automaticamente.
5) Obter transação via ID (local)
Obtém os dados de uma transação local através do gatewayKey ou do transactionId dessa transação. O onApproved do GetTransactionListener retorna um item do tipo TransactionStoreModel ou null.
tapOnPhoneSdkInstance.getTransaction(
transactionId: String,
listener: GetTransactionListener
)6) Outras operações
Sobre as operações da TapOnPhoneSdk.
6.1) isDeviceActive(listener: IsDeviceActiveListener)
Retorna se o dispositivo está ativo ou não, no onApproved(result: Boolean).
6.2) deactivateDevice(listener: DeactivateDeviceListener)
Desativa o dispositivo, tirando assim a habilidade do mesmo de fazer transações. Também limpa os dados locais da SDK. Retorna onApproved(true) ao concluir.
6.3) checkDeviceStatus(listener: DeviceStatusListener)
Retorna no onApproved um DeviceStatusModel com informações importantes: se o dispositivo é seguro, se está ativo e se pode usar o Tap On Phone.
data class DeviceStatusModel(
val canUseTapPhone: Boolean,
val isSecure: Boolean,
val isActivated: Boolean
)6.4) getActiveEstablishmentDetails(listener: ActiveEstablishmentDetailsListener)
Obtém dados do estabelecimento ativo para receber vendas no Tap On Phone. Retorna no onApproved um EstablishmentModel, ou null se o dispositivo não estiver ativo.
data class EstablishmentModel(
val document: String,
val firstName: String,
val lastName: String?,
val gatewayKey: String?,
val softDescriptor: String,
val phoneNumber: String,
val mcc: String,
val merchantId: String,
val address: AddressModel,
val limits: LimitsModel?
)6.5) isNFCSupported(): Boolean
Retorna se o dispositivo possui NFC.
6.6) isNFCEnabled(): Boolean
Retorna se o NFC está ativo.
6.7) goToNfcSetting(): Boolean
Abre as configurações de NFC do dispositivo. Retorna true se a tela de configurações foi aberta e false caso contrário.
6.8) isMockCardTransactionsEnabled(): Boolean
Indica se transações de testes estão mockadas (simuladas) ou em teste real. Como são necessários cartões de testes da certificadora, em debug, todas as transações são mockadas.
Transações mockadasCom transações mockadas, ainda é necessário aproximar um cartão (qualquer cartão). O resultado é definido pelo valor:
- Valor par (ex.:
amount = 1000): transação aprovada;- Valor ímpar (ex.:
amount = 1001): transação recusada, com códigoREJECTED_TRANSACTION.Transações aprovadas no modo mockado também podem ser canceladas pelo
nullifyTransaction.
7) Códigos de erro
Códigos retornados no parâmetro code do onError:
| Código | Descrição |
|---|---|
LOGON_NOT_PERFORMED | Dispositivo não ativado ou ativação expirada/inválida. Chame activateDevice novamente. |
ACTIVATION_ERROR | Falha ao ativar o dispositivo. |
DEACTIVATION_ERROR | Falha ao desativar o dispositivo. |
INVALID_VALUE | Parâmetro inválido (ex.: código de ativação com menos de 8 caracteres). |
INVALID_TRANSACTION | Transação inválida (tipo não suportado, operação cancelada pelo usuário, estorno não permitido etc.). |
EMPTY_TRANSACTION | Transação não encontrada na base local. |
REJECTED_TRANSACTION | Transação recusada. |
INTERNAL_ERROR | Erro interno, tempo expirado ou operação já em andamento. |
Além desses, o code pode trazer os códigos de erro retornados pelo provedor Tap On Phone. O parâmetro messages traz a descrição do erro e httpStatusCode vem preenchido quando o erro é de uma chamada de API.
Updated about 2 hours ago