Android integration guide

This page provides information on how to:

In order to optimize the efficiency of our support service, our SDK can send Sentry messages to our servers when an unusual situation or problem occurs. In this case, no sensitive data or data from your application is transferred.

View our integration examples

You will find many examples of our SDK''s integration codes in different languages in the Github repository.

Add the the payment SDK to your application

To add the payment SDK to your application, it is necessary to add the following dependency in your build.gradle :

implementation 'com.lyra:sdk:1.0.+'

We recommend to regularly update the payment SDK in order to guarantee optimal security of your payments.

You can regularly check our GitHub repository to follow new SDK releases.

Initialize the SDK

As mentioned in the chapter on the solution operation, it is necessary to perform the SDK initialization when launching your application, usually in the "onCreate" method of your core business.

To do this, simply call the Lyra.initialize method with the following parameters:

Parameter Format Description
publicKey String Your public key (available in the Merchant BO: Settings -> Shop -> REST API keys, see the Prerequisites page).
options HashMap Map allowing to configure the SDK: NFC, card scan.

Example of a call:

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

The possible keys in this dictionary are:

Keys Value format Description Required
apiServerName String Your REST API server name (available in the Merchant BO: Settings -> Shop -> REST API keys), see the Prerequisites page). Required
cardScanningEnabled Bool Enables/disables the card scan feature using the camera. If it is not defined, the feature will be disabled. Optional
nfcEnabled Bool Enables/disables the card scan feature via NFC. If it is not defined, the feature will be disabled. Optional

Warning: this method may return an error if the SDK initialization has failed. Please refer to the page on Error handling to resolve the issue. It should also be noted that the SDK does not allow several processes to be carried out simultaneously. During the processing of the first call, the other calls will be ignored (no callback, no exceptions).

Make a payment

The payment process occurs in 2 steps: the initialization of the form display, and the processing of the payment itself.

Initialize the display of the payment form

When the user decides to pay, you can initialize the payment form display.

To do this, you need to call your merchant server in order to check the user''s purchases, and then generate a form identifier (formToken) by calling the Charge/CreatePayment web service (also from your merchant server). In this query, you must pass a formTokenVersion parameter that corresponds to the result of the getFormTokenVersion method of the SDK. The web service response or this form identifier must then be returned to your mobile application.

Here is a sample code based on the Android code examples and the provided merchant server.

    requestQueue.add(JsonObjectRequest(Request.Method.POST,
    "${SERVER_URL}/createPayment",
    paymentParams,
    Response.Listener { response ->
        processPayment(response.toString())
    },
    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) {
            //In this sample, the processPayment checks the response and will call the process method of the SDK if the response is good.
            processPayment(response);
        }
    }, 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: do not call the Charge/CreatePayment web service from your mobile application!

  • The step of validating the cart is crucial. Before you transmit it to us, you must check on your servers that the amount corresponds to the one in the cart,
  • Calling the web service from the mobile application is amounts to making your call keys available to it (and to potential hackers), which is contrary to the security rules.

Display the payment screen

Once the formToken is received in the mobile application, you must transmit it to our payment SDK by calling the Lyra.processPayment method with the following parameters:

Parameter Format Description
supportFragmentManager FragmentManager Reference to your UI so that the SDK can display the payment form.
createPaymentResponse String Response from the previously called createPayment.
paymentHandler LyraHandler Callback to process the payment result.

The SDK then checks the formToken consistency and displays the available payment methods.

Example of a call:

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

The paymentHandler is an interface that must be implemented. It contains 2 methods:

Callback Description
onSuccess Called if the payment was successful.
onError This method is called if the payment fails. This situation can happen if a functional (refused payment) or technical error occurred during the payment. For more information, see: Error handling.

Description of the LyraResponse object

The same LyraResponse object is returned in both cases: onSuccess and onError. In case of success, it is necessary to check its integrity before displaying the payment result.

It is a JSONObject type object, therefore, it is possible to simply retrieve the payment information, if necessary.

Example:

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

The response contains the same elements as the ones sent in the IPN. The 4 parameters correspond to:

Parameter Description
kr-hash Hash of the JSON object stored in kr-answer. It allows to verify the authenticity of the response.
kr-hash-algorithm Algorithm used to calculate the hash.
kr-hash-key Key used for signing kr-answer.
kr-answer-type Type the JSON object stored in kr-answer.
kr-answer Object containing complete transaction objects encoded in JSON.

The kr-answer object contains the elements described here.

Check the transaction status

Once the payment has been finalized, regardless of whether was accepted or rejected, you will be notified in two 2 ways:

  • Via a call (IPN) to your merchant server, if the Merchant is registered on our payment gateway,
  • By calling the paymentHandler on the mobile application side.

It is necessary to check the integrity of the message (go here for more details), and to launch business processing on the server side (when the IPN is received).

Our sample code provides an example of message integrity check via your merchant server, i.e. the verifyResult endPoint called in the verifyResult method of the application.

Here is a sample code based on the Android code examples and the provided merchant server.

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

Customize the SDK

It is possible to customize the SDK so that the views generated via the SDK (payment form) are displayed with the same colors and font as those used in your application.

You can define:

  • One main color,
  • A secondary color,
  • The font to apply.

To customize the colors, just define them in your file colors.xml :

<color name="payment_sdk_PrimaryColor">#293C7A</color>
<color name="payment_sdk_SecondaryColor">#FFFFFF</color>

To customize the font you just need to override the necessary style in the file styles.xml :

<style name="PaymentSDK_Theme">
    <item name="android:fontFamily">casual</item>
</style>

Enable NFC feature

It is possible to enable the NFC functionality in the SDK. This feature allows a user not to enter their card information manually and, instead, to use NFC to scan the card and fill out the payment form automatically.

To enable this feature, you need to:

  1. When initializing the SDK, send true as a value for the nfcEnabled key in the configuration options (see Initializing the SDK).

     options[Lyra.OPTION_NFC_ENABLED] = true
                 
     options.put(Lyra.OPTION_NFC_ENABLED, true);
                 
  2. Add the following permission to your manifest:

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

Enable the card scanning feature

You can activate the camera card scan feature in the SDK. This feature allows a user to avoid entering their card information manually and, instead, use the camera on their mobile device to scan it and fill out the payment form automatically.

To enable this feature, you need to:

  1. Integrate the CardsCameraRecognizer library into your Android project by adding the following dependency to your build.gradle:
    // Lyra Cards Camera Recognizer SDK
    implementation 'com.lyra:cards-camera-recognizer:1.0.+'
  1. When initializing the SDK, send true as a value for the cardScanningEnabled key in the configuration options (see Initializing the SDK).

     options[Lyra.OPTION_CARD_SCANNING_ENABLED] = true
                 
     options.put(Lyra.OPTION_CARD_SCANNING_ENABLED, true);
                 

Please note that the following permissions will be directly added/merged in the final manifest:

<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" />

Copyright