Modelos e Estruturas de Dados
Referência das estruturas públicas do SDK (com.tupifintech.apossdk.sdk.api.model, salvo indicação).
PaymentResult
Resultado de uma tentativa de pagamento/estorno. Retornado por onTransactionCompleted e onRefundCompleted.
data class PaymentResult(
var status: PaymentStatus,
var errorCode: SdkErrorCode? = null,
var displayMessage: String? = null,
val slip: String? = null,
val receipt: TransactionReceipt? = null, // null em DECLINED/ERROR
val requiresCardRemoval: Boolean = false // true se chip inserido (ICC)
) {
enum class PaymentStatus { APPROVED, DECLINED, ERROR }
}
| Campo | Tipo | Descrição |
|---|---|---|
status | PaymentStatus | APPROVED, DECLINED ou ERROR |
errorCode | SdkErrorCode? | Código do erro quando não aprovado |
displayMessage | String? | Mensagem amigável pronta para exibição |
slip | String? | Texto do comprovante para impressão |
receipt | TransactionReceipt? | Dados estruturados (apenas quando aprovado) |
requiresCardRemoval | Boolean | true se o cartão (chip) precisa ser removido |
TransactionReceipt
Comprovante estruturado da transação. Valores monetários em centavos (Long).
data class TransactionReceipt(
val transactionId: String,
val amount: Long,
val feeAmount: Long? = null,
val transactionType: TransactionType,
val paymentMethod: PaymentMethod,
val authCode: String,
val installments: Int? = null,
val installmentValue: Long? = null,
val timestamp: Date = Date(),
val merchantId: String? = null,
val merchantName: String? = null,
val merchantCnpj: String? = null,
val merchantDocument: String,
val merchantAddress: String,
val merchantIdentifier: String? = null, // código EC no adquirente
val cardBrand: String? = null,
val cardLastDigits: String? = null,
val cardFirstDigits: String? = null, // BIN (6 primeiros dígitos)
val cvmMethod: CvmMethod? = null,
val arqc: String? = null,
val aid: String? = null,
val serialNumber: String? = null,
val terminalId: String? = null,
val signature: Boolean? = null,
val cardHolderName: String? = null,
val captureMethod: String? = null, // "CHIP", "CLESS", "TARJA"
val nsuLocal: String? = null, // NSU local do terminal
val originalAmount: Long? = null
)
Enums
PaymentMethod
Serializado para a API conforme o @SerializedName.
enum class PaymentMethod { DEBIT, CREDIT, PIX, CASH }
| Valor | API | Descrição |
|---|---|---|
DEBIT | debit_card | Débito (com PIN) |
CREDIT | credit_card | Crédito (à vista/parcelado) |
PIX | pix | PIX (use createPixPayment) |
CASH | cash | Dinheiro |
TransactionType
enum class TransactionType {
AUTHORIZATION, VOID, PRE_AUTHORIZE, CONFIRM_PRE_AUTHORIZED,
TRANSACTION_CONFIRM, REVERSAL, ADVICE, PIXQR_CODE,
PIX_PAYMENT_STATUS_CHECK, UNKNOWN
}
| Valor | API | Descrição |
|---|---|---|
AUTHORIZATION | authorization | Autorização (débito/crédito) |
VOID | void | Cancelamento/estorno |
PRE_AUTHORIZE | pre_authorization | Pré-autorização (reserva) |
CONFIRM_PRE_AUTHORIZED | capture | Captura de pré-autorização |
TRANSACTION_CONFIRM | confirmation | Confirmação de transação |
REVERSAL | reversal | Reversão |
ADVICE | advice | Advice |
PIXQR_CODE | pix_qr_code_generate | Geração de QR PIX |
PIX_PAYMENT_STATUS_CHECK | pix_payment_status_check | Consulta de status PIX |
UNKNOWN | — | Não mapeado |
CardReadType
Retornado por waitForCard().
enum class CardReadType { CHIP, CONTACTLESS, MAGSTRIPE, UNKNOWN }
CvmMethod
com.tupifintech.apossdk.domain.model.CvmMethod — método de verificação do portador.
enum class CvmMethod(val displayName: String) {
NO_CVM("Sem verificação"),
SIGNATURE("Assinatura"),
ONLINE_PIN("Senha online"),
OFFLINE_PIN_CLEAR("Senha offline"),
OFFLINE_PIN_ENCRYPTED("Senha offline criptografada"),
CONTACTLESS("Aproximação"),
UNKNOWN("Desconhecido")
}
InputCode
Tipo de dado solicitado em onRequestUserInput.
enum class InputCode { CVV, LAST_4_DIGITS }
NotificationType
Categoria da mensagem em onUiNotify.
enum class NotificationType { INFO, ERROR, WAITING_CARD, PROCESSING }
Impressão
PrintAttributes
data class PrintAttributes(
val align: Align = Align.LEFT,
val textSize: Int = 24,
val typeface: Typeface = Typeface.NORMAL,
val marginLeft: Int = 1,
val lineSpace: Int = 10, // mínimo aceito pela Positivo (~2mm)
val weight: Int = 10 // divisão proporcional em printColumns (ignorado em printText)
)
enum class Align(val value: Int) { CENTER(0), LEFT(1), RIGHT(2) }
enum class Typeface(val value: Int) { NORMAL(0), BOLD(1), SERIF(2), ARIAL(3) }
Configuração e Inicialização
TerminalConfigResponse
Personalização do terminal por parceiro, retornada por getTerminalConfig().
data class TerminalConfigResponse(
val partner: PartnerIdentity,
val scope: OrganizationScope,
val registrationSchema: RegistrationSchema? = null,
val dashboardButtons: Map<DashboardFeature, DashboardButtonConfig>? = null,
val legalDocuments: LegalDocuments,
val receiptCustom: ReceiptCustom? = null,
val resourceId: String? = null,
val updatedAt: String? = null
)
data class PartnerIdentity(
val brandName: String, val companyName: String,
val logoUrl: String, val logoPrintUrl: String? = null, val logoNegativeUrl: String? = null,
val supportPhone: String, val website: String,
val primaryColor: String, // #RRGGBB
val uiAlias: String? = null,
val fontFamily: String? = null // "roboto", "inter", "open_sans", "poppins"
)
data class OrganizationScope( // ao menos 1 não-nulo; viram headers nas chamadas
val acquirerId: String? = null, // X-Acquirer-Id
val subAcquirerId: String? = null, // X-Subacquirer-Id
val independentSalesOrganizationId: String? = null // X-Independent-Sales-Organization-Id
)
data class LegalDocuments(
val privacyPolicyUrl: String? = null,
val termsOfUseUrl: String? = null
)
RegistrationSchema
Define os campos da tela de registro. O app renderiza cada campo aplicando máscara/validação conforme type.
data class RegistrationSchema(
val title: String,
val submitLabel: String,
val fields: List<RegistrationSchemaField>
)
data class RegistrationSchemaField(
val id: String, // chave usada no payload de register (ex.: "cnpj", "token")
val type: String, // "EMAIL", "PASSWORD", "CNPJ", "TOKEN", ...
val label: String? = null,
val required: Boolean? = false,
val minLength: Int? = null,
val maxLength: Int? = null
)
DashboardFeature / DashboardButtonConfig
enum class DashboardFeature {
PAYMENT, REFUND, PRE_AUTH, CONFIRM_PRE_AUTH, REPRINT, SALES_HISTORY
}
data class DashboardButtonConfig(
val visible: Boolean = true,
val requiresPassword: Boolean = false
)
ReceiptCustom
data class ReceiptCustom(
val title: String? = null,
val description: String? = null,
val ouvidoriaPhone: String? = null // SAC/Ouvidoria (requisito BACEN)
)
AuthenticationRequest / AuthenticationResponse
data class AuthenticationRequest(val identifier: String, val password: String)
data class AuthenticationResponse(
val user: AuthenticatedUser? = null,
val expiresIn: Int? = null,
val issuedAt: String? = null,
val error: AuthError? = null,
val success: Boolean = (error == null) && (user != null)
)
data class AuthenticatedUser(val id: String, val name: String, val email: String, val role: String)
data class AuthError(val code: String, val message: String, val details: String? = null)
RegistrationResult
data class RegistrationResult(
val token: String? = null,
val refreshToken: String? = null,
val user: AuthenticatedUser? = null,
val terminalId: String? = null,
val merchantId: String? = null,
val merchantName: String? = null,
val acquirerId: String? = null,
val subacquirerId: String? = null,
val independentSalesOrganizationId: String? = null,
val error: AuthError? = null
) {
val success: Boolean get() = error == null && (terminalId != null || token != null)
}
TerminalInitializationRequest / Response
data class TerminalInitializationRequest(val merchantId: String)
data class TerminalInitializationResponse(
val terminalId: String? = null,
val success: Boolean = true,
val merchant: MerchantInfo? = null
)
MerchantInfo
Dados do estabelecimento (header, recibo). accessPassword é sensível — nunca logar.
data class MerchantInfo(
val merchantId: String? = null,
val name: String? = null, val corporateName: String? = null,
val taxId: String? = null, val personType: String? = null, val mcc: String? = null,
val address: String? = null, val city: String? = null, val state: String? = null,
val postalCode: String? = null, val phone: String? = null,
val accessPassword: String? = null
)
DeviceInfo
data class DeviceInfo(
val manufacturer: String,
val hardwareModel: String,
val firmwareVersion: String,
val applicationVersion: String,
val specificationVersion: String,
val serialNo: String,
val deviceInterfaces: DeviceInterfacesInfo,
val ctlsVersion: String, val masterCtlsVersion: String, val visaCtlsVersion: String,
val amexCtlsVersion: String, val discoverCtlsVersion: String,
val jcbCtlsVersion: String, val unionPayCtlsVersion: String,
val soVersion: String,
val acquirerName: String, val acquirerVersion: String, val acquirerProprietaryInfo: String
) {
data class DeviceInterfacesInfo(
val hasCtlsInterface: Boolean,
val hasChipInterface: Boolean,
val hasMagstripeInterface: Boolean
)
}
TablesInfo
data class TablesInfo(val versions: List<TableVersionInfo>, val lastUpdateAtMs: Long?)
data class TableVersionInfo(
val acquirerName: String,
val tableVersion: String,
val keyTableVersion: String? = null,
val normalizedHash: String? = null
)
TransactionLimits
Limites por operação (valores 0 significam "sem limite"). Retornado por getTransactionLimits().
data class TransactionLimits(
val featureCode: Int,
val transactionName: String,
val minTransactionValueCents: Long, val maxTransactionValueCents: Long,
val minInstallments: Int, val maxInstallments: Int,
val minInstallmentValueCents: Long, val maxInstallmentValueCents: Long
)
HealthCheckResult
data class HealthCheckResult(
val isConnected: Boolean,
val hasNetworkConnection: Boolean,
val isApiReachable: Boolean,
val latencyMs: Long?,
val errorMessage: String?
)
PixQrCodeData
data class PixQrCodeData(
val qrCode: String,
val transactionId: String,
val expiresInSeconds: Int? = null
)
Consulta de Transações
QueryFilterBuilder
Builder para os filtros de getTransactionSummaries(). Padrão da API: <campo>_<operador>=<valor> (para EQ, apenas <campo>=<valor>).
val filters = QueryFilterBuilder()
.pagination(offset = 0, limit = 20, preloads = true)
.add(FilterField.STATUS, FilterOperator.EQ, "approved")
.add(FilterField.CREATED_AT, FilterOperator.GE, "2025-01-01")
.addIn(FilterField.CARD_BRAND, listOf("visa", "mastercard"))
Operadores (FilterOperator): EQ, NE, GT, LT, GE, LE, LK, IN.
Campos (FilterField): STATUS, PAYMENT_METHOD, ACQUIRER, CREATED_AT, UPDATED_AT, CARD_BRAND, CARD_FIRST_DIGITS, CARD_LAST_DIGITS, TYPE, SYSTEM_TRACE_AUDIT_NUMBER, AUTHORIZATION_CODE, GATEWAY_TRANSACTION_ID.
TransactionSummaryResponse / TransactionSummary
data class TransactionSummaryResponse(
val metadata: Metadata, // offset, limit
val links: Links?, // first
val data: List<TransactionSummary>
)
data class TransactionSummary(
val id: String,
val acquirerId: String?,
val createdAt: String, val updatedAt: String?,
val gatewayTransactionId: String?,
val acquirer: String?, val currency: String?,
val paymentMethod: PaymentMethod,
val status: String, // "approved", "pre_approved", "refunded", "voided", "pending", ...
val amount: Amount, // Amount(amount, scale)
val installments: Int? = null,
val installmentsInterest: Boolean? = null,
val card: TransactionCard?,
val payer: Payer? = null, // PIX
val endToEndId: String? = null,
val cycles: List<TransactionCycle>? = null, // com preloads=true
val transactionType: TransactionType? = null
)
TransactionSummary expõe helpers úteis: cardBrand, cardLastDigits, amountInCents, amountAsDouble, isApproved, isPreApproved, isRefunded, nsu, authorizationCode, etc.
data class Amount(val amount: Long, val scale: Int) {
fun toDouble(): Double // Amount(15000, 2).toDouble() == 150.0
fun toCents(): Long
}
data class TransactionCard(
val brand: String?, val firstDigits: String?, val lastDigits: String?,
val holderName: String?, val expirationMonth: Int?, val expirationYear: Int?
)
data class TransactionCycle(
val type: String?, val authorizationCode: String?,
val systemTraceAuditNumber: String?, val retrievalReferenceNumber: String?,
val processedAt: String?
)
data class Payer(val name: String?, val taxId: String?, val bankName: String?)
SdkErrorCode
com.tupifintech.apossdk.sdk.model.SdkErrorCode — catálogo de erros recebido em onAppError(error, message) e PaymentResult.errorCode. Cada valor tem um code: Int.
Erros do SDK (customizados)
| Código | Valor | Descrição |
|---|---|---|
UNKNOWN_ERROR | -1 | Erro desconhecido |
NO_CONTEXT | 1001 | Contexto de transação ausente |
TERMINAL_NOT_INITIALIZED | 1002 | Terminal não inicializado |
TERMINAL_INITIALIZATION_FAILED | 1003 | Falha na inicialização |
INVALID_CARD_ENTRYMODE | 1004 | Modo de entrada de cartão inválido |
MAGNETIC_STRIPE_WITH_CHIP | 1005 | Tarja usada em cartão com chip |
PRODUCT_NOT_FOUND | 1006 | Produto/operação não encontrado |
INVALID_SELECTION | 1007 | Seleção inválida |
INVALID_LAST_DIGITS | 1008 | Últimos 4 dígitos inválidos |
INVALID_CVV | 1009 | CVV inválido |
ENCRYPTION_ERROR | 1010 | Erro de criptografia |
PIN_ERROR | 1011 | Erro de PIN |
GO_ON_CHIP_DENIED | 1012 | EMV (go on chip) negado |
FINISH_CHIP_DENIED | 1013 | EMV (finish chip) negado |
CACHE_INVALID | 1014 | Cache inválido |
GATEWAY_UNAUTHORIZED | 1015 | Gateway: não autorizado |
GATEWAY_INVALID_REQUEST | 1016 | Gateway: requisição inválida |
GATEWAY_NETWORK_ERROR | 1017 | Gateway: erro de rede |
NO_PRE_AUTHORIZATIONS | 1018 | Nenhuma pré-autorização |
CONNECTION_FAILED | 1019 | Falha ao conectar ao pinpad |
DISCONNECTION_FAILED | 1020 | Falha ao desconectar |
NO_TRANSACTIONS_FOUND | 1021 | Nenhuma transação encontrada |
PRE_AUTH_NOT_FOUND_FOR_CARD | 1022 | Pré-autorização não encontrada para o cartão |
GATEWAY_TIMEOUT | 1023 | Gateway: timeout |
TRANSACTION_UNDONE | 1024 | Transação desfeita |
PIN_BLOCKED | 1025 | PIN offline bloqueado |
AMOUNT_BELOW_MINIMUM | 1026 | Valor abaixo do mínimo |
AMOUNT_ABOVE_MAXIMUM | 1027 | Valor acima do máximo |
INSTALLMENTS_EXCEEDED | 1028 | Parcelas acima do permitido |
INSTALLMENT_VALUE_BELOW_MINIMUM | 1029 | Valor da parcela abaixo do mínimo |
CONTACTLESS_LIMIT_EXCEEDED | 1030 | Limite contactless excedido |
MAGNETIC_FALLBACK_NOT_ALLOWED | 1031 | Fallback para tarja não permitido |
INVALID_PAN_LENGTH | 1032 | Tamanho de PAN inválido |
INVALID_TRACK_DATA | 1033 | Track2 vazia/inválida |
Há também os códigos da lib SmartPOS da Positivo (prefixo
PP_*, ex.:PP_TIMEOUT(12),PP_CANCEL(13),PP_CARDBLOCKED(63),PP_ERRPIN(42)), úteis para diagnóstico de hardware/EMV.
Próximos Passos
- Exemplos — exemplos práticos de uso
- API PosPinpad — referência da API