Implementing the use of the SDK
1
data class TerminalConfigEntity(
val companyDocument: String?, // O número do CNPJ (Cadastro Nacional de Pessoa Jurídica) da empresa. - Contém o número do CNPJ da empresa.
val companyName: String?, // O nome da empresa.
val merchantId: UUID?, // O identificador único do comerciante, fornecido pela equipe FirstTech.
val terminalNumber: String?, // O número único atribuído ao terminal, fornecido pela equipe FirstTech.
val clientId: String?, // O ID do Cliente usado para autenticação, fornecido pela equipe FirstTech.
val clientSecret: String?, // O Client Secret usado para autenticação, fornecido pela equipe FirstTech.
val sdkScope: String?, // O escopo necessário para autenticação do SDK, fornecido pela equipe FirstTech e enviado pelo consumidor deste SDK.
val sdkClientId: String?, // O ID do Cliente para autenticação do SDK, fornecido pela equipe FirstTech e enviado pelo consumidor deste SDK.
val sdkClientSecret: String?, // O Client Secret para autenticação do SDK, fornecido pela equipe FirstTech e enviado pelo consumidor deste SDK.
val packageName: String?, // O nome do pacote da aplicação do cliente, enviado pelo consumidor deste SDK.O Nome do Pacote é usado para referência de onde a aplicação do cliente está sendo executada, enviado pelo consumidor deste SDK.
val appVersion: String?, // A versão atual da aplicação do cliente, enviado pelo consumidor deste SDK. - A Versão do Aplicativo é uma informação sobre a versão do aplicativo do cliente atual, enviado pelo consumidor deste SDK.
val sdkOrganization: String? // O nome da organização, enviado pelo consumidor deste SDK.
)
2

3
private val progressDialog by lazy { ProgressDialog(this) } //<- This Android user interface component is used to show a progress dialog box.
private val binding: ActivityMainBinding by lazy { ActivityMainBinding.inflate(layoutInflater) } //<- Define the binding variable as ActivityMainBinding. //<- This is a class automatically generated by Android's View Binding feature.
private val mppProviderViewModel by lazy { MPPPProviderViewModel(application as Application) } //<- ViewModel to manage the data and logic of the user interface.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
setupView()
setupObserver()
askPermission()
getVersionCode()
}4

private fun askPermission() {
val permissionsToRequest = mutableListOf<String>()
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
) {
permissionsToRequest.add(Manifest.permission.ACCESS_FINE_LOCATION)
}
if (permissionsToRequest.isNotEmpty()) {
Log.d("Signal", "Solicitando permissões.")
ActivityCompat.requestPermissions(
this,
permissionsToRequest.toTypedArray(),
ALL_PERMISSIONS_REQUEST_CODE
)
} else {
Log.d("Signal", "Todas as permissões já concedidas.")
}
}5
private fun startPayment() {
mppProviderViewModel.startPaymentFlow( // <- Este é o método que inicia o fluxo de pagamento
TransactionInfoEntity(
operationType, //<- Define o tipo da operação
((binding.etValor.text.toString().toDigits() ?: 0.0) * 100).toLong(), // <- Valor da transação, multiplicado por 100 (para representar centavos)
binding.etInstallments.text.toString().toInt() //<- Número de parcelas //<- Número de parcelas (quando o pagamento é a crédito)
)
)
}

SessionHelper.clearCurrentTerminalSession()import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.Promise
import com.firsttech.taponphone.sdk.v2.utils.DeviceInformationUtils
import com.firsttech.taponphone.sdk.v2.utils.SessionHelper
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import android.util.Log
class DeviceInfoModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
override fun getName(): String = "DeviceInfoModule"
@ReactMethod
fun getDeviceId(promise: Promise) {
try {
val id = DeviceInformationUtils.getDeviceIdentifier(reactApplicationContext)
promise.resolve(id)
} catch (e: Exception) {
promise.reject("ERROR", e.message)
}
}
@ReactMethod
fun getDeviceInfo(promise: Promise) {
CoroutineScope(Dispatchers.Default).launch {
try {
val info = DeviceInformationUtils.getDeviceInfo(reactApplicationContext)
promise.resolve(info)
} catch (e: Exception) {
promise.reject("DEVICE_INFO_ERROR", e.message)
}
}
}
//
fun addListener(eventName: String?) {
// Requerido pelo NativeEventEmitter
}
fun removeListeners(count: Int) {
// Requerido pelo NativeEventEmitter
}
@ReactMethod
fun clearTerminalSession() {
try {
SessionHelper.clearCurrentTerminalSession()
} catch (e: Exception) {
Log.e("TerminalModule", "Erro ao limpar sessão do terminal", e)
}
}
}
import { NativeModules } from 'react-native';
const { DeviceInfoModule } = NativeModules;
export function getDeviceInfo(): Promise<string> {
return DeviceInfoModule.getDeviceInfo();
}
export function clearTerminal(): void {
DeviceInfoModule.clearTerminalSession();
}import { clearTerminal } from '../../native-modules/DeviceInfoModule <BackButtonWrapper
onPress={() => {
clearTerminal();
goBack();
}}
>
<BackButtonArrowLeftVector source={arrowLeftVector} />
</BackButtonWrapper>6
private fun setupObserver() {
mppProviderViewModel.onMessage.observe(this, ::onMessage)
}
private fun onMessage(viewData: MPPViewData?) {
viewData?.let {
when (viewData) {
MPPViewData.TerminalInitializingViewData -> {
showLoadingDialog("Inicializando terminal")
binding.tvMessage.text = "Inicializando terminal"
}
MPPViewData.TerminalInitializingErrorViewData -> {
showFeedbackDialog("Erro ao inicializar terminal")
progressDialog.dismiss()
}
MPPViewData.TerminalInitializingSuccessViewData -> {
progressDialog.dismiss()
binding.tvMessage.text = "Inicialização concluída"
}
is MPPViewData.TerminalPaymentSuccessViewData -> {
enableEditFields(true)
binding.tvMessage.text =
if (viewData.result.isProcessingResultSuccess()) "Pagamento realizado" else "Pagamento recusado"
val metaData = viewData.result.getMetaDataTranslated()
binding.tvLog.text = "" +
"Resultado: ${viewData.result.uiMessage.messageId.sampleUiMessage}" +
createReceipt(metaData)
}
//Mapear todos os cenários de MPPViewData
}
}
}
val metaData = viewData.result.getMetaDataTranslated()
val messageJson = metaData?.receipt?.merchant?.messageJson7

