SDK Android
Instale o SDK Android da DEUNA e integre fluxos de modal, embutido, carteira, voucher e próxima etapa.
Nesta página
- Requisitos
- Instalação
- Inicialização
- Abrir widget de pagamento
- Experiências disponíveis
- Incorpore um widget
- Filtrar e configurar métodos de pagamento
- Estilização dinâmica e atualização do pedido
- Armazenamento de Pagamentos e Pagamento com Clique
- Google Pay nativo
- Continue uma ação pendente
- Abra um cupom
- Dados do dispositivo e fingerprinting antifraude
- Referência do ciclo de vida e callbacks
- Exemplos e código-fonte oficiais
Requisitos#
Para integrar o DEUNA Android SDK, certifique-se de que seu projeto atenda aos seguintes requisitos:
- Versão mínima do SDK:
minSdkVersion 24ou superior (Android API 24+) - Android Gradle Plugin (AGP): Versão 8.5.1 ou superior (necessária para suporte ao tamanho de página de 16 KB do Android)
- Linguagem de programação: Kotlin ou Java
- Credenciais da DEUNA: Conta ativa e credenciais válidas (entre em contato com support@deuna.com se você tiver atrasos para obter credenciais)
Instalação#
1. Adicione o repositório JitPack
Adicione o repositório JitPack dentro do dependencyResolutionManagement no seu settings.gradle.kts (ou settings.gradle):
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven(url = "https://jitpack.io")
}
}dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}Se seu projeto não usar dependencyResolutionManagement, adicione o repositório no arquivo raiz build.gradle:
allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}2. Configure o build.gradle e as dependências
Certifique-se de que seu minSdk seja 24 ou superior, e adicione a dependência do SDK DEUNA:
android {
defaultConfig {
minSdk = 24
}
}
dependencies {
implementation("com.github.deuna-developers:deuna-sdk-android:2.12.7")
}android {
defaultConfig {
minSdk 24
}
}
dependencies {
implementation 'com.github.deuna-developers:deuna-sdk-android:2.12.7'
}Inicialização#
import com.deuna.maven.DeunaSDK
import com.deuna.maven.shared.EnvironmentVocê pode inicializar o SDK de duas maneiras, dependendo da arquitetura do seu aplicativo:
Instância compartilhada global
Inicialize uma vez durante a inicialização do aplicativo (por exemplo, no seu Application.onCreate):
DeunaSDK.initialize(
environment = Environment.SANDBOX, // Environment.SANDBOX or Environment.PRODUCTION
publicApiKey = "YOUR_PUBLIC_API_KEY"
)
val deunaSDK = DeunaSDK.sharedInstância de fluxo ou tela
Crie uma instância para uma tela de checkout específica ou ViewModel:
val deunaSDK = DeunaSDK(
environment = Environment.SANDBOX,
publicApiKey = "YOUR_PUBLIC_API_KEY"
)Abrir widget de pagamento#
O Widget de Pagamento oferece vários métodos de pagamento aos clientes:
- Cartões de crédito e débito: Visa, Mastercard, American Express e cartões co-branded.
- Métodos de pagamento alternativos (APMs): OXXO, KueskiPay, Aplazo, Daviplata, Nequi e mais.
- Carteiras digitais: Google Pay e PayPal.
Exibir em uma caixa de diálogo
Para apresentar o widget de pagamento em uma DialogFragment, chame initPaymentWidget passando uma Activity Context:
import com.deuna.maven.initPaymentWidget
import com.deuna.maven.widgets.payment_widget.PaymentWidgetCallbacks
import com.deuna.maven.payments.PaymentsError
deunaSDK.initPaymentWidget(
context = this, // Activity context
orderToken = "YOUR_ORDER_TOKEN",
callbacks = PaymentWidgetCallbacks().apply {
onSuccess = { order ->
deunaSDK.close() // Close the DialogFragment
// YOUR CODE HERE: Handle successful payment (e.g. navigate to confirmation)
}
onError = { error ->
// Error handling
when (error.type) {
PaymentsError.Type.INITIALIZATION_FAILED -> {
deunaSDK.close()
// YOUR CODE HERE: Handle initialization failure (e.g. show alert or fallback)
}
PaymentsError.Type.PAYMENT_ERROR -> {
// YOUR CODE HERE: Handle payment processing failure (e.g. prompt retry)
}
else -> {}
}
}
onClosed = { action ->
// Widget closed: action == CloseAction.USER_ACTION or CloseAction.SYSTEM_ACTION
// YOUR CODE HERE: Handle dialog dismissal
}
onCardBinDetected = { metadata, refetchOrder ->
if (metadata != null) {
// YOUR CODE HERE: Handle card brand or BIN detection (e.g. apply discounts)
}
}
onInstallmentSelected = { metadata, refetchOrder ->
// YOUR CODE HERE: Handle installment plan selection
}
onPaymentProcessing = {
// YOUR CODE HERE: Payment processing started (e.g. disable UI buttons)
}
onEventDispatch = { event, payload ->
// YOUR CODE HERE: Track analytics event
}
},
userToken = "YOUR_USER_TOKEN", // optional
styleFile = "YOUR_STYLE_FILE_UUID", // optional
language = "en" // optional: "es", "en", "pt"
)Referência de Parâmetros
| Parâmetro | Tipo | Caixa de diálogo | Embutido | Descrição |
|---|---|---|---|---|
context | Context | ✅ | ❌ | Obrigatório para caixa de diálogo. Contexto de Activity que fornece recursos de UI e token de janela. |
orderToken | String | ✅ | ✅ | Obrigatório. Token único para o pedido criado via API DEUNA. Importante: Não defina um redirect_url na criação do pedido se desejar que o onSuccess execute no aplicativo. |
callbacks | PaymentWidgetCallbacks | ✅ | ✅ | Obrigatório. Ouvintes de eventos (onSuccess, onError, onClosed, onCardBinDetected, onInstallmentSelected, onPaymentProcessing, onEventDispatch). |
userToken | String? | ✅ | ✅ | Opcional. Token de portador DEUNA do cliente. Importante: Para cartões salvos aparecerem, o email vinculado ao userToken deve corresponder ao billing_address.email da criação do pedido. |
styleFile | String? | ✅ | ✅ | Opcional. UUID fornecido pela DEUNA para aplicar personalização de tema (cores, tipografia, logo). |
paymentMethods | List<Map<String, Any>>? | ✅ | ✅ | Opcional. Lista de método de pagamento único para fluxo de formulários diretos (ex. listOf(mapOf("paymentMethod" to "bnpl", "processors" to listOf("kueski")))). |
language | String? | ✅ | ✅ | Opcional. Código de idioma ("es", "en", "pt"). Substitui a configuração padrão do lojista. |
behavior | WidgetBehavior? | ✅ | ✅ | Opcional. Personalização de fluxo, como WidgetBehavior(paymentMethods = mapOf("flowType" to "twoStep")) para PayPal, ou Pagamentos Divididos splitPayments. |
fraudCredentials | Map<String, Any>? | ✅ | ✅ | Opcional. Credenciais do provedor antifraude (ex. mapOf("RISKIFIED" to mapOf("storeDomain" to "example.com"))). |
domain | String? | ✅ | ✅ | Opcional. Substitui o host base padrão (https://pay.deuna.io). |
hidePayButton | Boolean | ❌ | ✅ | Opcional. Oculta o botão de pagamento integrado no modo incorporado quando seu aplicativo renderiza um botão nativo. |
Experiências disponíveis#
| Experiência | Método | Tipo de configuração | Entrada importante |
|---|---|---|---|
| Widget de pagamento | initPaymentWidget(...) | PaymentWidgetConfiguration | context, orderToken, PaymentWidgetCallbacks |
| Cofre de Pagamentos | initElements(...) | ElementsWidgetConfiguration | context, ElementsCallbacks; types pode ser omitido |
| Clique para pagar | initElements(...) | ElementsWidgetConfiguration | types = listOf(mapOf("name" to "click_to_pay")) |
| Próxima Ação | initNextAction(...) | NextActionWidgetConfiguration | context, orderToken, NextActionCallbacks |
| Voucher | initVoucherWidget(...) | VoucherWidgetConfiguration | context, orderToken, VoucherCallbacks |
Todos os métodos modais aceitam entradas opcionais de idioma, fraude e domínio, quando suportados. Não substitua domain a menos que a DEUNA atribua um host dedicado a você.
Incorpore um widget#
Para exibir o widget incorporado dentro do seu aplicativo com Jetpack Compose, use AndroidView e DeunaWidget.
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.deuna.maven.DeunaSDK
import com.deuna.maven.web_views.deuna.DeunaWidget
import com.deuna.maven.web_views.deuna.extensions.build
import com.deuna.maven.widgets.configuration.PaymentWidgetConfiguration
import com.deuna.maven.widgets.payment_widget.PaymentWidgetCallbacks
@Composable
fun EmbeddedCheckoutScreen(
deunaSDK: DeunaSDK,
orderToken: String,
userToken: String? = null,
) {
// Retain the Deuna WebView instance across recompositions
val deunaWidget = remember { mutableStateOf<DeunaWidget?>(null) }
Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
Box(modifier = Modifier.fillMaxWidth().weight(1f)) {
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
DeunaWidget(context).apply {
this.widgetConfiguration = PaymentWidgetConfiguration(
sdkInstance = deunaSDK,
orderToken = orderToken,
userToken = userToken,
callbacks = PaymentWidgetCallbacks().apply {
onSuccess = { order ->
// YOUR CODE HERE: Handle successful payment
}
onError = { error ->
// YOUR CODE HERE: Handle payment error
}
onEventDispatch = { event, payload ->
// YOUR CODE HERE: Track analytics event
}
}
)
this.build() // Render the DEUNA widget
deunaWidget.value = this
}
}
)
}
}
// Explicitly clean up WebView resources when composable leaves composition
DisposableEffect(Unit) {
onDispose {
deunaWidget.value?.destroy()
}
}
}Redimensionamento automático e manipulação do teclado
Quando você passa autoResizeConfig = AutoResizeConfig(initialHeightDp = 100), o widget alterna para o modo de redimensionamento automático: ele cresce e encolhe dinamicamente para corresponder à altura do conteúdo do WebView, tornando-o ideal para incorporação dentro de um contêiner rolável.
- Configuração do manifesto: Certifique-se de que sua Activity de checkout está configurada com
adjustResizeemAndroidManifest.xml:
<activity
android:name=".CheckoutActivity"
android:windowSoftInputMode="adjustResize" />- Integração de rolagem no Compose: Coloque
DeunaWidgetdentro de um contêiner de rolagem vertical e conectesetOnScrollByCallbackao ComposeScrollState:
@Composable
fun ScrollableCheckoutScreen(
deunaSDK: DeunaSDK,
widgetConfig: PaymentWidgetConfiguration,
) {
val scrollState = rememberScrollState()
val coroutineScope = rememberCoroutineScope()
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(scrollState)
) {
// Content above widget...
AndroidView(
modifier = Modifier.fillMaxWidth(),
factory = { context ->
DeunaWidget(context).apply {
this.widgetConfiguration = widgetConfig
this.build()
}
},
update = { widget ->
// Wire the SDK scroll request to Compose ScrollState
widget.setOnScrollByCallback { amountPx ->
coroutineScope.launch {
scrollState.animateScrollBy(amountPx)
}
}
}
)
// Content below widget...
}
}Botão de pagamento personalizado (hidePayButton)
Se seu aplicativo renderiza seu próprio botão nativo fora do widget, passe hidePayButton = true e manipule o envio programaticamente usando isValid e submit:
PaymentWidgetConfiguration(
sdkInstance = deunaSDK,
orderToken = orderToken,
hidePayButton = true,
callbacks = callbacks
)
// When the user taps your custom native pay button:
deunaWidget.value?.isValid { isValid ->
if (isValid) {
deunaWidget.value?.submit { result ->
// result.status: "success" | "error"
// result.message: Detailed message
}
}
}| Método | Descrição | Valor de Retorno |
|---|---|---|
deunaWidget.isValid { valid -> ... } | Valida a entrada do usuário no formulário de pagamento ativo. | Boolean |
deunaWidget.submit { result -> ... } | Envia o pagamento equivalente a clicar no botão do widget. | SubmitResult (status: "success" ou status: "error") |
Filtrar e configurar métodos de pagamento#
Fluxo de formulários diretos (paymentMethods)
As arquiteturas de checkout da DEUNA suportam a abertura direta em um formulário de pagamento individual — um padrão conhecido como fluxo de formulários.
Embora paymentMethods seja tipado como uma lista, os mecanismos de checkout internos atualmente suportam apenas um elemento nesta lista. Fornecer um único método de pagamento abre o widget diretamente no formulário desse método (por exemplo, Kueski Pay BNPL), ignorando o seletor de métodos.
deunaSDK.initPaymentWidget(
context = this,
orderToken = "YOUR_ORDER_TOKEN",
callbacks = callbacks,
paymentMethods = listOf(
mapOf(
"paymentMethod" to "bnpl",
"processors" to listOf("kueski")
)
)
)Resolução de prioridade de configuração
| Prioridade | Fonte | Comportamento |
|---|---|---|
| 1 (Mais alta) | paymentMethods em .initPaymentWidget() | Fluxo de formulários diretos: Abre imediatamente no formulário do método de pagamento único especificado (ex.: Kueski), contornando o seletor de método. |
| 2 | include_payment_options na criação do pedido | Seleção de múltiplos métodos: Exibe apenas os métodos de pagamento especificados durante a criação do pedido que estão ativos na sua conta. |
| 3 (Fallback) | Configuração no nível do merchant (/payment-methods) | Seletor completo: Se omitido tanto na chamada do SDK quanto no payload do pedido, exibe todos os métodos de pagamento ativos configurados para sua conta de merchant. |
Configurações do PayPal
Tipo de Fluxo (flowType)
deunaSDK.initPaymentWidget(
context = this,
orderToken = orderToken,
behavior = WidgetBehavior(
paymentMethods = mapOf(
"flowType" to "twoStep" // "twoStep" (summary first) or "singleStep" (direct)
)
)
)Compra Automática (express)
Quando os clientes já autorizaram pagamentos rápidos com o PayPal anteriormente, habilite o processamento imediato:
deunaSDK.initPaymentWidget(
context = this,
orderToken = orderToken,
callbacks = callbacks,
paymentMethods = listOf(
mapOf(
"paymentMethod" to "wallet",
"processors" to listOf("paypal_wallet"),
"configuration" to mapOf("express" to true)
)
)
)Pagamentos divididos com múltiplos cartões
deunaSDK.initPaymentWidget(
context = this,
orderToken = orderToken,
behavior = WidgetBehavior(
paymentMethods = mapOf(
"creditCard" to mapOf(
"splitPayments" to mapOf(
"maxCards" to 2 // Maximum number of cards allowed
)
)
)
)
)Estilização dinâmica e atualização do pedido#
Personalize a aparência dinamicamente (setCustomStyle)
Atualize os estilos do widget dinamicamente (por exemplo, adaptando a marca após detecção do BIN do cartão):
callbacks = PaymentWidgetCallbacks().apply {
onCardBinDetected = { metadata, _ ->
deunaSDK.setCustomStyle(
data = mapOf(
"theme" to mapOf(
"colors" to mapOf(
"primaryTextColor" to "#023047",
"buttonPrimaryFill" to "#FFB703",
"buttonPrimaryText" to "#000000"
)
)
)
)
}
}Atualize totais do pedido (refetchOrder)
Ao oferecer promoções específicas de franquia (por exemplo, "20% de desconto com Mastercard"), escute onCardBinDetected, atualize o pedido no seu backend e notifique o widget:
callbacks = PaymentWidgetCallbacks().apply {
onCardBinDetected = { metadata, _ ->
val cardBrand = metadata?.get("cardBrand") as? String
if (cardBrand == "Mastercard") {
// 1. Notify backend to apply promo
applyDiscountOnBackend(orderId, "MASTERCARD_20") {
// 2. Refresh widget totals
deunaSDK.refetchOrder { updatedOrder ->
println("Order refreshed with discount: $updatedOrder")
}
}
}
}
}Armazenamento de Pagamentos e Pagamento com Clique#
Payment Vault é um componente das soluções de pagamento da DEUNA que permite salvar cartões com segurança e pagar via Click to Pay sem processar checkouts regulares.
Exibir em uma caixa de diálogo
Para exibir o Card Vault em uma caixa de diálogo modal, chame initElements (omitir types para o Vault padrão):
import com.deuna.maven.initElements
import com.deuna.maven.shared.ElementsCallbacks
import com.deuna.maven.shared.domain.UserInfo
import com.deuna.maven.widgets.elements.ElementsWidgetExperience
deunaSDK.initElements(
context = this,
userToken = "<USER_TOKEN>", // optional if userInfo is provided
userInfo = UserInfo(
firstName = "Esteban", // optional if userToken is provided
lastName = "Posada", // optional if userToken is provided
email = "esteban@deuna.com" // required
),
callbacks = ElementsCallbacks().apply {
onSuccess = { response ->
deunaSDK.close() // Close the Vault widget
// YOUR CODE HERE: Handle card saved successfully
}
onError = { error ->
deunaSDK.close() // Close the widget on error
// YOUR CODE HERE: Handle error
}
onClosed = { action ->
// Widget closed: action == CloseAction.USER_ACTION or CloseAction.SYSTEM_ACTION
// YOUR CODE HERE: Handle widget dismissal
}
onEventDispatch = { type, response ->
// YOUR CODE HERE: Listen to widget events
}
},
orderToken = "YOUR_ORDER_TOKEN", // optional
widgetExperience = ElementsWidgetExperience( // optional
userExperience = ElementsWidgetExperience.UserExperience(
showSavedCardFlow = true, // optional: show card saving toggle
defaultCardFlow = true // optional: show toggle to save as default
)
)
)Exibir incorporado (Jetpack Compose)
import com.deuna.maven.widgets.configuration.ElementsWidgetConfiguration
DeunaWidget(context).apply {
this.widgetConfiguration = ElementsWidgetConfiguration(
sdkInstance = deunaSDK,
orderToken = "YOUR_ORDER_TOKEN",
userInfo = UserInfo(
firstName = "Esteban",
lastName = "Posada",
email = "esteban@deuna.com"
),
callbacks = ElementsCallbacks().apply {
onSuccess = { response ->
// Explicitly release resources or update state
// YOUR CODE HERE: Handle card saved
}
onError = { error ->
// YOUR CODE HERE: Handle error
}
},
autoResizeConfig = AutoResizeConfig(initialHeightDp = 150)
)
this.build()
}Clique para pagar
deunaSDK.initElements(
context = this,
userInfo = UserInfo( // mandatory for Click To Pay
firstName = "Esteban",
lastName = "Posada",
email = "esteban@deuna.com"
),
callbacks = ElementsCallbacks().apply {
onSuccess = { data ->
deunaSDK.close()
// YOUR CODE HERE: Handle Click to Pay success
}
onError = { error ->
deunaSDK.close()
// YOUR CODE HERE: Handle error
}
onClosed = { action ->
// YOUR CODE HERE: Handle widget dismissal
}
},
types = listOf(
mapOf("name" to "click_to_pay")
)
)Referência de Parâmetros
| Parâmetro | Tipo | Caixa de diálogo | Embutido | Descrição |
|---|---|---|---|---|
context | Context | ✅ | ❌ | Obrigatório para caixa de diálogo. Contexto da Activity. |
callbacks | ElementsCallbacks | ✅ | ✅ | Obrigatório. Ouvintes de eventos (onSuccess, onError, onClosed, onEventDispatch). |
userInfo | UserInfo? | ✅ | ✅ | Do cliente firstName, lastNamee email. Obrigatório para Click to Pay. |
userToken | String? | ✅ | ✅ | Opcional. Token de portador da DEUNA. Se passado, omita userInfo. |
types | List<Map<String, Any>>? | ✅ | ✅ | Opcional. Omita para renderizar a experiência padrão do Card Vault. Passe listOf(mapOf("name" to "click_to_pay")) para renderizar o Click to Pay. |
orderToken | String? | ✅ | ✅ | Opcional. Token único do pedido. Os detalhes do cliente podem ser extraídos de billing_address. |
styleFile | String? | ✅ | ✅ | Opcional. UUID de personalização do tema. |
widgetExperience | ElementsWidgetExperience? | ✅ | ✅ | Opcional. showSavedCardFlow (alternância de salvamento de cartão) e defaultCardFlow (alternância de salvar como padrão). |
domain | String? | ✅ | ✅ | Opcional. Substitui o host (https://elements.deuna.com). |
hidePayButton | Boolean | ❌ | ✅ | Opcional. Oculta o botão quando incorporado. Use isValid e submit para botões personalizados. |
Google Pay nativo#
Verifique a configuração do merchant e a capacidade do dispositivo antes de renderizar um botão do Google Pay.
import com.deuna.maven.wallets.GetWalletsAvailableParams
import com.deuna.maven.wallets.WalletProvider
import com.deuna.maven.wallets.getWalletsAvailable
val userInfo = UserInfo(email = "ada@example.com")
val params = GetWalletsAvailableParams(
orderToken = "YOUR_ORDER_TOKEN",
userInfo = userInfo
)
deunaSDK.getWalletsAvailable(
context = this,
params = params
) { wallets, error ->
if (error != null) {
// YOUR CODE HERE: Handle wallet availability check error
return@getWalletsAvailable
}
// Check if Google Pay is available on this device and merchant account
val isGooglePayAvailable = WalletProvider.GOOGLE_PAY in wallets
// YOUR CODE HERE: Update Google Pay button visibility in UI
}Após a verificação de disponibilidade ter sucesso, inicie o Google Pay a partir da ação do botão usando initElements:
deunaSDK.initElements(
context = this,
userInfo = userInfo,
callbacks = ElementsCallbacks().apply {
onSuccess = { data ->
// YOUR CODE HERE: Handle Google Pay authorization success
}
onError = { error ->
// YOUR CODE HERE: Handle Google Pay error
}
onClosed = { action ->
// YOUR CODE HERE: Handle Google Pay sheet dismissal
}
},
types = listOf(
mapOf("name" to "GOOGLE_PAY")
),
orderToken = "YOUR_ORDER_TOKEN"
)Veja Google Pay para inscrição do merchant e configuração de testes.
Continue uma ação pendente#
Utilize o mesmo token de pedido quando a DEUNA informar que o pagamento requer um desafio ou redirecionamento 3DS suportado.
import com.deuna.maven.widgets.next_action.NextActionCallbacks
deunaSDK.initNextAction(
context = this,
orderToken = "YOUR_ORDER_TOKEN",
callbacks = NextActionCallbacks().apply {
onSuccess = { order ->
deunaSDK.close()
// YOUR CODE HERE: Handle 3DS or action completion
}
onError = { error ->
deunaSDK.close()
// YOUR CODE HERE: Handle error
}
onClosed = { action ->
// YOUR CODE HERE: Handle modal dismissal
}
}
)O SDK abre URLs externos suportados e retorna para o widget ativo. Utilize o estado do callback para a interface e o status de pagamento final da DEUNA para o fulfillment.
Abra um cupom#
import com.deuna.maven.widgets.voucher.VoucherCallbacks
deunaSDK.initVoucherWidget(
context = this,
orderToken = "YOUR_ORDER_TOKEN",
callbacks = VoucherCallbacks().apply {
onSuccess = { order ->
// YOUR CODE HERE: Handle voucher instructions display
}
onError = { error ->
// YOUR CODE HERE: Handle error
}
onClosed = { action ->
// YOUR CODE HERE: Handle widget dismissal
}
}
)Dados do dispositivo e fingerprinting antifraude#
O SDK Android da DEUNA usa uma arquitetura modular: ele não agrupa SDKs de fraude de terceiros por padrão. Adicione apenas o(s) provedor(es) específico(s) que você planeja usar.
Provedores Suportados
| Provedor | Dependência Gradle / Posicionamento do AAR | Parâmetros obrigatórios |
|---|---|---|
MERCADOPAGO | implementation("com.mercadolibre.android.device:sdk:4.0.1") | (Nenhuma necessária - passe emptyMap()) |
RISKIFIED | implementation("com.riskified:android-sdk:1.11.0:nogoogle@aar") | storeDomain |
CYBERSOURCE | app/libs/cybersource/*.aar | orgId, merchantId (Opcional: fpServer) |
SIGNIFYD | app/libs/signifyd/*.aar | orgId (Opcional: fpServer) |
ACCERTIFY | app/libs/accertify/*.aar + dependências transitivas | Arquivos de configuração em src/main/assets/ (Opcional: locationConsent, phoneConsent) |
Ativos da Accertify e dependências transitivas
- AAR e dependências: Coloque
inmobile.aareinmobile-common.aaremapp/libs/accertify/, e adicione dependências transitivas:
dependencies {
implementation(fileTree(dir: "libs/accertify", include: ["*.aar"]))
implementation("io.insert-koin:koin-core:3.5.6")
implementation("androidx.biometric:biometric:1.1.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
}- Ativos de Configuração: Coloque dois arquivos dentro de
app/src/main/assets/:server_keys_message_hosted.json: As chaves de criptografia públicas fornecidas pela Accertify.inmobile.properties: Arquivo de configuração com os detalhes do seu merchant:PROPERTIESregisterUrl=YOUR_INMOBILE_ENDPOINT_URL logUrl=YOUR_INMOBILE_ENDPOINT_URL accountGuid=YOUR_ACCOUNT_GUID serverKeysMessage=server_keys_message_hosted.json
Configuração e inicialização antecipada do Mercado Pago
- Adicione o repositório do Mercado Libre em
settings.gradle.kts:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven(url = "https://artifacts.mercadolibre.com/repository/android-releases/")
}
}- Adicione a dependência em
app/build.gradle.kts:
dependencies {
implementation("com.mercadolibre.android.device:sdk:4.0.1")
}- Pré-aquecimento de fingerprinting antecipado: O Mercado Pago requer até 3,5 segundos para realizar o perfilamento de hardware. Chame
initializeFraudProvidersemApplication.onCreateouMainActivity.onCreate:
DeunaSDK.initializeFraudProviders(
context = applicationContext,
params = mapOf(
"MERCADOPAGO" to emptyMap<String, Any>()
),
onSuccess = {
// Fingerprint collected and ready in background
},
onError = { error ->
// Handle initialization error
}
)Chamada direta via generateFraudId
deunaSDK.generateFraudId(
context = this,
params = mapOf(
"RISKIFIED" to mapOf(
"storeDomain" to "yourdomain.com"
),
"ACCERTIFY" to mapOf(
"locationConsent" to true,
"phoneConsent" to false
),
"MERCADOPAGO" to emptyMap()
)
) { fraudId ->
// fraudId is a Base64-encoded JSON string, or null if failed
if (fraudId != null) {
println("Base64 Fraud ID: $fraudId")
}
}Passe fraudCredentials diretamente para os widgets
Ao usar widgets da DEUNA, passe suas credenciais diretamente via fraudCredentials. O SDK gera o identificador internamente no momento da compra:
PaymentWidgetConfiguration(
sdkInstance = deunaSDK,
orderToken = "YOUR_ORDER_TOKEN",
callbacks = callbacks,
fraudCredentials = mapOf(
"RISKIFIED" to mapOf(
"storeDomain" to "yourdomain.com"
),
"MERCADOPAGO" to emptyMap()
)
)Notas de comportamento
- Sem inchaço e seguro contra falhas: Se um provedor estiver incluído nos parâmetros mas sua dependência nativa não foi vinculada, o SDK o ignora com segurança sem travar.
- Execução paralela: Todos os provedores solicitados realizam perfilamento simultaneamente em threads em segundo plano.
- Comportamento de fallback: Se nenhum provedor válido estiver configurado ou disponível no dispositivo,
generateFraudIdresolve paranull.
Referência do ciclo de vida e callbacks#
| Callback / Método | Caixa de diálogo | Embutido | Descrição |
|---|---|---|---|
onSuccess | ✅ | ✅ | Operação de pagamento ou cofre de cartão concluída com sucesso. Recebe payload de pedido ou credencial. Chame deunaSDK.close() (dialog) ou destroy() (embedded). |
onError | ✅ | ✅ | Erro ocorrido durante a inicialização ou processamento do pagamento. Recebe PaymentsError ou ElementsError. |
onClosed | ✅ | ❌ | Dialog fechado. Recebe CloseAction.USER_ACTION (fechado manualmente) ou CloseAction.SYSTEM_ACTION (fechado pelo cliente) ou close()). |
onPaymentProcessing | ✅ | ✅ | Acionado quando o cliente toca em pagar e o processamento do pagamento começa. Use para desabilitar botões e mostrar indicadores de progresso. |
onCardBinDetected | ✅ | ✅ | Acionado quando um BIN de cartão é detectado ou limpo (null Acionado quando um BIN de cartão é detectado ou limpo (retorna |
onInstallmentSelected | ✅ | ✅ | Acionado quando o cliente seleciona parcelas diferidas (null Acionado quando o cliente seleciona um plano de parcelamento (retorna |
onEventDispatch | ✅ | ✅ | Acionado quando o cliente solicita o download de voucher ou recibo. CheckoutEvent ou ElementsEvent ocorrências com payloads de dados. |
close() | ✅ | ❌ | Fecha o dialog modal ativo após as abas de URL externas terem sido concluídas. |
destroy() | ❌ | ✅ | Limpa os recursos do WebView quando o composable que o contém é desmontado. |
para registro personalizado e análises.onError)
Inspecione error.type Inspecione o erro
onError = { error ->
when (error.type) {
PaymentsError.Type.INITIALIZATION_FAILED -> {
// Widget failed to load; close dialog and notify user
deunaSDK.close()
}
PaymentsError.Type.PAYMENT_ERROR -> {
// Transaction declined or processor error; prompt retry
}
else -> {}
}
}Exemplos e código-fonte oficiais#
Consulte o arquivo ExploreViewModel.kt para fábricas de configuração e EmbeddedScreen.kt para o gerenciamento do ciclo de vida do WebView.