Saltar al contenido principal
En esta página

Requisitos#

Para integrar el SDK de Android de DEUNA, asegúrese de que su proyecto cumpla con los siguientes requisitos:

  • Versión mínima del SDK: minSdkVersion 24 o superior (Android API 24+)
  • Android Gradle Plugin (AGP): Versión 8.5.1 o superior (requerido para soporte de tamaño de página de 16 KB de Android)
  • Lenguaje de programación: Kotlin o Java
  • Credenciales de DEUNA: Cuenta activa y credenciales válidas (contacte a support@deuna.com si experimenta demoras para obtener credenciales)

Instalación#

1. Agregue el repositorio JitPack

Agregue el repositorio JitPack dentro del dependencyResolutionManagement bloque en su settings.gradle.kts (o settings.gradle):

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven(url = "https://jitpack.io")
    }
}

Si su proyecto no utiliza dependencyResolutionManagement, agregue el repositorio en el archivo raíz build.gradle:

build.gradleGROOVY
allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}

2. Configure build.gradle y las dependencias

Asegúrese de que su minSdk sea 24 o superior, y agregue la dependencia del SDK de DEUNA:

android {
    defaultConfig {
        minSdk = 24
    }
}

dependencies {
    implementation("com.github.deuna-developers:deuna-sdk-android:2.12.7")
}

Inicialización#

Kotlin
import com.deuna.maven.DeunaSDK
import com.deuna.maven.shared.Environment

Puede inicializar el SDK de dos maneras según la arquitectura de su aplicación:

Instancia global compartida

Inicialice una vez durante el inicio de la aplicación (por ejemplo, en su Application.onCreate):

Kotlin
DeunaSDK.initialize(
    environment = Environment.SANDBOX, // Environment.SANDBOX or Environment.PRODUCTION
    publicApiKey = "YOUR_PUBLIC_API_KEY"
)

val deunaSDK = DeunaSDK.shared

Flujo o instancia de pantalla

Cree una instancia para una pantalla de pago específica o ViewModel:

Kotlin
val deunaSDK = DeunaSDK(
    environment = Environment.SANDBOX,
    publicApiKey = "YOUR_PUBLIC_API_KEY"
)

Abrir widget de pago#

El Widget de Pago ofrece múltiples métodos de pago a los clientes:

  • Tarjetas de crédito y débito: Visa, Mastercard, American Express y tarjetas co-branded.
  • Métodos de pago alternativos (APMs): OXXO, KueskiPay, Aplazo, Daviplata, Nequi y más.
  • Carteras digitales: Google Pay y PayPal.

Mostrar en un cuadro de diálogo

Para presentar el widget de pago en un DialogFragment, llamar initPaymentWidget pasando una Activity Context:

Kotlin
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"
)

Referencia de parámetros

ParámetroTipoCuadro de diálogoIntegradoDescripción
contextContext✅❌Requerido para el cuadro de diálogo. Contexto de Activity que proporciona recursos de UI y token de ventana.
orderTokenString✅✅Requerido. Token único para la orden creada a través de la API de DEUNA.

importante: No defina un redirect_url en la creación del pedido si desea que onSuccess se ejecute dentro de la aplicación.
callbacksPaymentWidgetCallbacks✅✅Requerido. Los oyentes de eventos (onSuccess, onError, onClosed, onCardBinDetected, onInstallmentSelected, onPaymentProcessing, onEventDispatch).
userTokenString?✅✅Opcional. Token de portador (bearer) de DEUNA del cliente.

importante: Para que aparezcan tarjetas guardadas, el correo electrónico vinculado al userToken deben coincidir con billing_address.email de la creación del pedido.
styleFileString?✅✅Opcional. UUID proporcionado por DEUNA para aplicar personalización de marca de tema personalizado (colores, tipografía, logo).
paymentMethodsList<Map<String, Any>>?✅✅Opcional. Lista de método de pago único para flujo de formularios directos (por ejemplo, listOf(mapOf("paymentMethod" to "bnpl", "processors" to listOf("kueski")))).
languageString?✅✅Opcional. Código de idioma ("es", "en", "pt"). Anula la configuración predeterminada del comerciante.
behaviorWidgetBehavior?✅✅Opcional. Personalización del flujo, como WidgetBehavior(paymentMethods = mapOf("flowType" to "twoStep")) para PayPal, o Pagos Divididos splitPayments.
fraudCredentialsMap<String, Any>?✅✅Opcional. Credenciales del proveedor antifraude (por ejemplo, mapOf("RISKIFIED" to mapOf("storeDomain" to "example.com"))).
domainString?✅✅Opcional. Anula el host base predeterminado (https://pay.deuna.io).
hidePayButtonBoolean❌✅Opcional. Oculta el botón de pago integrado en modo embebido cuando su aplicación renderiza un botón nativo.

Experiencias disponibles#

ExperienciaMétodoTipo de configuraciónInformación necesaria
Widget de pagoinitPaymentWidget(...)PaymentWidgetConfigurationcontext, orderToken, PaymentWidgetCallbacks
Caja de PagoinitElements(...)ElementsWidgetConfigurationcontext, ElementsCallbacks; types puede omitirse
Haga clic para pagarinitElements(...)ElementsWidgetConfigurationtypes = listOf(mapOf("name" to "click_to_pay"))
Siguiente AccióninitNextAction(...)NextActionWidgetConfigurationcontext, orderToken, NextActionCallbacks
valeinitVoucherWidget(...)VoucherWidgetConfigurationcontext, orderToken, VoucherCallbacks

Todos los métodos modales aceptan entradas opcionales de idioma, fraude y dominio cuando están admitidas. No anules domain a menos que DEUNA te asigne un host dedicado.

Integrar un widget#

Para mostrar el widget incrustado dentro de tu aplicación con Jetpack Compose, usa AndroidView y DeunaWidget.

Kotlin
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()
        }
    }
}

