Full SDK (Android)


👍

SDK recommandé

Nous recommandons d'utiliser le SDK Seamless Android  pour une expérience d'intégration fluide. Cette option offre une solution de paiement flexible avec des composants d'interface utilisateur (UI) pré-construits et des options de personnalisation.

Cette page fournit un guide pour le Full SDK de Yuno pour Android, qui offre une solution de paiement complète avec une interface utilisateur personnalisable. Il fournit des fonctionnalités avancées comme la gestion des modes de paiement, la prévention de la fraude et des flux de paiement fluides, le rendant plus riche en fonctionnalités que notre Headless SDK, qui est spécifique aux capacités de traitement de paiement de base.

Prérequis

Avant de commencer l'intégration du SDK Android de Yuno, assurez-vous que votre projet répond aux exigences techniques. De plus, les pré-requis suivants doivent être en place :

  1. Vous devez disposer d'un compte Yuno actif
  2. Vous avez besoin de vos identifiants API Yuno (account_id, public-api-keyet  private-secret-key), que vous pouvez obtenir dans la  Section Développeurs du tableau de bord Yuno. Ces identifiants sont requis pour authentifier les requêtes auprès de l'API Yuno, utilisée pour :
  • Créer un checkout_session, qui initialise le flux de paiement
  • Créer le paiement associé à la session
  1. Avant de créer un paiement, vous devez d'abord créer un client en utilisant le endpoint Créer un client

Étape 1 : Inclure la bibliothèque dans votre projet

Incluez le fichier du SDK Yuno dans votre projet via Gradle. Ensuite, ajoutez la source du dépôt :

maven { url "https://yunopayments.jfrog.io/artifactory/snapshots-libs-release" }
📘

Version du SDK

Accédez aux notes de version ou au dépôt du SDK Android Yuno pour vérifier la dernière version du SDK disponible.

Ensuite, incluez le code suivant dans le fichier build.gradle pour ajouter la dépendance du SDK Yuno à l'application :

dependencies {
    implementation 'com.yuno.payments:android-sdk:{last_version}'
}

Permissions

Le SDK Yuno inclut, par défaut, la permission INTERNET , qui est requise pour effectuer des requêtes réseau.

<uses-permission android:name="android.permission.INTERNET" />

Étape 2 : Initialiser le SDK avec la clé publique

Récupérez vos clés API publiques depuis le Tableau de bord Yuno.

Si vous n'avez pas implémenté une classe Application personnalisée, créez-en une. Dans la méthode onCreate() de votre classe d'application, appelez la fonction d'initialisation (Yuno.initialize) :

class CustomApplication : Application() {
  override fun onCreate() {
    super.onCreate()
    Yuno.initialize(
      this,
      "<your-public-api-key>",
      config: YunoConfig,
    )
  }
}
📘

Identifiants

Pour plus d'informations, Consultez la page des identifiants : https://docs.y.uno/reference/authentication

Utiliser la classe de données YunoConfig pour personnaliser le comportement du SDK. Incluez cette configuration lors de l'appel à Yuno.initialize(). Les options disponibles sont :

classe de données YunoConfig(
    val cardFlow : CardFormType  CardFormType.ONE_STEP,
    val saveCardEnabled : Boolean = false,
    val cardFormDeployed : Boolean = false,
    val language : YunoLanguage? = null,
    val styles : YunoStyles? = null,
    val cardNumberPlaceholder : String? = null, // Facultatif : texte de remplacement personnalisé pour le champ du numéro de carte
    val hideCardholderName: Boolean? = null // Facultatif : définir sur true pour masquer le champ du nom du titulaire de la carte
)

Paramètres

Le tableau suivant décrit chaque personnalisation disponible :

Option de personnalisationDescription
cardFlowIl s'agit d'une configuration facultative qui définit le flux des cartes de paiement et d'inscription. Par défaut, le flux de CardFormType.ONE_STEP est utilisée. Consultez la section  Options de rendu  pour plus d'informations.
saveCardEnabledActive la case à cocher Sauvegarder la carte sur les flux de carte. Consultez la section Sauvegarder la carte pour plus d'informations.
cardFormDeployedCette option est uniquement disponible pour le Full SDK. Si TRUE le système présente le formulaire de carte déployé sur la liste des modes de paiement. Si FALSE, il présente le formulaire de carte normal sur un autre écran.
languageDéfinit la langue à utiliser dans les formulaires de paiement. Vous pouvez choisir l'une des options linguistiques disponibles :
  • Es (Espagnol)
  • En (Anglais)
  • Po (Portugais)
  • Ph (Philippin)
  • In (Indonésien)
  • Ma (Malais)
  • Th (Thaïlandais)
  • zh-TW (chinois (traditionnel, taïwanais))
  • zh-CN (chinois (simplifié, Chine))
  • vi (vietnamien)
  • fr (français)
  • pl (polonais)
  • it (Italien)
  • de (allemand)
  • ru (russe)
  • tr (turc)
  • nl (néerlandais)
  • sv (suédois)
  • ko (coréen)
  • ja (japonais)