package com.firsttech.taponphone.app.utils
import java.text.NumberFormat
import java.util.Locale
import com.firsttech.taponphone.sdk.v2.models.TransactionCompleted
fun createReceipt(metaDataTranslated: TransactionCompleted.Metadata?):String {
val messageJson = metaDataTranslated?.receipt?.merchant?.messageJson
val parcelas = messageJson?.transaction?.installments?.total ?: 0
val valor = messageJson?.transaction?.amount
return "\n${messageJson?.acquirer}" +
"\n" +
"\nCNPJ: ${messageJson?.businessDocument}" +
"\nTID: ${messageJson?.transactionId}" +
"\n" +
"\n${messageJson?.card?.number}" +
"\n${messageJson?.card?.brand}" +
"\nAID: ${messageJson?.card?.aid}" +
"\n${messageJson?.transaction?.datetime}" +
"\nCV: ${messageJson?.transaction?.stan}" +
"\nValor: ${messageJson?.transaction?.currency} ${valor?.let { it1 -> setCurrencyFormat(it1) }}" +
"\nForma de Pagamento: ${messageJson?.transaction?.paymentMethod}" +
(if(messageJson?.transaction?.paymentMethod.equals("Crédito")){
"\n${if(parcelas==1)"À vista" else "Valor de cada parcela: ${messageJson?.transaction?.currency} ${setCurrencyFormat(messageJson?.transaction?.installments?.value.toString())}" }" +
"\nQuantidade de parcela: ${messageJson?.transaction?.installments?.total}"
}else{
"\n${setTextInstallments(parcelas)}"
}) +
"\nTerm: ${messageJson?.terminalCode}" +
"\n" +
"\nDADOS ORIGINAIS DA VENDA" +
"\nValor: ${messageJson?.transaction?.currency} ${messageJson?.transaction?.amount?.let { it1 ->
setCurrencyFormat(
it1
)
}}" +
"\nTerm: ${messageJson?.terminalCode}" +
"\n${messageJson?.transaction?.messageAuthorizedBy}"
}
private fun setCurrencyFormat(amount:String): String {
val formatCurrency = NumberFormat.getCurrencyInstance(Locale("pt", "BR"))
val amountToDouble = formatCurrency.format(amount.toDouble())
val amountConverted = amountToDouble.replace("R$", "").trim()
return amountConverted
}
private fun setTextInstallments(installements:Int): String {
return if (installements==1) "À vista" else "Parcelado em $installements vezes"
}
"receipt":{
"merchant":{
"message":"Via Loja\n\nCNPJ: 00.595.154/0001-73\nTID: 010000865033\n\n**** **** **** 2029\nMASTERCARD\nAID: A0000000041010\n17/06/25 11:32\nCV: 241393\nValor: R$ 50,00\nForma de pagamento: Crédito\nValor de cada parcela: 5\nQuantidade de parcelas: 10\nTerm: 00000026\n\nDADOS ORIGINAIS DA VENDA\nValor: R$ 50,00\nTerm: 00000026\nTransação autorizada pelo emissor\n",
"messageJson":{
"acquirer":"Via Loja",
"merchant":"First Customer",
"businessDocument":"00.595.154/0001-73",
"transactionId":"010000865033",
"card":{
"number":"**** **** **** 2029",
"brand":"MASTERCARD",
"aid":"A0000000041010"
},
"transaction":{
"amount":50,
"currency":"BRL",
"datetime":"17/06/25 11:32:25",
"stan":"241393",
"installments":{
"value":5,
"total":10
},
"paymentMethod":"Crédito",
"messageAuthorizedBy":"Transação autorizada pelo emissor"
},
"terminalCode":"00000026"
}
},8
is MPPViewData.TerminalPaymentValueBelowMinimunLimitViewData -> {
progressDialog.dismiss()
showFeedbackDialog("O valor do pagamento está abaixo do limite mínimo R$${viewData.minValue}")
binding.tvMessage.text = "O valor do pagamento está abaixo do limite mínimo."
}
} is MPPViewData.TerminalPaymentValueBelowMinimunLimitViewData ->{
sendErrorMessage("O valor do pagamento está abaixo do limite mínimo R$${viewData.minValue}")
}
9
is MPPViewData.PaymentInformationInvalidViewData -> {
showFeedbackDialog("Pagamento com parametros incorretos.")
binding.tvMessage.text = "Revise as condições de pagamento."
} is MPPViewData.PaymentInformationInvalidViewData -> {
sendErrorMessage("Condicoes de pagamento incorretos.")
}Last updated