Redimensionamiento automático y manejo del teclado

Cuando pasas autoResizeConfig = AutoResizeConfig(initialHeightDp = 100), el widget cambia al modo de redimensionamiento automático: crece y se reduce dinámicamente para coincidir con la altura del contenido del WebView, lo que lo hace ideal para incrustar dentro de un contenedor desplazable.

  1. Configuración del manifiesto: Asegúrate de que tu Activity de checkout esté configurada con adjustResize en AndroidManifest.xml:
AndroidManifest.xmlXML
<activity
    android:name=".CheckoutActivity"
    android:windowSoftInputMode="adjustResize" />
  1. Integración con desplazamiento en Compose: Coloca DeunaWidget dentro de un contenedor de desplazamiento vertical y conecta setOnScrollByCallback al Compose ScrollState:
Kotlin
@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ón de pago personalizado (hidePayButton)

Si tu aplicación renderiza su propio botón nativo fuera del widget, pasa hidePayButton = true y maneja el envío de forma programática usando isValid y submit:

Kotlin
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étodoDescripciónValor de retorno
deunaWidget.isValid { valid -> ... }Valida la entrada del usuario en el formulario de pago activo.Boolean
deunaWidget.submit { result -> ... }Envía el pago equivalente a hacer clic en el botón del widget.SubmitResult (status: "success" o status: "error")

Filtrar y configurar métodos de pago#

Flujo de formularios directos (paymentMethods)

Las arquitecturas de checkout de DEUNA admiten lanzarse directamente a un formulario de pago individual, un patrón conocido como flujo de formularios.

Aunque paymentMethods está tipado como una lista, los motores de checkout internos actualmente admiten solo un elemento en esta lista. Proporcionar un único método de pago abre el widget directamente en el formulario de ese método (por ejemplo, Kueski Pay BNPL), omitiendo el selector de métodos.

Kotlin
deunaSDK.initPaymentWidget(
    context = this,
    orderToken = "YOUR_ORDER_TOKEN",
    callbacks = callbacks,
    paymentMethods = listOf(
        mapOf(
            "paymentMethod" to "bnpl",
            "processors" to listOf("kueski")
        )
    )
)

Resolución de prioridad de configuración

PrioridadFuenteComportamiento
1 (Mayor prioridad)paymentMethods en .initPaymentWidget()Flujo de formularios directos: Se abre inmediatamente en el formulario del método de pago único especificado (por ejemplo, Kueski), omitiendo el selector de métodos.
2include_payment_options en la creación de la ordenSelección de múltiples métodos: Muestra solo los métodos de pago especificados durante la creación de la orden que estén activos en tu cuenta.
3 (Respaldo)Configuración a nivel de comerciante (/payment-methods)Selector completo: Si se omite tanto en la llamada al SDK como en el payload de la orden, muestra todos los métodos de pago activos configurados para tu cuenta de comerciante.

Configuraciones de PayPal

Tipo de flujo (flowType)

Kotlin
deunaSDK.initPaymentWidget(
    context = this,
    orderToken = orderToken,
    behavior = WidgetBehavior(
        paymentMethods = mapOf(
            "flowType" to "twoStep" // "twoStep" (summary first) or "singleStep" (direct)
        )
    )
)

Compra automática (express)

Cuando los clientes han autorizado previamente pagos rápidos con PayPal, habilita el procesamiento inmediato:

Kotlin
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)
        )
    )
)

Pagos divididos con múltiples tarjetas

Kotlin
deunaSDK.initPaymentWidget(
    context = this,
    orderToken = orderToken,
    behavior = WidgetBehavior(
        paymentMethods = mapOf(
            "creditCard" to mapOf(
                "splitPayments" to mapOf(
                    "maxCards" to 2 // Maximum number of cards allowed
                )
            )
        )
    )
)