cardNumberPlaceholderCe champ facultatif vous permet de personnaliser le texte de remplacement pour le champ du numéro de carte. Il prend en charge les caractères alphanumériques, les espaces et les caractères UTF-8 pour la localisation. Si aucun texte n'est fourni, le SDK utilise le texte de remplacement par défaut (« Numéro de carte »). Cette personnalisation n'affecte pas le formatage de la carte, le masquage, la logique BIN ou la validation.
hideCardholderNameCe champ facultatif vous permet de masquer le champ du nom du titulaire de la carte dans le formulaire de carte. Lorsqu'il est défini sur true, le champ du nom du titulaire de la carte n'est pas affiché. Lorsqu'il n'est pas spécifié ou défini sur false, le champ du nom du titulaire de la carte s'affiche (comportement par défaut). Le fait de masquer ce champ n'a aucune incidence sur le PAN, la date d'expiration, la collecte du CVV, la logique BIN ou les validations 3DS/fournisseur. Le commerçant est tenu de s'assurer que le nom du titulaire de la carte est fourni lorsque son fournisseur de services de paiement l'exige.
stylesPermet la personnalisation de l'interface utilisateur à l'échelle du SDK. Utilisez-le pour définir des styles visuels globaux (famille de polices, apparence des boutons) via un objet YunoStyles . Pour plus d'informations, consultez la page styles .

Mettez à jour votre manifeste pour utiliser votre application :

<application android:name=".CustomApplication"></application>

Étape 3 : Créer la session de paiement

Chaque paiement nécessite une nouvelle checkout_session, qui donne accès à tous les modes de paiement disponibles pour un client spécifique. Utilisez le endpoint  Créer une session de paiement  pour obtenir une nouvelle checkout_session. Cette session est ensuite utilisée pour initier le paiement.

📘

Gestion du retour du navigateur externe

