Guide d'intégration Android
- Ajouter le SDK de paiement à votre application
- Initialiser le SDK
- Réaliser un paiement
- Vérifier le statut de la transaction
Sur cette page vous pouvez trouver comment :
- Consulter nos exemples d'intégration
- Personnaliser le SDK
- Annuler un paiement en cours
- Activer la fonctionnalité NFC
- Activer la fonctionnalité de scan de la carte par caméra
Consulter nos exemples d'intégration
Vous trouverez de nombreux exemples de codes d'intégration de notre SDK dans différents langages dans le dépôt Github.
Ajouter le SDK de paiement à votre application
Pour ajouter le SDK de paiement à votre application, il est nécessaire d'ajouter la dépendance suivante dans votre build.gradle :
implementation 'com.lyra:sdk:1.5.+'
Nous vous conseillons de mettre à jour régulièrement le SDK de paiement, afin de garantir une sécurité optimale de vos paiements.
Pour être tenu informé des nouvelles versions du SDK, vous pouvez consulter régulièrement notre repository GitHub.
Optimisation de l'efficacité de notre support
Notre SDK peut envoyer des messages Sentry vers nos serveurs lorsqu'une situation inhabituelle ou un problème survient. Dans ce cas, aucune donnée sensible n'est transférée ni aucune donnée de votre application.
Uniquement si votre minSdkVersion est <= 23, il est alors nécessaire de suivre la procédure suivante https://developer.android.com/studio/write/java8-support afin de permettre aux devices Android <= 6 de bénéficier de l'envoi des messages sentry. Lors du filtrage des données sensibles, notre SDK utilise du code Java8.
En résumé, voici les modifications à apporter au build.gradle de votre application :
// only if your minSdkVersion <= 23 android { compileOptions { // Flag to enable support for the new language APIs coreLibraryDesugaringEnabled = true // Sets Java compatibility to Java 8 sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } } dependencies { // Needed by coreLibraryDesugaringEnabled compileOptions coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5") }
Initialiser le SDK
Comme mentionné dans le chapitre sur le fonctionnement de la solution, il est nécessaire d'effectuer l'initialisation du SDK au lancement de votre application, typiquement dans la méthode « onCreate » de votre activité principale.
Pour cela, il suffit d'appeler la méthode Lyra.initialize avec les paramètres suivants :
Paramètre | Format | Description |
---|---|---|
publicKey | String | Votre clé publique (disponible dans le |
options | HashMap | Map permettant de configurer le SDK: NFC, scan de la carte |
{:.lita-excluded-col1.lita-excluded-col2} Exemple d'appel :
val options = HashMap<String, Any>() options[Lyra.OPTION_API_SERVER_NAME] = "MY_API_SERVER_NAME" Lyra.initialize(applicationContext, PUBLIC_KEY, options)
HashMap options = new HashMap(); options.put(Lyra.OPTION_API_SERVER_NAME, "MY_API_SERVER_NAME"); Lyra.INSTANCE.initialize(getApplicationContext(), PUBLIC_KEY, options);
Les clés possibles dans ce dictionnaire sont :
Clés | Format valeur | Description | Requis |
---|---|---|---|
apiServerName | String | Nom du serveur de l’API REST (disponible dans le | Requis |
cardScanningEnabled | Bool | Active/Désactive la fonctionnalité de scan de la carte par caméra. Si elle n’est pas définie, la fonctionnalité sera désactivée. | Optionnel |
nfcEnabled | Bool | Active/Désactive la fonctionnalité de scan de la carte par NFC. Si elle n’est pas définie, la fonctionnalité sera désactivée. | Optionnel |
Attention : cette méthode peut renvoyer une erreur si l'initialisation du SDK a échoué. Merci de consulter la page sur la Gestion des erreurs pour résoudre la situation. Il faut aussi noter que le SDK ne permet pas de faire plusieurs process en parallèle. Durant le traitement du premier appel, les autres appels seront ignorés (pas de callback, pas d'exception).
Réaliser un paiement
La réalisation d'un paiement se décline en 2 étapes : l'initialisation de l'affichage du formulaire, et le traitement du paiement proprement dit.
Initialisation de l'affichage du formulaire de paiement
Lorsque l'utilisateur décide de payer, vous pouvez initialiser l'affichage du formulaire de paiement.
Pour cela, vous devez appeler votre serveur marchand, pour y vérifier les achats de l'utilisateur, puis générer un identifiant de formulaire (appelé formToken) en appelant le Web Service Charge/CreatePayment (toujours depuis votre serveur marchand). Dans cette requête, vous devez passer un paramètre formTokenVersion qui correspond au résultat de la méthode getFormTokenVersion du SDK. La réponse du Web Service ou cet identifiant de formulaire doit ensuite être renvoyé à votre application mobile.
Voici un code exemple se basant sur les exemples de code Android et le serveur marchand mis à votre disposition.
requestQueue.add(JsonObjectRequest(Request.Method.POST, "${SERVER_URL}/createPayment", paymentParams, Response.Listener { response -> //Extract the formToken from the serverResponse val answer = JSONObject(response).getJSONObject("answer") val formToken = answer.getString("formToken") //Now, call Lyra.process() with the formToken }, Response.ErrorListener { error -> //Please manage your error behaviour here Toast.makeText( applicationContext, "Error Creating Payment", Toast.LENGTH_LONG ).show() } ))
requestQueue.add(new JsonObjectRequest(Request.Method.POST, SERVER_URL + "/createPayment", getPaymentParams(), new Response.Listener<JSONObject>() { //Process merchant server response @Override public void onResponse(JSONObject response) { //Extract the formToken from the serverResponse JSONObject answer = new JSONObject(response).getJSONObject("answer"); String formToken = answer.getString("formToken"); //Now, call Lyra.process() with the formToken } }, new Response.ErrorListener() { //Error when calling merchant server @Override public void onErrorResponse(VolleyError error) { //Please manage your error behaviour here Toast.makeText(getApplicationContext(), "Error Creating Payment", Toast.LENGTH_LONG).show(); } }));
Important : n'appelez pas le Web Service Charge/CreatePayment depuis votre application mobile !
- L'étape de validation du panier est une étape cruciale, et il vous revient de vérifier sur vos serveurs que le montant correspond bien au panier avant de nous le transmettre.
- Appeler le Web Service depuis l'application mobile revient à mettre à sa disposition (à des pirates potentiels) vos clés d'appels, ce qui est contraire aux règles de sécurité.
Affichage de l'écran de paiement
Une fois le formToken reçu dans l'application mobile, vous devez le transmettre à notre SDK de paiement en appelant la méthode Lyra.process avec les paramètres suivants :
Paramètre | Format | Description |
---|---|---|
supportFragmentManager | FragmentManager | Référence vers votre UI afin que le SDK puisse afficher le formulaire de paiement. |
formToken | String | Le formToken, extrait de la réponse du createPayment précédemment appelé. |
paymentHandler | LyraHandler | Callback pour traiter le résultat du paiement. |
{:.lita-excluded-col1.lita-excluded-col2} Le SDK se charge alors de vérifier la cohérence du formToken puis affiche les moyens de paiements disponibles.
Exemple d'appel :
Lyra.process(supportFragmentManager, formToken, object : LyraHandler { override fun onSuccess(lyraResponse: LyraResponse) { verifyPayment(lyraResponse) } override fun onError(lyraException: LyraException, lyraResponse: LyraResponse?) { Toast.makeText( applicationContext, "Payment fail: ${lyraException.errorMessage}", Toast.LENGTH_LONG ).show() } })
Lyra.INSTANCE.process(getSupportFragmentManager(), formToken, new LyraHandler() { @Override public void onSuccess(LyraResponse lyraResponse) { verifyPayment(lyraResponse); } @Override public void onError(LyraException e, LyraResponse lyraResponse) { Toast.makeText(getApplicationContext(), "Payment fail: " + e.getErrorMessage(), Toast.LENGTH_LONG).show(); } });
Le paymentHandler est une interface que vous devez implémenter et qui contient 2 méthodes :
Callback | Description |
---|---|
onSuccess | Appelée si le paiement s'est déroulé correctement. |
onError | Cette méthode est appelée si le paiement est en échec ou n'a pu être initié. Cette situation peut se produire si une erreur fonctionnelle (le paiement a été refusé) ou technique est survenue pendant le paiement. Pour en savoir plus consulter: Gestion des erreurs. |
Description de l'objet LyraResponse
Le même objet LyraResponse est retourné dans les deux cas : onSuccess et onError. C'est un objet de type JSONObject. En cas de succès, il est nécessaire de vérifier son intégrité avant d'afficher le résultat du paiement.
Dans le cas où la transaction a été initiée coté serveur, il sera possible de récupérer simplement les informations du paiement.
Exemple :
{ "kr-hash":"80f5188e757c1828e8d4ccab87467eb50c4299e4057fa03b3f3185342f6d509c", "kr-hash-algorithm":"sha256_hmac", "kr-answer-type":"V4\/Payment", "kr-answer": "{ "shopId":"65512466", "orderCycle":"CLOSED", "orderStatus":"PAID", "serverDate":"2019-03-01T10:54:45+00:00", "orderDetails":{ "orderTotalAmount":1100, "orderEffectiveAmount":1100, "orderCurrency":"EUR", "mode":"TEST", "orderId":null, "_type":"V4\/OrderDetails" }, "customer":{ "billingDetails":{ "address":null, "category":null, "cellPhoneNumber":null, ... }, "email":null, "reference":null, "shippingDetails":{ "address":null, "address2":null, "category":null, ... }, "extraDetails":{ "browserAccept":null, "fingerPrintId":null, "ipAddress":"77.136.84.251", "browserUserAgent":"{\"deviceName\":\"Xiaomi Mi MIX 2S\",\"os\":\"Android\",\"osVersion\":\"[9]\",\"sdkVersion\":28,\"isMobile\":true}", "_type":"V4\/Customer\/ExtraDetails" }, "shoppingCart":{ "insuranceAmount":null, "shippingAmount":null, "taxAmount":null, "cartItemInfo":null, "_type":"V4\/Customer\/ShoppingCart" }, "_type":"V4\/Customer\/Customer" }, "transactions":[ { "shopId":"65512466", "uuid":"64d704a9bb664898954c3ef537982f99", "amount":1100, "currency":"EUR", "paymentMethodType":"CARD", "status":"PAID", "detailedStatus":"AUTHORISED", "operationType":"DEBIT", "creationDate":"2019-03-01T10:54:44+00:00", ... } ], "_type":"V4\/Payment" }" }
La réponse contient les mêmes éléments que ceux envoyés dans l'IPN :
Paramètre | Description |
---|---|
kr-hash | Hash de l'objet JSON stocké dans kr-answer. Il permet de vérifier l'authenticité de la réponse |
kr-hash-algorithm | Algorithme utilisé pour calculer le hash |
kr-hash-key | Clé utilisée pour signer kr-answer. |
kr-answer-type | Type de l'objet JSON contenu dans kr-answer |
kr-answer | Objet contenant les objets transactions complets encodés en JSON |
L'objet kr-answer contient les éléments décrits ici.
Dans certains cas, il se peut que la transaction n'ait pu être initiée coté serveur. Il sera possible de retrouver l'erreur renvoyée par l'API dans le json (vous trouverez le format ici : Codes d'erreur).
Vérifier le statut de la transaction
Une fois le paiement terminé, qu'il soit accepté ou refusé, vous serez notifié de 2 manières :
- par un appel (IPN) vers votre serveur marchand, si vous avez correctement configuré les règles de notifications,
- par l'appel du paymentHandler coté application mobile.
Il est nécessaire de vérifier l'intégrité du message (voir ici pour plus de détails), et de lancer les traitements métiers coté serveur (lors de la réception de l'IPN).
Nos exemples de code fournissent un exemple de contrôle d'intégrité du message via votre serveur marchand, il s'agit du endPoint verifyResult appelé dans la méthode verifyResult de l'application.
Voici un code exemple se basant sur les exemples de code Android et le serveur marchand mis à votre disposition.
requestQueue.add(JsonObjectRequest(Request.Method.POST, "${SERVER_URL}/verifyResult", payload, Response.Listener { response -> //Check the response integrity by verifying the hash on your server Toast.makeText( applicationContext, "Payment success", Toast.LENGTH_LONG ).show() }, Response.ErrorListener { error -> //Manage error here, please refer to the documentation for more information Toast.makeText( applicationContext, "Payment verification fail", Toast.LENGTH_LONG ).show() } ))
requestQueue.add(new JsonObjectRequest(Request.Method.POST, SERVER_URL + "/verifyResult", response, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { //Check the response integrity by verifying the hash on your server Toast.makeText(getApplicationContext(), "Payment Success", Toast.LENGTH_LONG).show(); } }, new Response.ErrorListener() { //Error when verifying payment @Override public void onErrorResponse(VolleyError error) { //Manage error here, please refer to the documentation for more information Toast.makeText(getApplicationContext(), "Payment verification fail", Toast.LENGTH_LONG).show(); } }));
Personnaliser le SDK
Thème
Il est possible de personnaliser le SDK, de sorte que les vues générées à partir du SDK (formulaire de paiement) soient affichées avec les mêmes couleurs et la même police que celles utilisées dans votre application.
Vous pouvez définir :
- une couleur principale,
- une couleur secondaire,
- la police à utiliser sur l'ensemble des textes affichés dans le SDK.
La couleur principale permet de modifier :
- la couleur de fond de l'entête,
- la couleur de fond du bouton "Payer",
- la couleur de mot de fermeture de la popup d'aide au CVV,
- la couleur de mot de fermeture de la popup du choix de la marque,
- la couleur du surlignage et libellé du champ lorsque celui-ci est édité,
- la couleur du texte dans le message de paiement en cours,
- la couleur du spinner dans le message de paiement en cours.
La couleur secondaire permet de modifier :
- la couleur du logo de la flèche de retour arrière dans l'entête du SDK,
- la couleur des textes dans l'entête du SDK,
- la couleur du texte dans le bouton "Payer".
Pour personnaliser les couleurs, il suffit de les définir dans votre fichier colors.xml :
<color name="payment_sdk_PrimaryColor">#293C7A</color>
<color name="payment_sdk_SecondaryColor">#FFFFFF</color>
Pour personnaliser la police vous devez juste surcharger le style nécessaire dans le fichier styles.xml :
<style name="PaymentSDK_Theme">
<item name="android:fontFamily"></i>casual</item></style>
Textes
Il est aussi possible de personnaliser certains textes. Pour cela, spécifier le paramètre optionnel "options" lors de l'appel au Lyra.process().
Bouton PAYER
- Le texte du bouton PAYER peut être personnalisé.
Spécifier la clé Lyra.CUSTOM_PAY_BUTTON_LABEL
.
Entête
- Si le texte est forcé et qu'il n'y a pas d'orderId, il remplacera le texte par défaut qui est "Paiement" ou "Enregistrement de la carte".
- Par contre, si un orderId est précisé alors, on continuera à afficher "Commande OrderId".
Spécifier la clé Lyra.CUSTOM_HEADER_LABEL
.
Popup de paiement
- Le texte de la popup qui s'ouvre suite au clic sur le bouton PAYER peut aussi être personnalisé.
Spécifier la clé Lyra.CUSTOM_POPUP_LABEL
.
Lyra.process(supportFragmentManager, formToken, LyraHandler, hashMapOf(Lyra.CUSTOM_PAY_BUTTON_LABEL to "MyPayButtonLabel", Lyra.CUSTOM_HEADER_LABEL to "MyHeaderLabel", Lyra.CUSTOM_POPUP_LABEL to "MyPopupLabel"))
Annuler un paiement en cours
Il est possible d'annuler un paiement en cours en utilisant la méthode Lyra.cancelProcess(). En général, cette méthode permet de quitter correctement le formulaire de paiement mais il existe différents scénarios :
- Le processus de paiement peut être annulé :
- le formulaire de paiement se ferme correctement.
- le handler onError qui est passé au Lyra.process() est appelé avec l'erreur "MOB_009 - Payment cancelled", indiquant que le processus de paiement a été annulé.
- Le processus de paiement ne peut pas être annulé. Si le Lyra.cancelProcess() est invoqué pendant que le SDK est en communication avec la plateforme de paiement (l'utilisateur vient de cliquer sur le bouton payer) :
- le formulaire de paiement reste affiché.
- le handler onError qui est passé au Lyra.process() est appelé avec l'erreur "MOB_013 - Payment cannot be cancelled", indiquant que le processus de paiement ne peut pas être annulé.
- le comportement normal du SDK se poursuit :
- si le paiement se termine correctement alors le handler onSuccess sera appelé.
- si le paiement est en échec. Suivant l'erreur, le formulaire de paiement reste affiché ou le handler onError sera appelé.
- S'il n'y a pas de processus de paiement en cours, l'appel au Lyra.cancelProcess() n'aura aucun effet.
Activer la fonctionnalité NFC
Il est possible, dans le SDK, d’activer la fonctionnalité NFC. Cette fonctionnalité permet à un utilisateur de ne pas saisir les informations de sa carte manuellement mais d'utiliser le NFC pour la scanner et remplir automatiquement le formulaire de paiement.
Pour activer cette fonctionnalité, vous devez :
- Lors de l'initialisation du SDK, envoyer true comme valeur pour la clé nfcEnabled dans les options de configuration (Voir Initialiser le SDK).
options[Lyra.OPTION_NFC_ENABLED] = true
options.put(Lyra.OPTION_NFC_ENABLED, true);
- Ajouter la permission suivante dans le fichier AndroidManifest.xml de votre application :
<uses-permission android:name="android.permission.NFC" />
Activer la fonctionnalité de scan de la carte par caméra
Il est possible, dans le SDK, d’activer la fonctionnalité de scan de la carte par caméra. Cette fonctionnalité permet à un utilisateur de ne pas saisir les informations de sa carte manuellement mais d'utiliser la caméra de son appareil mobile pour la scanner et remplir automatiquement le formulaire de paiement.
Pour activer cette fonctionnalité, vous devez :
- Intégrer la librairie CardsCameraRecognizer dans votre projet Android en ajoutant la dépendance suivante à votre build.gradle :
// Lyra Cards Camera Recognizer SDK
implementation 'com.lyra:cards-camera-recognizer:1.0.+'
- Lors de l'initialisation du SDK, envoyer true comme valeur pour la clé cardScanningEnabled dans les options de configuration (Voir Initialiser le SDK).
options[Lyra.OPTION_CARD_SCANNING_ENABLED] = true
options.put(Lyra.OPTION_CARD_SCANNING_ENABLED, true);
A noter que les permissions suivantes seront directement ajoutées dans le fichier AndroidManifest.xml lors de la compilation du projet :
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-feature android:name="android.hardware.CAMERA" android:required="false" />
<uses-feature android:name="android.hardware.camera.AUTOFOCUS" android:required="false" />