Estilo dinámico y actualización del pedido#

Personaliza la apariencia de forma dinámica (setCustomStyle)

Actualiza los estilos del widget dinámicamente (por ejemplo, adaptando la marca al detectar el BIN de la tarjeta):

Kotlin
callbacks = PaymentWidgetCallbacks().apply {
    onCardBinDetected = { metadata, _ ->
        deunaSDK.setCustomStyle(
            data = mapOf(
                "theme" to mapOf(
                    "colors" to mapOf(
                        "primaryTextColor" to "#023047",
                        "buttonPrimaryFill" to "#FFB703",
                        "buttonPrimaryText" to "#000000"
                    )
                )
            )
        )
    }
}

Actualiza totales del pedido (refetchOrder)

Al ofrecer promociones específicas de franquicia (por ejemplo, "20% de descuento con Mastercard"), escucha a onCardBinDetected, actualice el pedido en su backend y notifique al widget:

Kotlin
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")
                }
            }
        }
    }
}

Almacén de pagos y Pago con un clic#

Payment Vault es un componente de las soluciones de pago DEUNA que permite guardar tarjetas de forma segura y pagar mediante Click to Pay sin procesar pagos regulares.

Mostrar en un cuadro de diálogo

Para mostrar Card Vault en un cuadro de diálogo modal, llame a initElements (omita types para el Vault predeterminado):

Kotlin
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
        )
    )
)

Mostrar incrustado (Jetpack Compose)

Kotlin
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()
}

Haga clic para pagar

Kotlin
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")
    )
)

Referencia de parámetros

ParámetroTipoCuadro de diálogoIntegradoDescripción
contextContext✅❌Requerido para el cuadro de diálogo. Contexto de Activity.
callbacksElementsCallbacks✅✅Requerido. Los oyentes de eventos (onSuccess, onError, onClosed, onEventDispatch).
userInfoUserInfo?✅✅Del cliente firstName, lastNamey email. Requerido para Click to Pay.
userTokenString?✅✅Opcional. Token de portador DEUNA. Si se proporciona, omita userInfo.
typesList<Map<String, Any>>?✅✅Opcional. Omitir para renderizar la experiencia predeterminada de Card Vault. Pasar listOf(mapOf("name" to "click_to_pay")) para renderizar Click to Pay.
orderTokenString?✅✅Opcional. Token de pedido único. Los detalles del cliente se pueden extraer de billing_address.
styleFileString?✅✅Opcional. UUID de personalización de tema.
widgetExperienceElementsWidgetExperience?✅✅Opcional. showSavedCardFlow (alternador de guardado de tarjeta) y defaultCardFlow (alternador de guardar como predeterminado).
domainString?✅✅Opcional. Anula el host (https://elements.deuna.com).
hidePayButtonBoolean❌✅Opcional. Oculta el botón cuando está incrustado. Usar isValid y submit para botones personalizados.

Google Pay nativo#

Verificar la configuración del comerciante y la capacidad del dispositivo antes de renderizar un botón de Google Pay.

Kotlin
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
}

Después de que la verificación de disponibilidad tenga éxito, lanzar Google Pay desde la acción del botón usando initElements:

Kotlin
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"
)

Ver pago de google para la inscripción del comerciante y la configuración de pruebas.

Continúe con una acción pendiente#

Utilice el mismo token de pedido cuando DEUNA informe que el pago requiere un desafío o redirección 3DS compatible.

Kotlin
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
        }
    }
)

El SDK abre las URLs externas compatibles y regresa al widget activo. Utilice el estado de llamada de retorno para la interfaz y el estado de pago final de DEUNA para el cumplimiento.

Abrir un cupón#

Kotlin
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
        }
    }
)

Datos del dispositivo y huella digital para fraude#

El SDK de Android de DEUNA utiliza una arquitectura modular: no incluye SDKs de fraude de terceros por defecto. Solo agregue el(los) proveedor(es) específico(s) que planea usar.

Proveedores compatibles