Si votre flux de paiement envoie les utilisateurs vers un navigateur externe (par exemple, pour l'authentification 3DS ou les redirections bancaires), assurez-vous de définir le callback_url lors de la création de votre session de checkout. Pour un guide étape par étape sur la gestion du retour à votre application, consultez  Gérer le retour du navigateur externe (callback_url).

Étape 4 : Démarrer le processus de paiement

Appelez la fonction startCheckout à l'intérieur de la fonction onCreate() de l'activité qui initialise le SDK pour démarrer un nouveau processus de paiement avec le Full SDK :

startCheckout(
 checkoutSession: "checkout_session",
 countryCode: "country_code_iso",
 callbackPaymentState: ((String?) -> Unit)?,
  merchantSessionId: String? = null
)

Paramètres

Configurez le paiement avec les options suivantes :

ParamètresDescription
checkoutSessionUn identifiant unique pour la session de paiement associée au paiement. Il est nécessaire pour initialiser le processus de paiement et permet d'accéder aux méthodes de paiement disponibles pour le client.
countryCodeCode du pays où le paiement est effectué. Consultez la Couverture des pays pour une liste complète des pays pris en charge et de leurs codes.
callbackPaymentStateC'est une fonction qui retourne le processus de paiement actuel. Vous n'avez pas besoin d'envoyer cette fonction si vous n'avez pas besoin du résultat.
merchantSessionIdIdentifiant utilisé par le commerçant pour suivre le paiement.

Voici les états possibles retournés par le callbackPaymentState:

const val PAYMENT_STATE_SUCCEEDED = "SUCCEEDED"
const val PAYMENT_STATE_FAIL = "FAIL"
const val PAYMENT_STATE_PROCESSING = "PROCESSING"
const val PAYMENT_STATE_REJECT = "REJECT"
const val PAYMENT_STATE_INTERNAL_ERROR = "INTERNAL_ERROR"
const val PAYMENT_STATE_STATE_CANCELED_BY_USER = "CANCELED"

Le tableau suivant fournit des informations supplémentaires sur les états possibles :

ÉtatDescriptionAction supplémentaire requise
SUCCEEDEDLa transaction ou le processus de paiement a été complété avec succès.Non.
FAILLa transaction a échoué en raison d'erreurs (validation des données, échec de connexion serveur, problèmes techniques/réseau).Oui. Recherchez la cause de la défaillance (validation, réseau, serveur) et prenez des mesures correctives.
PROCESSINGLa transaction est en cours, en attente d'approbation ou de vérification.Non.
REJECTLa transaction a été rejetée pour des raisons telles qu'une insuffisance de fonds ou un soupçon d'activité frauduleuse.Oui. Informer l'utilisateur du rejet, fournir la raison si possible, et suggérer des actions.
INTERNAL_ERRORUne erreur interne inattendue s'est produite dans le système qui gère le processus de paiement.Oui. Nécessite une intervention technique pour examiner le système, résoudre les problèmes internes et réessayer ou informer l'utilisateur.
CANCELEDL'utilisateur a volontairement annulé la transaction ou abandonné le processus de paiement.Non.

Validation du statut de paiement

Cette section explique comment le SDK gère le statut des paiements lorsque les utilisateurs annulent ou quittent les flux de paiement, et comment le statut du SDK est lié au statut des paiements backend dans ces scénarios.

Synchroniser les modes de paiement (Google Pay)

Pour les méthodes de paiement synchronisées telles que Google Pay, lorsqu'un utilisateur annule ou ferme l'interface utilisateur du portefeuille avant de recevoir la réponse du prestataire de services de paiement (PSP) :

  • Statut du SDK: Retours CANCELED (CANCELLED)
  • Statut du paiement backend: Restes PENDING jusqu'à l'expiration du délai PSP ou l'annulation par le commerçant
  • Important: Le SDK ne renverra pas REJECT ou PROCESSING dans ce scénario

Cela garantit que le paiement backend reste en attente et peut être correctement traité par le système du commerçant.

Modes de paiement asynchrones (PIX et méthodes basées sur les QR codes)

Pour les méthodes de paiement asynchrones telles que PIX, lorsqu'un utilisateur ferme la fenêtre du code QR (clique sur X) avant d'avoir terminé le paiement :

  • Statut du SDK: Retours PROCESSING, éventuellement avec un sous-statut tel que CLOSED_BY_USER
  • Statut du paiement backend: Restes PENDING et le code QR reste valide jusqu'à son expiration.
  • Réutilisation de la session de paiement: la réouverture de la même session de paiement permet d'afficher le même code QR valide.
  • Pas d'annulation automatique: le paiement PIX n'est pas automatiquement annulé lorsque l'utilisateur ferme la fenêtre QR.

Ce comportement permet aux utilisateurs de revenir au flux de paiement et de terminer la transaction à l'aide du même code QR avant son expiration.

Paiements asynchrones expirés

Si un code QR PIX expire naturellement :

  • Statut du backend: Mis à jour vers EXPIRED
  • Statut du SDK: Les rappels SDK et endpoints d'interrogation endpoints EXPIRED de manière cohérente

Cela garantit que les commerçants reçoivent des informations précises sur le statut lorsqu'un moyen de paiement a expiré.

Étape 5 : Ajouter la vue SDK au paiement

Utilisez l'endpoint  PaymentMethodListViewComponent pour afficher les méthodes de paiement disponibles lors de l'implémentation du Full SDK avec Jetpack Compose. Ce composant fournit des rappels pour notifier à votre application quand il faut activer ou désactiver le bouton de paiement, et quand une méthode de paiement inscrite est supprimée avec succès.

Signature du composant

@Composable
fun PaymentMethodListViewComponent(
    activity: Activity,
    modifier: Modifier? = null,
    onPaymentSelected: (Boolean) -> Unit,
    onUnEnrollSuccess: (Boolean) -> Unit = {}
)

Paramètres

  • activity: Activity
    • L' Activity actuelle où le composant est hébergé. Requis pour gérer correctement les flux de paiement.
  • modifier: Modifier? (facultatif)
    • Vous permet de personnaliser la mise en page et l'apparence (par exemple, le rembourrage, l'espacement). La valeur par défaut est null.
  • onPaymentSelected: (Boolean) -> Unit
    • Rappel invoqué lorsqu'une méthode de paiement est sélectionnée ou désélectionnée.
      • true → Une méthode est sélectionnée (activer le bouton de paiement).
      • false → Aucune méthode n'est sélectionnée (désactiver le bouton de paiement).
  • onUnEnrollSuccess: (Boolean) -> Unit (facultatif)
    • Rappel invoqué lorsqu'une méthode de paiement enregistrée est supprimée avec succès (déinscrit).
      • true → Indique que la suppression a réussi.
      • Peut être utilisé pour afficher un snackbar, actualiser la liste ou mettre à jour l'état de l'interface utilisateur.

