Instalação do SDK
Guia de instalação do SDK (apossdk) para Android.
Requisitos
Hardware
- Terminal POS Positivo L300, L400 ou OCTA 400
- Conexão de rede (Wi-Fi, dados móveis ou Ethernet)
Software
- Android 8.0 (API 26) ou superior (
minSdk = 26) - Kotlin com coroutines (boa parte da API é
suspend). O SDK é compilado com Kotlin 2.3.10; recomenda-se Kotlin 2.3 ou superior no app - Java 17 (
sourceCompatibility/targetCompatibilityejvmTarget17) compileSdk = 36(a versão com que o SDK é compilado)
Distribuição
O SDK é distribuído como um AAR Fused Library — um único artefato que combina o módulo :apossdk com as bibliotecas de hardware da Positivo. O arquivo AAR é disponibilizado por e-mail; após recebê-lo, publique-o no seu repositório Maven local conforme o guia abaixo.
São dois artefatos, um por ambiente. A coordenada escolhe ao mesmo tempo os endpoints e o certificado mTLS:
| Artefato | Ambiente | Observação |
|---|---|---|
com.tupifintech:apossdk-release-prod | Produção | Sem POS simulado |
com.tupifintech:apossdk-debug-staging | Homologação (staging) | Inclui PosPinpad.createFake(...), um POS simulado para testes sem hardware |
Maven local
Publique o SDK no seu repositório Maven local a partir do projeto do SDK:
./gradlew publishToMavenLocal
Configure o mavenLocal() no settings.gradle.kts do seu app, antes dos demais repositórios:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenLocal() // 👈 antes de google()/mavenCentral()
google()
mavenCentral()
}
}
Adicione a dependência no build.gradle.kts do módulo app:
dependencies {
debugImplementation("com.tupifintech:apossdk-debug-staging:<versao>")
releaseImplementation("com.tupifintech:apossdk-release-prod:<versao>")
}
O repositório local fica em
~/.m2/repository/(macOS/Linux) ouC:\Users\{usuario}\.m2\repository\(Windows). Verifique a publicação comls ~/.m2/repository/com/tupifintech/.
As dependências de terceiros que o SDK usa em runtime (okhttp, Gson, kotlinx-serialization, kotlinx-coroutines, androidx core-ktx, work-runtime e security-crypto) vêm pelo POM do artefato, em escopo runtime, e o Gradle as resolve sozinho.
Usando o .aar como arquivo
Um AAR solto (copiado para libs/ ou via flatDir) não traz POM, então nenhuma dependência é resolvida e o app quebra em runtime com NoClassDefFoundError. Nesse caso, declare as dependências você mesmo:
dependencies {
implementation(files("libs/apossdk-release-prod.aar"))
// O que viria pelo POM se o SDK fosse consumido de um repositório Maven:
implementation("androidx.core:core-ktx:1.17.0")
implementation("androidx.work:work-runtime-ktx:2.11.1")
implementation("androidx.security:security-crypto:1.1.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0")
implementation("com.squareup.okhttp3:okhttp:5.3.2")
implementation("com.google.code.gson:gson:2.13.2")
}
Prefira o Maven local sempre que possível: a lista acima corresponde à versão atual do SDK, e a do POM acompanha cada versão.
Certificado mTLS
O gateway exige mTLS. O certificado cliente vem dentro do SDK, um por ambiente: o apossdk-debug-staging leva o de staging e o apossdk-release-prod o de produção. Na integração normal, o app não faz nada.
Para usar outro certificado (um ambiente fora do padrão, por exemplo), passe um MtlsCertificate ao criar a instância. Veja Configuração.
Permissões
O SDK declara no próprio manifest as permissões de hardware do terminal (com.pos.permission.*: leitores de cartão, impressora, segurança, EMV) e ACCESS_NETWORK_STATE. Elas chegam ao seu app pelo merge de manifest.
Declare no manifest do app a permissão de internet:
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.INTERNET" />
Assinatura do APK
As permissões com.pos.permission.* só são concedidas a apps assinados com a chave de plataforma do modelo de terminal. Sem ela, o app instala e abre, mas não acessa o leitor de cartão, a impressora nem o módulo de segurança. A keystore de plataforma de cada modelo é fornecida pela Tupi.
// build.gradle.kts
android {
signingConfigs {
create("platform") {
storeFile = file("<keystore-de-plataforma-do-modelo>.jks")
storePassword = providers.gradleProperty("platform.storePassword").get()
keyAlias = "platform"
keyPassword = providers.gradleProperty("platform.keyPassword").get()
}
}
buildTypes {
debug { signingConfig = signingConfigs.getByName("platform") }
release { signingConfig = signingConfigs.getByName("platform") }
}
}
Não versione a keystore nem as senhas no repositório do app.
Configuração do JVM Target e SDK
android {
compileSdk = 36
defaultConfig {
minSdk = 26
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}
kotlin {
compilerOptions {
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
}
}
Configuração do R8/ProGuard
O SDK usa serialização por reflexão (Gson), proxies dinâmicos e as bibliotecas da Positivo, que o R8 quebraria se renomeasse ou removesse.
Versões posteriores à 1.0.7: o AAR já traz as regras necessárias (consumer rules), aplicadas automaticamente quando o seu app compila com isMinifyEnabled = true. Não é preciso declarar nada. Elas cobrem:
- o SDK (modelos serializados pelo Gson, enums, interfaces públicas e os proxies internos);
- as bibliotecas da Positivo (
br.com.positivo,com.pos.sdk, o serviço de impressãocom.xcheng.printerservice) e o kernel EMV (com.emv), que é chamado por nome a partir do código nativo: sem a regra, a venda por aproximação derruba o app; - o componente de tela secundária da Kozen;
- o
TypeTokendo Gson e os workers do WorkManager usados na fila de pendências.
Versão 1.0.7 e anteriores: o AAR não traz regras. Declare no proguard-rules.pro do seu app:
# Tupi apossdk
-keepattributes Signature,InnerClasses,EnclosingMethod,RuntimeVisibleAnnotations,RuntimeVisibleParameterAnnotations,AnnotationDefault
-keep class com.tupifintech.apossdk.** { *; }
-keep interface com.tupifintech.apossdk.** { *; }
# Gson e WorkManager
-keep class com.google.gson.reflect.TypeToken { *; }
-keep class * extends com.google.gson.reflect.TypeToken
-keep class * extends androidx.work.ListenableWorker {
<init>(android.content.Context, androidx.work.WorkerParameters);
}
# Bibliotecas Positivo, impressora e kernel EMV
-keep class br.com.positivo.** { *; }
-keep class com.pos.sdk.** { *; }
-keep class com.xcheng.printerservice.** { *; }
-keep class com.emv.** { *; }
# Tela secundária (Kozen)
-keep class com.kozen.** { *; }
-dontwarn br.com.positivo.**
-dontwarn com.pos.**
-dontwarn com.xcheng.printerservice.**
-dontwarn com.emv.**
-dontwarn com.kozen.**
Verificação da Instalação
Após sincronizar o projeto, valide que o SDK carrega criando uma instância e consultando o dispositivo:
import com.tupifintech.apossdk.sdk.api.PosPinpad
val posPinpad = PosPinpad.create(this, myCallback)
// A conexão com o pinpad acontece em segundo plano após create
try {
val deviceInfo = posPinpad.getDeviceInfo()
Log.d("YBY", "Terminal: ${deviceInfo.hardwareModel}")
Log.d("YBY", "Serial: ${deviceInfo.serialNo}")
} catch (e: IllegalStateException) {
Log.d("YBY", "Pinpad ainda conectando")
}
Problemas Comuns
SDK não encontrado
- Confirme que
mavenLocal()está configurado antes degoogle()/mavenCentral(). - Verifique se as coordenadas (
apossdk-debug-staging/apossdk-release-prod) e as versões emdependenciescoincidem com as publicadas. - Limpe o cache:
./gradlew cleane./gradlew --refresh-dependencies.
NoClassDefFoundError em runtime
- O SDK foi adicionado como AAR solto. Declare as dependências de terceiros (seção Usando o
.aarcomo arquivo) ou consuma pelo Maven local.
Leitor de cartão ou impressora não respondem
- O APK não foi assinado com a chave de plataforma do modelo do terminal.
Erro de compatibilidade
- Certifique-se de que
minSdké 26 ou superior e que o projeto usa Java 17.
Crash na primeira chamada de rede (sslSocketFactory has not been initialized)
- Sempre obtenha a instância via
PosPinpad.create(context, callback). Ocreate()inicializa oHttpClientcom o socket factory mTLS — usar a implementação diretamente pula essa etapa.