ProveedorDependencia de Gradle / Ubicación de AARParámetros requeridos
MERCADOPAGOimplementation("com.mercadolibre.android.device:sdk:4.0.1")(Ninguna requerida - pasar emptyMap())
RISKIFIEDimplementation("com.riskified:android-sdk:1.11.0:nogoogle@aar")storeDomain
CYBERSOURCEapp/libs/cybersource/*.aarorgId, merchantId (Opcional: fpServer)
SIGNIFYDapp/libs/signifyd/*.aarorgId (Opcional: fpServer)
ACCERTIFYapp/libs/accertify/*.aar + dependencias transitivasArchivos de configuración en src/main/assets/ (Opcional: locationConsent, phoneConsent)

Activos de Accertify y dependencias transitivas

  1. AAR y dependencias: Coloca inmobile.aar y inmobile-common.aar en app/libs/accertify/, y agregar dependencias transitivas:
app/build.gradleGROOVY
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")
}
  1. Activos de configuración: Colocar dos archivos dentro de app/src/main/assets/:
    • server_keys_message_hosted.json: Las claves de cifrado públicas proporcionadas por Accertify.
    • inmobile.properties: Archivo de configuración con los detalles de su comercio:
      PROPERTIES
      registerUrl=YOUR_INMOBILE_ENDPOINT_URL
      logUrl=YOUR_INMOBILE_ENDPOINT_URL
      accountGuid=YOUR_ACCOUNT_GUID
      serverKeysMessage=server_keys_message_hosted.json

Configuración e inicialización temprana de Mercado Pago

  1. Agregar el repositorio de Mercado Libre en settings.gradle.kts:
settings.gradle.ktsKotlin
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven(url = "https://artifacts.mercadolibre.com/repository/android-releases/")
    }
}
  1. Agregar la dependencia en app/build.gradle.kts:
app/build.gradle.ktsKotlin
dependencies {
    implementation("com.mercadolibre.android.device:sdk:4.0.1")
}
  1. Precalentar la huella digital temprano: Mercado Pago requiere hasta 3.5 segundos para realizar el perfilado de hardware. Llamar initializeFraudProviders en Application.onCreate o MainActivity.onCreate:
Kotlin
DeunaSDK.initializeFraudProviders(
    context = applicationContext,
    params = mapOf(
        "MERCADOPAGO" to emptyMap<String, Any>()
    ),
    onSuccess = {
        // Fingerprint collected and ready in background
    },
    onError = { error ->
        // Handle initialization error
    }
)

Llamada directa mediante generateFraudId

Kotlin
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")
    }
}

Pasar fraudCredentials directamente a los widgets

Al usar widgets de DEUNA, pase sus credenciales directamente mediante fraudCredentials. El SDK genera el identificador internamente en el momento de la compra:

Kotlin
PaymentWidgetConfiguration(
    sdkInstance = deunaSDK,
    orderToken = "YOUR_ORDER_TOKEN",
    callbacks = callbacks,
    fraudCredentials = mapOf(
        "RISKIFIED" to mapOf(
            "storeDomain" to "yourdomain.com"
        ),
        "MERCADOPAGO" to emptyMap()
    )
)

Notas de comportamiento

  • Sin inflado y seguro ante fallos: Si un proveedor está incluido en los parámetros pero su dependencia nativa no fue vinculada, el SDK lo omite de forma segura sin fallar.
  • Ejecución paralela: Todos los proveedores solicitados se perfilan concurrentemente en hilos en segundo plano.
  • Comportamiento de respaldo: Si no hay proveedores válidos configurados o disponibles en el dispositivo, generateFraudId se resuelve a null.

Referencia del ciclo de vida y llamadas de retorno#

Callback / MétodoCuadro de diálogoIntegradoDescripción
onSuccess✅✅Operación de pago o bóveda de tarjetas completada exitosamente. Recibe carga útil de orden o credencial. Llamar deunaSDK.close() (diálogo) o destroy() (incrustado).
onError✅✅Error ocurrido durante la inicialización o procesamiento del pago. Recibe PaymentsError o ElementsError.
onClosed✅❌Diálogo cerrado. Recibe CloseAction.USER_ACTION (cerrado manualmente) o CloseAction.SYSTEM_ACTION (cerrado mediante close()).
onPaymentProcessing✅✅Se activa cuando el cliente toca pagar y comienza el procesamiento del pago. Usar para deshabilitar botones y mostrar indicadores de progreso.
onCardBinDetected✅✅Se activa cuando se detecta o se borra un BIN de tarjeta (null cuando el usuario borra el número). Úselo para descuentos de franquicia.
onInstallmentSelected✅✅Se activa cuando el cliente selecciona cuotas diferidas (null en el pago único completo).
onEventDispatch✅✅Emite todas las ocurrencias subyacentes de CheckoutEvent o ElementsEvent ocurrencias con cargas útiles de datos.
close()✅❌Cierra el diálogo modal activo después de que se completen las pestañas de URL externas.
destroy()❌✅Limpia los recursos de WebView cuando el componente composable contenedor se desmonta.

Manejo de errores (onError)

Inspeccionar error.type para distinguir fallas de inicialización de rechazos de pago:

Kotlin
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 -> {}
    }
}

Ejemplos y código fuente oficiales#

Consulta ExploreViewModel.kt para fábricas de configuración y EmbeddedScreen.kt para el manejo del ciclo de vida de WebView.

En esta sección