Exemple

val coroutineScope = rememberCoroutineScope()
val snackbarHostState = remember { SnackbarHostState() }
var paymentMethodIsSelected by remember { mutableStateOf(false) }

Column(
    modifier = Modifier
        .weight(1f)
        .verticalScroll(rememberScrollState()))
 {
    PaymentMethodListViewComponent(
        activity = activity,
 onPaymentSelected { isSelected ->
            paymentMethodIsSelected = isSelected
        },
       onUnEnrollSuccess { success ->
            if (success) {
                coroutineScope.launch {
                    snackbarHostState.showSnackbar(
                        message = "Votre mode de paiement a été supprimé",
                    )
                }
            }
        },
    )
}

Important

Enveloppez toujours le composant dans une Column par .verticalScroll(rememberScrollState()). Sans cela, la liste des méthodes de paiement risque de ne pas s'afficher ou de ne pas défiler correctement lorsqu'il y a plusieurs méthodes disponibles.

Étape 6 : Initier le processus de paiement

Appelez la fonction startPayment() pour démarrer un processus de paiement :

startPayment(
    showStatusYuno : booléen,
 callbackOTT: (chaîne ?) -> unité = thisonTokenUpdated,
 callBackTokenWithInformation: (OneTimeTokenModel?) -> unité = this::onTokenComplete

)

Paramètres

Configurez le paiement avec les options suivantes :

ParamètresDescription
showStatusYunoUn booléen qui spécifie si le statut de paiement doit être affiché dans l'interface Yuno.
callbackOTTUne fonction requise qui retourne le Token à usage unique (OTT) mis à jour nécessaire pour compléter le processus de paiement. Ce Token est requis pour compléter le paiement.
callBackTokenWithInformationUne fonction qui fournit des informations détaillées sur le token à usage unique, enveloppée dans un objet OneTimeTokenModel , permettant une gestion complète des détails du Token.

Étape 7 : Obtenir le token à usage unique (OTT)

Une fois que le client a rempli les données demandées dans les formulaires de paiement de Yuno, vous obtiendrez le token à usage unique, un paramètre requis pour créer un paiement à l'aide de l'API Yuno.

Le token à usage unique sera partagé par Yuno en utilisant la fonction callbackOTT que vous avez fournie à l'Étape 6 lors de l'initiation du paiement. Le token à usage unique sera disponible dans l' onActivityResult.

📘

Configuration du Loader

Pendant que Yuno reçoit les informations du client et partage le token à usage unique, un loader peut être affiché pour améliorer l'expérience utilisateur. Yuno fournit un loader par défaut qui peut être utilisé tel quel. Cependant, les commerçants peuvent choisir d'implémenter leur propre loader et sont responsables d'effectuer les configurations nécessaires.

Étape 8 : Créer le paiement

Après avoir reçu le token à usage unique de  l'Étape 7 créez le paiement en utilisant le endpoint  Créer un paiement . Utilisez la checkout_session de  l'Étape 3  et le token à usage unique pour créer le paiement.

La réponse du endpoint Créer un paiement comprendra le paramètre sdk_action_required, qui définit si des actions supplémentaires sont requises pour finaliser le paiement en fonction du type de paiement.

🚧

Intégration de la Méthode continuePayment

Yuno vous  demande  d'intégrer la méthode continuePayment du SDK après la création du paiement, car certaines méthodes de paiement asynchrones nécessitent une action client supplémentaire pour être complétées. L'API vous informera de ce scénario via le champ sdk_action_required de la réponse, qui sera retourné comme true. La fonction yuno.continuePayment() affichera des écrans supplémentaires aux clients, où ils pourront effectuer les actions nécessaires pour finaliser le paiement sans que vous ayez à gérer chaque scénario.

