SDK Android
Installez le SDK Android DEUNA et intégrez les flux de type modal, embarqué, portefeuille, coupon et prochaine étape.
Sur cette page
- Exigences
- Installation
- Initialisation
- Ouvrir le widget de paiement
- Expériences disponibles
- Intégrer un widget
- Filtrer et configurer les méthodes de paiement
- Style dynamique et rafraîchissement de commande
- Coffre-fort de paiement et Paiement en un clic
- Google Pay natif
- Poursuivre une action en attente
- Ouvrir un bon de réduction
- Données de fraude-appareil et empreinte numérique
- Référence des callbacks et du cycle de vie
- Exemples et code source officiels
Exigences#
Pour intégrer le SDK Android DEUNA, assurez-vous que votre projet respecte les exigences suivantes :
- Version SDK minimale:
minSdkVersion 24ou supérieure (Android API 24+) - Android Gradle Plugin (AGP): Version 8.5.1 ou supérieure (requise pour la prise en charge de la taille de page 16 KB d'Android)
- Langage de programmation: Kotlin ou Java
- Identifiants DEUNA: Compte actif et identifiants valides (contactez support@deuna.com si vous rencontrez des délais pour obtenir des identifiants)
Installation#
1. Ajoutez le dépôt JitPack
Ajoutez le dépôt JitPack dans le dependencyResolutionManagement dans votre 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' }
}
}Si votre projet n'utilise pas dependencyResolutionManagement, ajoutez le dépôt dans le build.gradle:
allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}2. Configurez build.gradle et les dépendances
Assurez-vous que votre minSdk est 24 ou supérieure, et ajoutez la dépendance du 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'
}Initialisation#
import com.deuna.maven.DeunaSDK
import com.deuna.maven.shared.EnvironmentVous pouvez initialiser le SDK de deux manières selon l'architecture de votre application :
Instance partagée globale
Initialisez une fois au démarrage de l'application (par exemple, dans votre Application.onCreate):
DeunaSDK.initialize(
environment = Environment.SANDBOX, // Environment.SANDBOX or Environment.PRODUCTION
publicApiKey = "YOUR_PUBLIC_API_KEY"
)
val deunaSDK = DeunaSDK.sharedInstance de Flow ou d'écran
Créez une instance pour un écran de paiement ou un ViewModel spécifique :
val deunaSDK = DeunaSDK(
environment = Environment.SANDBOX,
publicApiKey = "YOUR_PUBLIC_API_KEY"
)Ouvrir le widget de paiement#
Le Widget de Paiement propose plusieurs méthodes de paiement aux clients :
- Cartes de crédit et de débit: Visa, Mastercard, American Express et les cartes co-brandées.
- Méthodes de paiement alternatives (APM): OXXO, KueskiPay, Aplazo, Daviplata, Nequi, et plus.
- Portefeuilles numériques: Google Pay et PayPal.
Afficher dans une boîte de dialogue
Pour présenter le widget de paiement dans une DialogFragment, appeler initPaymentWidget en passant une 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"
)Référence des paramètres
| Paramètre | Tapez | Boîte de dialogue | Intégré | Descriptif |
|---|---|---|---|---|
context | Context | ✅ | ❌ | Requis pour la boîte de dialogue. Contexte d'Activity fournissant les ressources d'interface utilisateur et le jeton de fenêtre. |
orderToken | String | ✅ | ✅ | Obligatoire. Jeton unique pour la commande créée via l'API DEUNA. Important: Ne définissez pas de redirect_url lors de la création de commande si vous souhaitez que onSuccess s'exécute dans l'application. |
callbacks | PaymentWidgetCallbacks | ✅ | ✅ | Obligatoire. Écouteurs d'événements (onSuccess, onError, onClosed, onCardBinDetected, onInstallmentSelected, onPaymentProcessing, onEventDispatch). |
userToken | String? | ✅ | ✅ | Facultatif. Jeton porteur DEUNA du client. Important: Pour que les cartes enregistrées apparaissent, l'email lié au userToken doit correspondre à billing_address.email de la création de commande. |
styleFile | String? | ✅ | ✅ | Facultatif. UUID fourni par DEUNA pour appliquer une personnalisation de thème (couleurs, typographie, logo). |
paymentMethods | List<Map<String, Any>>? | ✅ | ✅ | Facultatif. Liste de méthode de paiement unique pour le flux de formulaires direct (par ex. listOf(mapOf("paymentMethod" to "bnpl", "processors" to listOf("kueski")))). |
language | String? | ✅ | ✅ | Facultatif. Code de langue ("es", "en", "pt"). Remplace la configuration par défaut du marchand. |
behavior | WidgetBehavior? | ✅ | ✅ | Facultatif. Personnalisation du flux, comme WidgetBehavior(paymentMethods = mapOf("flowType" to "twoStep")) pour PayPal, ou Paiements fractionnés splitPayments. |
fraudCredentials | Map<String, Any>? | ✅ | ✅ | Facultatif. Identifiants du fournisseur anti-fraude (par ex. mapOf("RISKIFIED" to mapOf("storeDomain" to "example.com"))). |
domain | String? | ✅ | ✅ | Facultatif. Remplace l'hôte de base par défaut (https://pay.deuna.io). |
hidePayButton | Boolean | ❌ | ✅ | Facultatif. Masque le bouton de paiement intégré en mode intégré lorsque votre application affiche un bouton natif. |
Expériences disponibles#
| Expérience | Méthode | Type de configuration | Informations importantes |
|---|---|---|---|
| Widget de paiement | initPaymentWidget(...) | PaymentWidgetConfiguration | context, orderToken, PaymentWidgetCallbacks |
| Coffre-fort de paiement | initElements(...) | ElementsWidgetConfiguration | context, ElementsCallbacks; types Peut être omis |
| Cliquez pour payer | initElements(...) | ElementsWidgetConfiguration | types = listOf(mapOf("name" to "click_to_pay")) |
| Prochaine étape | initNextAction(...) | NextActionWidgetConfiguration | context, orderToken, NextActionCallbacks |
| Bon de réduction | initVoucherWidget(...) | VoucherWidgetConfiguration | context, orderToken, VoucherCallbacks |
Toutes les méthodes modales acceptent des entrées facultatives de langue, de fraude et de domaine lorsque pris en charge. Ne remplacez pas domain à moins que DEUNA ne vous attribue un hôte dédié.
Intégrer un widget#
Pour afficher le widget intégré dans votre application avec Jetpack Compose, utilisez AndroidView et 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()
}
}
}Redimensionnement automatique et gestion du clavier
Lorsque vous passez autoResizeConfig = AutoResizeConfig(initialHeightDp = 100), le widget passe en mode de redimensionnement automatique : il grandit et rétrécit dynamiquement pour correspondre à la hauteur du contenu WebView, ce qui le rend idéal pour une intégration dans un conteneur déroulant.
- Configuration du manifeste: Assurez-vous que votre Activity de paiement est configurée avec
adjustResizedansAndroidManifest.xml:
<activity
android:name=".CheckoutActivity"
android:windowSoftInputMode="adjustResize" />- Intégration au défilement Compose: Placez
DeunaWidgetà l'intérieur d'un conteneur de défilement vertical et connectezsetOnScrollByCallbackauScrollState:
@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...
}
}Bouton de paiement personnalisé (hidePayButton)
Si votre application affiche son propre bouton natif en dehors du widget, passez hidePayButton = true et gérez la soumission de manière programmatique en utilisant isValid et 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éthode | Descriptif | Valeur de retour |
|---|---|---|
deunaWidget.isValid { valid -> ... } | Valide la saisie de l'utilisateur dans le formulaire de paiement actif. | Boolean |
deunaWidget.submit { result -> ... } | Soumet le paiement équivalent à un clic sur le bouton du widget. | SubmitResult (status: "success" ou status: "error") |
Filtrer et configurer les méthodes de paiement#
Flux de formulaires directs (paymentMethods)
Les architectures de paiement DEUNA prennent en charge le lancement direct dans un formulaire de paiement individuel — un modèle connu sous le nom de flux de formulaires.
Bien que paymentMethods soit typé comme une liste, les moteurs de paiement internes prennent actuellement en charge un seul élément dans cette liste. Fournir un seul moyen de paiement ouvre le widget directement dans le formulaire de cette méthode (par ex. Kueski Pay BNPL), en contournant le sélecteur de méthode.
deunaSDK.initPaymentWidget(
context = this,
orderToken = "YOUR_ORDER_TOKEN",
callbacks = callbacks,
paymentMethods = listOf(
mapOf(
"paymentMethod" to "bnpl",
"processors" to listOf("kueski")
)
)
)Résolution de priorité de configuration
| Priorité | Source | Comportement |
|---|---|---|
| 1 (Priorité la plus élevée) | paymentMethods dans .initPaymentWidget() | Flux de formulaires directs : Ouvre immédiatement le formulaire du moyen de paiement unique spécifié (par exemple, Kueski), en contournant le sélecteur de méthode. |
| 2 | include_payment_options dans la création de commande | Sélection multi-méthodes : Affiche uniquement les moyens de paiement spécifiés lors de la création de la commande qui sont actifs sur votre compte. |
| 3 (Fallback) | Configuration au niveau marchand (/payment-methods) | Sélecteur complet : Si omis à la fois dans l'appel SDK et dans le payload de commande, affiche tous les moyens de paiement actifs configurés pour votre compte marchand. |
Configurations PayPal
Type de flux (flowType)
deunaSDK.initPaymentWidget(
context = this,
orderToken = orderToken,
behavior = WidgetBehavior(
paymentMethods = mapOf(
"flowType" to "twoStep" // "twoStep" (summary first) or "singleStep" (direct)
)
)
)Achat automatique (express)
Lorsque les clients ont précédemment autorisé des paiements rapides avec PayPal, activez le traitement immédiat :
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)
)
)
)Paiements fractionnés avec plusieurs cartes
deunaSDK.initPaymentWidget(
context = this,
orderToken = orderToken,
behavior = WidgetBehavior(
paymentMethods = mapOf(
"creditCard" to mapOf(
"splitPayments" to mapOf(
"maxCards" to 2 // Maximum number of cards allowed
)
)
)
)
)Style dynamique et rafraîchissement de commande#
Personnalisez dynamiquement l'apparence (setCustomStyle)
Mettez à jour les styles du widget dynamiquement (par ex. adaptation de la marque lors de la détection du BIN de carte) :
callbacks = PaymentWidgetCallbacks().apply {
onCardBinDetected = { metadata, _ ->
deunaSDK.setCustomStyle(
data = mapOf(
"theme" to mapOf(
"colors" to mapOf(
"primaryTextColor" to "#023047",
"buttonPrimaryFill" to "#FFB703",
"buttonPrimaryText" to "#000000"
)
)
)
)
}
}Rafraîchissez les totaux de commande (refetchOrder)
Lorsque vous proposez des promotions spécifiques à une franchise (par ex., "20 % de réduction avec Mastercard"), écoutez onCardBinDetected, mettez à jour la commande sur votre backend, et notifiez le 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")
}
}
}
}
}Coffre-fort de paiement et Paiement en un clic#
Payment Vault est un composant des solutions de paiement DEUNA qui permet de sauvegarder des cartes de manière sécurisée et de payer via Click to Pay sans traiter les paiements classiques.
Afficher dans une boîte de dialogue
Pour afficher Card Vault dans une boîte de dialogue modale, appelez initElements (omettez types pour le Vault par défaut) :
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
)
)
)Afficher intégré (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()
}Cliquez pour payer
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")
)
)Référence des paramètres
| Paramètre | Tapez | Boîte de dialogue | Intégré | Descriptif |
|---|---|---|---|---|
context | Context | ✅ | ❌ | Requis pour la boîte de dialogue. Contexte d'activité. |
callbacks | ElementsCallbacks | ✅ | ✅ | Obligatoire. Écouteurs d'événements (onSuccess, onError, onClosed, onEventDispatch). |
userInfo | UserInfo? | ✅ | ✅ | Client firstName, lastNameet email. Requis pour Click to Pay. |
userToken | String? | ✅ | ✅ | Facultatif. Jeton porteur DEUNA. S'il est fourni, omettez userInfo. |
types | List<Map<String, Any>>? | ✅ | ✅ | Facultatif. Omettez pour afficher l'expérience Card Vault par défaut. Fournissez listOf(mapOf("name" to "click_to_pay")) pour afficher Click to Pay. |
orderToken | String? | ✅ | ✅ | Facultatif. Jeton de commande unique. Les détails du client peuvent être extraits de billing_address. |
styleFile | String? | ✅ | ✅ | Facultatif. UUID de personnalisation du thème. |
widgetExperience | ElementsWidgetExperience? | ✅ | ✅ | Facultatif. showSavedCardFlow (bouton de sauvegarde de carte) et defaultCardFlow (bouton de sauvegarde par défaut). |
domain | String? | ✅ | ✅ | Facultatif. Remplace l'hôte (https://elements.deuna.com). |
hidePayButton | Boolean | ❌ | ✅ | Facultatif. Masque le bouton en mode intégré. Utilisez isValid et submit pour des boutons personnalisés. |
Google Pay natif#
Vérifiez la configuration du marchand et les capacités de l'appareil avant d'afficher un bouton 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
}Après la réussite de la vérification de disponibilité, lancez Google Pay depuis l'action du bouton en utilisant 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"
)Voir Google Payer pour l'inscription du marchand et la configuration des tests.
Poursuivre une action en attente#
Utilisez le même jeton de commande lorsque DEUNA signale que le paiement nécessite un défi ou une redirection 3DS pris en charge.
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
}
}
)L'SDK ouvre les URL externes supportées et retourne au widget actif. Utilisez l'état de callback pour l'interface et l'état de paiement final DEUNA pour la fulfillment.
Ouvrir un bon de réduction#
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
}
}
)Données de fraude-appareil et empreinte numérique#
Le SDK Android DEUNA utilise une architecture modulaire: il ne regroupe pas les SDK de fraude tiers par défaut. Ajoutez uniquement le(s) fournisseur(s) spécifique(s) que vous prévoyez d'utiliser.
Fournisseurs pris en charge
| Fournisseur | Dépendance Gradle / Placement AAR | Paramètres requis |
|---|---|---|
MERCADOPAGO | implementation("com.mercadolibre.android.device:sdk:4.0.1") | (Aucune requise - passez emptyMap()) |
RISKIFIED | implementation("com.riskified:android-sdk:1.11.0:nogoogle@aar") | storeDomain |
CYBERSOURCE | app/libs/cybersource/*.aar | orgId, merchantId (Optionnel : fpServer) |
SIGNIFYD | app/libs/signifyd/*.aar | orgId (Optionnel : fpServer) |
ACCERTIFY | app/libs/accertify/*.aar + dépendances transitives | Fichiers de configuration dans src/main/assets/ (Optionnel : locationConsent, phoneConsent) |
Actifs Accertify et dépendances transitives
- AAR et dépendances: Placez
inmobile.aaretinmobile-common.aardansapp/libs/accertify/, et ajoutez les dépendances transitives :
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")
}- Actifs de configuration: Placez deux fichiers dans
app/src/main/assets/:server_keys_message_hosted.json: Les clés de chiffrement publiques fournies par Accertify.inmobile.properties: Fichier de configuration avec vos détails marchand :PROPERTIESregisterUrl=YOUR_INMOBILE_ENDPOINT_URL logUrl=YOUR_INMOBILE_ENDPOINT_URL accountGuid=YOUR_ACCOUNT_GUID serverKeysMessage=server_keys_message_hosted.json
Configuration et initialisation anticipée de Mercado Pago
- Ajoutez le dépôt Mercado Libre dans
settings.gradle.kts:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven(url = "https://artifacts.mercadolibre.com/repository/android-releases/")
}
}- Ajoutez la dépendance dans
app/build.gradle.kts:
dependencies {
implementation("com.mercadolibre.android.device:sdk:4.0.1")
}- Préchauffage de l'empreinte numérique anticipé: Mercado Pago nécessite jusqu'à 3,5 secondes pour effectuer le profilage matériel. Appelez
initializeFraudProvidersdansApplication.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
}
)Appel direct 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")
}
}Passez fraudCredentials directement aux widgets
Lorsque vous utilisez les widgets DEUNA, passez vos identifiants directement via fraudCredentials. Le SDK génère l'identifiant en interne au moment de l'achat :
PaymentWidgetConfiguration(
sdkInstance = deunaSDK,
orderToken = "YOUR_ORDER_TOKEN",
callbacks = callbacks,
fraudCredentials = mapOf(
"RISKIFIED" to mapOf(
"storeDomain" to "yourdomain.com"
),
"MERCADOPAGO" to emptyMap()
)
)Notes sur le comportement
- Zéro surcharge et résistant aux plantages: Si un fournisseur est inclus dans les paramètres mais que sa dépendance native n'a pas été liée, le SDK l'ignore en toute sécurité sans planter.
- Exécution parallèle: Tous les fournisseurs demandés effectuent le profilage simultanément sur des threads d'arrière-plan.
- Comportement de repli: Si aucun fournisseur valide n'est configuré ou disponible sur l'appareil,
generateFraudIdse résout ennull.
Référence des callbacks et du cycle de vie#
| Rappel / Méthode | Boîte de dialogue | Intégré | Descriptif |
|---|---|---|---|
onSuccess | ✅ | ✅ | Opération de paiement ou de coffre-fort de carte terminée avec succès. Reçoit la charge utile de commande ou d'identification. Appelez deunaSDK.close() (dialogue) ou destroy() (intégré). |
onError | ✅ | ✅ | Erreur survenue pendant l'initialisation ou le traitement du paiement. Reçoit un PaymentsError ou ElementsError. |
onClosed | ✅ | ❌ | Dialogue fermé. Reçoit CloseAction.USER_ACTION (fermé manuellement) ou CloseAction.SYSTEM_ACTION (fermé par le client) ou close()). |
onPaymentProcessing | ✅ | ✅ | Déclenché lorsque le client appuie sur payer et que le traitement du paiement commence. Utilisez pour désactiver les boutons et afficher les indicateurs de progression. |
onCardBinDetected | ✅ | ✅ | Déclenché lorsqu'un BIN de carte est détecté ou effacé (null Déclenché lorsqu'un BIN de carte est détecté ou effacé (retourne |
onInstallmentSelected | ✅ | ✅ | Déclenché lorsque le client sélectionne des échéances différées (null Déclenché lorsque le client sélectionne un plan de paiement échelonné (retourne |
onEventDispatch | ✅ | ✅ | Déclenché lorsque le client demande le téléchargement d'un bon ou d'un reçu. CheckoutEvent ou ElementsEvent occurrences avec des charges utiles de données. |
close() | ✅ | ❌ | Ferme le dialogue modal actif après la fin des onglets d'URL externes. |
destroy() | ❌ | ✅ | Nettoie les ressources WebView lorsque le composable contenant est démonté. |
pour la journalisation personnalisée et l'analyse.onError)
Inspectez error.type Inspectez l'erreur
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 -> {}
}
}Exemples et code source officiels#
Consultez le fichier ExploreViewModel.kt Pour les usines de configuration et EmbeddedScreen.kt Pour la gestion du cycle de vie de WebView.