Étape 9 : Continuer le paiement

Yuno exige l'intégration de la méthode continuePayment du SDK après la création du paiement, car certaines méthodes de paiement asynchrones nécessitent des actions client supplémentaires pour être complétées. La réponse du endpoint  Créer un paiement, de l'Étape 8, inclura un champ sdk_action_required . S'il retourne TRUE, vous devez appeler la fonction continuePayment() pour afficher des écrans supplémentaires qui permettent au client de finaliser le paiement. Sinon, cette étape n'est pas nécessaire. Appelez la méthode continuePayment : Indicateurs booléens

continuePayment(
 showPaymentStatus: Boolean = true,
 checkoutSession: String? = null,
 countryCode: String? = null,
 callbackPaymentState: ((String?) -> Unit)? = null
)

Pour afficher vos écrans de statut de paiement, envoyez FALSE dans le paramètre showPaymentStatus Ensuite, obtenez l'état du paiement par Rappel.

Intégration du Mode Rendu

Le mode rendu du SDK Yuno offre une flexibilité avancée de l'interface utilisateur, permettant aux développeurs d'intégrer des flux de paiement avec un contrôle complet de l'interface utilisateur tout en conservant toutes les fonctionnalités du Full SDK. Ce mode renvoie des fragments qui peuvent être utilisés à la fois avec Jetpack Compose et les vues XML traditionnelles.

Fonction principale : startPaymentRender

Le champ startPaymentRender initialise le flux de paiement en mode rendu, vous donnant un contrôle granulaire sur la présentation de l'interface utilisateur.

fun Activity.startPaymentRender(
 checkoutSession: String? = null,
 countryCode: String? = null,
    coroutineScope: CoroutineScope,
 paymentSelected: PaymentSelected,
    listener: YunoPaymentRenderListener,
): YunoPaymentFragmentController

Paramètres

ParamètresTypeRequisDescription
checkoutSessionString?NonID de la session de paiement précédemment créée
countryCodeString?NonCode pays pour les configurations régionales
coroutineScopeCoroutineScopeOuiPortée de coroutine pour les opérations asynchrones
paymentSelectedPaymentSelectedOuiMode de paiement sélectionné
listenerYunoPaymentRenderListenerOuiImplémentation du l'écouteur pour recevoir les événements

Exemple d'Implémentation

class PaymentActivity : Activity() {

    private lateinit var fragmentController: YunoPaymentFragmentController

    private fun initializePayment() {
        fragmentController = startPaymentRender(
            checkoutSession = "your_checkout_session_id",
            countryCode = "US",
            coroutineScope = lifecycleScope,
            paymentSelected = PaymentSelected.CARD,
            listener = paymentRenderListener
        )
    }
}

YunoPaymentRenderListener interface

Implémentez cette interface pour recevoir tous les événements et vues du SDK pendant le flux de paiement :

class PaymentRenderListener : YunoPaymentRenderListener {

    override fun showView(fragment: Fragment) {
        supportFragmentManager.beginTransaction()
            .replace(R.id.payment_container, fragment)
            .commit()
    }

    override fun returnStatus(resultCode: Int, paymentStatus: String) {
        when (paymentStatus) {
            "SUCCEEDED" -> handleSuccessfulPayment()
            "FAIL" -> handleFailedPayment()
        }
    }

    override fun returnOneTimeToken(oneTimeToken: String, additionalData: OneTimeTokenModel?) {
        createPaymentInBackend(oneTimeToken) { result ->
            when (result) {
                is Success -> fragmentController.continuePayment()
                is Error -> handlePaymentError(result.error)
            }
        }
    }

    override fun loadingListener(isLoading: Boolean) {
        progressBar.visibility = if (isLoading) View.VISIBLE else View.GONE
    }
}

YunoPaymentFragmentController interface

Contrôlez le flux de paiement à l'aide de l'instance de contrôleur retournée :

Méthodes

  • submitForm(): Soumet le formulaire actuel lorsqu'il est disponible
  • continuePayment(): Continue le flux de paiement après le traitement OTT du backend
fragmentController.submitForm()

fragmentController.continuePayment()

Avantages de l'intégration

Flexibilité de l'interface utilisateur

  • Compatible Compose et XML: Fonctionne à la fois avec Jetpack Compose et les vues XML traditionnelles
  • Contrôle complet : Vous décidez où et comment afficher chaque vue
  • Intégration personnalisée: Intégration facile avec la conception d'application existante

Contrôle du Flux

  • Logique de soumission personnalisée: Contrôlez quand soumettre les formulaires
  • Intégration backend: Traitez l'OTT sur votre backend avant de continuer

Exemple d'intégration Complet 

class PaymentActivity : ComponentActivity() {

    private lateinit var fragmentController: YunoPaymentFragmentController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        fragmentController = startPaymentRender(
            checkoutSession = checkoutSessionId,
            countryCode = "US",
            coroutineScope = lifecycleScope,
            paymentSelected = PaymentSelected.CARD,
            listener = object : YunoPaymentRenderListener {
                override fun showView(fragment: Fragment) {
                    supportFragmentManager.beginTransaction()
                        .replace(R.id.payment_fragment_container, fragment)
                        .commit()
                }

                override fun returnOneTimeToken(oneTimeToken: String, additionalData: OneTimeTokenModel?) {
                    processPaymentToken(oneTimeToken) {
                        fragmentController.continuePayment()
                    }
                }

                override fun returnStatus(resultCode: Int, paymentStatus: String) {
                    handlePaymentResult(paymentStatus)
                }

                override fun loadingListener(isLoading: Boolean) {
                    updateLoadingState(isLoading)
                }
            }
        )
    }
}
🚧

Gestion du cycle de vie

Assurez-vous que la CoroutineScope est liée au cycle de vie de l'Activité/Fragment pour éviter les fuites de mémoire et garantir un nettoyage approprié.

Fonctionnalités Complémentaires

Le SDK Android Yuno fournit des services et des configurations supplémentaires que vous pouvez utiliser pour améliorer l'expérience client. Utilisez les personnalisations du SDK pour modifier l'apparence du SDK afin qu'il corresponde à votre marque ou pour configurer le chargeur :

Cliquez pour payer (CTP) avec Passkey

Contrairement à d'autres processus, lorsqu'un utilisateur effectue un paiement à l'aide de CTP Passkey, le Token à usage unique (OTT) ne seront pas reçus par les méthodes de rappel habituelles. L'OTT sera livré via le URL de lien profond dans l'intention. Votre application doit le lire à partir du Intent, créez le paiement dans votre backend, puis poursuivez le flux avec le SDK.

⚠️

Important

C'est essentiel inclure un callback_url lors de la création de la session de paiement pour les paiements CTP Passkey. Cette URL doit correspondre au schéma de lien profond configuré dans votre AndroidManifest. Par exemple :

{
  "callback_url": "myapp://pay/ctp"
}

Le champ callback_url est utilisé pour rediriger le client vers votre application une fois le processus d'authentification par mot de passe terminé.

1. AndroidManifest (lien profond)

Ajoutez un intent-filter à votre activité principale dans AndroidManifest.xml:

<activity android:name=".CheckoutActivity" android:exported="true">
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <!-- Adjust to your actual scheme/host -->
    <data android:scheme="myapp" android:host="pay" android:pathPrefix="/ctp" />
  </intent-filter>
</activity>

Réglez le scheme, hostet  pathPrefix pour correspondre à la configuration de votre application.

2. Traiter l'intention

Dans votre activité, traitez l'intention dans les deux cas. onCreate()  et  onNewIntent():

class CheckoutActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initYuno()
        startCheckout()
        // Initialize your SDK / UI
        handleDeeplink(intent)
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        handleDeeplink(intent)
    }

    private fun handleDeeplink(intent: Intent?) {
        val uri = intent?.data ?: return

        when {
            // Cancellation or error
            uri.getBooleanQueryParameter("has_error", false) -> {
                val message = uri.getQueryParameter("message") ?: "Operation canceled"
                showError(message)
            }

            // Success: OTT received in URL
            uri.getQueryParameter("one_time_token") != null -> {
                val ott = extractOtt(uri) ?: return
                val checkoutSession = extractCheckoutSession(uri)

                // 1) Send the OTT to your backend to create the payment
                createPaymentOnBackend(ott) { success ->
                    if (success && checkoutSession != null) {
                        // 2) Then continue the flow in the SDK
                        continuePayment(
                            checkoutSession = checkoutSession,
                            countryCode = currentCountry
                        ) { result ->
                            // Handle payment state
                        }
                    }
                }
            }
        }
    }
    
    private fun extractOtt(uri: Uri): String? =
        uri.getQueryParameter("one_time_token")

    private fun extractCheckoutSession(uri: Uri): String? =
        uri.getQueryParameter("checkout_session")
            ?: uri.getQueryParameter("checkoutSession")
}

3. Créer le paiement (backend)

Une fois que vous avez extrait l'OTT du lien profond, créez le paiement sur votre backend à l'aide du endpoint Create Payment.

Après avoir reçu une réponse positive de votre backend (paiement créé), poursuivez le flux dans le SDK en appelant continuePayment().

4. Fonctions d'aide

Créer des fonctions d'aide pour extraire les paramètres de l'URI d'intention :

private fun extractOtt(uri: Uri): String? =
    uri.getQueryParameter("one_time_token")

private fun extractCheckoutSession(uri: Uri): String? =
    uri.getQueryParameter("checkout_session")
        ?: uri.getQueryParameter("checkoutSession")
💡

Conseil

Dans les environnements d'assurance qualité, enregistrez l'URL complète pour vérifier les noms des paramètres.

5. Test rapide

Vous pouvez tester le flux CTP Passkey à l'aide de ces exemples d'URL de liens profonds :

  • Succès : myapp://pay/ctp?one_time_token=OTT_123&checkout_session=CHK_456
  • Erreur : myapp://pay/ctp?has_error=true&message=User%20canceled
  • Suite : myapp://pay/ctp

6. Liste de contrôle

Utilisez cette liste de contrôle pour vous assurer que l'intégration de CTP Passkey est correcte :

  • callback_url inclus lors de la création de la session de paiement (doit correspondre au schéma de lien profond)
  • intent-filter correctement configuré (schéma/hôte/chemin)
  • handleDeeplink mis en œuvre dans les deux onCreate()  et  onNewIntent()
  • ✅ Extraire les deux one_time_token  et  checkout_session paramètres
  • ✅ Créer un paiement en arrière-plan avec OTT ➜ appeler continuePayment(...)
  • ✅ Poignée has_error  et  message paramètres pour les scénarios d'erreur
⚠️

Important

L'OTT va pas être reçu par le biais du callbackOTT fonction pour les paiements CTP Passkey. Vous devez plutôt extraire le token paramètres URI Intent.

styles

Avec l'option de personnalisation styles , vous pouvez définir des styles visuels globaux via un objet YunoStyles . Il vous permet d'appliquer une image de marque cohérente dans tout le SDK en personnalisant l'apparence des boutons et la typographie.

classe de données YunoStyles(
    val buttonStyles: YunoButtonStyles? = null,
    val fontFamily: FontFamily? = null
)
ParamètresDescription
buttonStylesPersonnalise les boutons principaux affichés dans le SDK.
fontFamilyDéfinit la famille de polices utilisée sur tous les éléments de texte du SDK.

Le champ YunoButtonStyles vous permet de définir des paramètres spécifiques pour l'apparence des boutons :

data class YunoButtonStyles(
    val backgroundColor : Couleur ? = null,
    val contentColor : Couleur ? = null,
    val cornerRadius : Dp ? = null,
    val elevation : Dp ? = null,
    val padding : Dp ? = null,
    val fontFamily : FontFamily ? = null,
    val fontSize : TextUnit ? = null,
    val fontStyle : FontStyle ? = null
)

Pour utiliser styles , utilisez la classe de données YunoConfig décrite à l'étape 2.

Loader

La fonctionnalité du loader est contrôlée par le paramètre keepLoader dans la classe de données YunoConfig qui est documentée en ligne dans la section de configuration du SDK ci-dessus.

Sauvegarde de carte pour les futurs paiements

Vous pouvez afficher une case à cocher pour sauvegarder ou enregistrer des cartes en utilisant cardSaveEnable: true. Les exemples suivants montrent la case à cocher pour les deux rendus de formulaire de carte :

Options de rendu

Vous pouvez choisir entre deux options de rendu de formulaire de carte. Les captures d'écran suivantes montrent la différence entre cardFormType ONE_STEP  et  STEP_BY_STEP:

Personnalisations du SDK

Vous pouvez modifier l'apparence du SDK pour qu'elle corresponde à votre marque. Pour plus d'informations, consultez la personnalisations du SDK.

📘

Application Démo

En plus des exemples de code fournis, vous pouvez accéder au dépôt Yuno pour une implémentation complète des SDK Android de Yuno.