Android SDK

The Ravelin Mobile SDKs are critical to our ability to provide informed decisions to our clients.

Like the JavaScript library, the SDK enables:

  • The generation of a unique and persistent device ID
  • The collection of additional device details
  • Session tracking
  • If relevant to your integration, the encryption of card details

We have two modules/dependencies within the SDK:

  • ravelin-core - Which is used for deviceId, fingerprinting and tracking activity
  • ravelin-encrypt - for card details encryption

You can choose what functionality of the SDK you would like to use. However, at a mimimum we advise that you use the SDK to generate a reliable device ID and to send the additional device details for your app traffic. Device IDs are critical throughout our fraud prevention tool, especially for use in our graph database.

Getting Started

Before you can integrate with the Ravelin mobile SDK for Android, you will need:

  • read access to our CloudRepo repository
  • valid API keys which are available in the Ravelin Dashboard. See Authentication for where to find these.
  • valid username and password for the private Ravelin Maven/CloudRepo repository

If you have any questions on getting started, please ask us in your Ravelin support channel on Slack.

Contents

Minimum Requirements

The SDK supports a minimum Android API level: 15 - 4.0.3 ICE_CREAM_SANDWICH_MR1 with some exceptions around encryption written up below.

For Encryption:

If you would like to use encryption it’s only available for Android API level: 22 5.1 LOLLIPOP_MR1, where you can use the ravelin-encrypt module which relies on native encryption.

Installing the Ravelin Android SDK

There are two methods of installing the Ravelin Android SDK: via Gradle, or manually with a precompiled AAR file. Our preferred method is through Gradle, due to its ease of maintenance.

Installing via Gradle

Before attempting to use Gradle for Ravelin, ensure that you have a valid username and password for the private Maven repository. This can be obtained from a Ravelin integrations engineer.

IMPORTANT - Do not store the repository credentials within Source Control. They can be stored in the user’s gradle.properties

// ~/.gradle/gradle,properties

ravelinRepoUsername=username
ravelinRepoPassword=password

Within the Project level build.gradle, make sure the repositories include the appropriate Ravelin maven repository:

allprojects {
   repositories {
      /* other repositories */
      maven {
         credentials {
            username "$ravelinRepoUsername"
            password "$ravelinRepoPassword"
         }
         url "https://maven.ravelin.com/repositories/releases/"
      }
   }
}

Then in the Module level build.gradle add Ravelin to the app dependencies:

dependencies {
    /* other dependencies */
    implementation 'com.ravelin.sdk:ravelin-core:1.0.0'
    implementation 'com.ravelin.sdk:ravelin-encrypt:1.0.0'
}

Use ravelin-core for deviceId, fingerprinting and tracking activity and ravelin-encrypt if using card encryption.

Installing Manually

The Ravelin library may be imported as a standard AAR. Please be advised that we do not recommend manual installation and strongly advise that you use Gradle.

Into the Project level build.gradle make sure the repositories include the local libraries directory. Assuming that the AARs are stored within lib:

allprojects {
   repositories {
      /* other repositories */
      flatDir {
        dirs 'libs'
      }
   }
}

Then in the Module level build.gradle, add Ravelin to the app dependencies:

dependencies {
    implementation(name:'ravelin', ext:'aar')
}

Updating the Ravelin Android SDK

There are two methods of updating the Ravelin Android SDK: via Gradle, or manually with a precompiled AAR file. Our preferred method is through Gradle, due to its ease of maintenance.

Updating via Gradle

In the Module level build.gradle change the dependencies to the latest SDK version number.

dependencies {
    /* other dependencies */
    implementation 'com.ravelin.sdk:ravelin-core:1.0.0'
    implementation 'com.ravelin.sdk:ravelin-encrypt:1.0.0'
}

Use ravelin-core for deviceId, fingerprinting and tracking activity and ravelin-encrypt if using card encryption.

To verify the latest Ravelin SDK version check our Release Notes section.

Updating Manually

The Ravelin library may be imported as a standard AAR. Please be advised that we do we do not recommend manual update and strongly advise that you use Gradle.

Please flow the same steps mentioned in the Installing Manually section and make sure you are using the latest sdk version AAR.

Permissions

For a better experience with Ravelin SDK each app has to provide a way for accessing users information. Here is a list of what each permission allows us to get from the users:

ACCESS_COARSE_LOCATION

Information about users localization

  • Accuracy
  • Altitude
  • Bearing
  • ElapsedRealTimeNanos
  • Latitude
  • Logitude
  • Provider
  • Speed
  • Time

READ_PHONE_STATE

Information about users phone

  • IsWorldPhone

BLUETOOTH

Informatin about devices bluetooth.

  • Bluetooth MAC

ACCESS_WIFI_STATE

Informatin about devices wireless connection interface.

  • WIFI MAC

INTERNET

Allows internet connection access to background processes.

The SDK will retry events in case of issues like no internet connection or server errors. Since the retry is a background process that relies on internet connection this permission is need for the retry functionality to work. If you do not grant this permission the retry functionality will not work and silently fail.

Usage

Please ensure only the publishable API key is used. The live secret API key should never be embedded into the app – it should only be used for server-to-server communications.

Accessing the Singleton

The Ravelin Android SDK has two static instance accessors:

  1. RavelinSDK.createInstance
  2. RavelinSDK.getSharedInstance

These both access the singleton if it has already been created, however, the instance must be created first. Calling getSharedInstance before an instance has been created will pass a RavelinError to the RavelinCallback#failure callback.

Calling RavelinSDK#createInstance a second time will not create a second instance but will instead return a previously created instance.

Kotlin

First call:

// MyApplication.kt

// using callbacks
RavelinSDK.createInstance(this, "publishable_key_live",) object : RavelinCallback<RavelinSDK>() {
    override fun success(ravelin : RavelinSDK) {
        Log.e("Ravelin Setup Success", "hooray")
    }

    override fun failure(error: RavelinError) {
        Log.e("Ravelin Setup Error", error.message)
    }
})

// not using callback
val ravelin: RavelinSDK? = RavelinSDK.createInstance(this, "publishable_key_live",)

Subsequent calls:

// MyActivity.kt

// using callback
RavelinSDK.getSharedInstance(object : RavelinCallback<RavelinSDK>() {
    override fun success(ravelin : RavelinSDK) {
        Log.e("Ravelin Setup Success", "hooray")
    }

    override fun failure(error: RavelinError) {
        Log.e("Ravelin Setup Error", error.message)
    }
})

// not using callback
val ravelin: RavelinSDK? = RavelinSDK.getSharedInstance()

Java

First call:

// MyApplication.java

// null-safe inside callback
RavelinSDK.Companion.createInstance(this, "publishable_key_live", new RavelinCallback<RavelinSDK>() {
    @Override
    public void success(RavelinSDK ravelinSDK) {
        Log.e("Ravelin Setup Success", "hooray");
    }

    @Override
    public void failure(@NotNull RavelinError ravelinError) {
        Log.e("Ravelin Setup Error", ravelinError.getMessage());
    }
});

// no callback, not null safe
RavelinSDK ravelin = RavelinSDK.Companion.createInstance(this, "publishable_key_live", );

Subsequent calls:

// MyActivity.java

// null-safe with handled error message
RavelinSDK.getSharedInstance(object : RavelinCallback<RavelinSDK>() {
    override fun success(ravelin : RavelinSDK) {
        Log.e("Ravelin Setup Success", "hooray")
    }

    override fun failure(error: RavelinError) {
        Log.e("Ravelin Setup Error", error.message)
    }
})

// nullable, no error message
RavelinSDK ravelin = RavelinSDK.Companion.getSharedInstance();

After first initialisation, the SDK instance can be referenced anywhere using RavelinSDK.getSharedInstance(...).

Encrypting Cards

Depending on your integration, you may want to encrypt card details via the SDK. The SDK can be used to allow the secure sharing of card information with Ravelin whilst removing the need to handle PCI-compliant data. When collecting the card details, using CardDetails(pan, month, year, nameOnCard). pan, month, year are required, while nameOnCard is optional and may be an empty string.

The CardDetails are then passed into the encryptCard method along with the appropriate RSA key to produce an EncryptedCard instance with encrypted ciphers. Encrypted cards are validated prior to encryption. You can perform this validation yourself by calling CardDetails#validate. The optional callback parameter will inform you of a success or failure. In case of a failure the method returns null, and if successful the newly created valid CardDetails is created with extra values stripped, ready to be encrypted.

Ravelin Android encryption is only available for Android 5.1 LOLLIPOP_MR1 API level: 22 and above, since it uses the native encryption provided within the standard Ravelin SDK.

Validation is performed, confirming that expiry dates are valid and that the PAN is at least 13 characters. Should any validation checks fail, nil is returned from the method. Pass an error by ref to determine the cause of failure if any occurs.

The basic checks performed by the validation are:

  1. PAN length must be greater than 12 digits
  2. the month must be between 1 and 12 inclusive
  3. the year must be between the current year and 50 years in the future

Please note, the use of encryption is entirely optional and not required as part of your integration. If you are confused about whether or not you should use encryption, please contact an integration engineer. If you do not want to use encryption at all, please make sure not to use either encryptCard.

Kotlin

val ravelinSDK = RavelinSDK.getSharedInstance()
val cardDetails = CardDetails("1234 1234 1234 1234", "02", "18", "Dr Jilly McJillson")

// null safe callback
ravelinSDK.encryptCard(cardDetails, "2|rsakeykeykeykeykeykey", object : EncryptCallback<EncryptedCard>() {
    override fun success(encrpytedCard : EncryptedCard) {
        Log.e("Card Encryption Success", "hooray")
    }

    override fun failure(error: EncryptError) {
        Log.e("Card Encryption Error", error.message)
    }
})

// nullable
val encryptedCard = ravelinSDK.encryptCard(cardDetails, "2|rsakeykeykeykeykeykey")

Java

final CardDetails cardDetails = new CardDetails("1234 1234 1234 1234", "02", "18", "Dr Jilly McJillson");
final RavelinSDK ravelin = RavelinSDK.getSharedInstance();

// null safe callback
ravelin.encryptCard(cardDetails, "2|rsakeykeykeykeykeykey", new EncryptCallback<EncryptedCard>() {
    @Override
    public void success(EncryptedCard result) {
        Log.e("Card Encryption Success", "hooray");
    }

    @Override
    public void failure(EncryptError error) {
        Log.e("Card Encryption Error", error.getMessage());
    }
});

// nullable
final CardDetails valid = ravelin.encryptCard(cardDetails, "2|rsakeykeykeykeykeykey");

Card Validation

Kotlin

val cardDetails = CardDetails("1234 1234 1234 1234", "02", "18", "Dr Jilly McJillson")

cardDetail.validate(object : EncryptCallback<CardDetails>() {
    override fun failure(error: EncryptError) {
        Log.d("Card Validation Error", error.message)
    }

    override fun success(result: CardDetails?) {
        Log.d("Card Validation Success", "hooray")
    }
})

final CardDetails valid = cardDetails.validate()

RavelinEncrypt().encryptCard(cardDetail, "RSA-Key",
    object : EncryptCallback<EncryptedCard>() {
        override fun failure(error: EncryptError) {
            Log.d("Card encryption Error", error.message)
        }
        override fun success(result: EncryptedCard?) {
            Log.d("Card encryption Success", result.toString())
        }
    })

Java

final CardDetails cardDetails = new CardDetails("1234 1234 1234 1234", "02", "18", "Dr Jilly McJillson");

// null safe callback
cardDetails.validate(new EncryptCallback<CardDetails>() {
    @Override
    public void success(CardDetails result) {
        Log.e("Card Validation Success", "hooray");
    }

    @Override
    public void failure(EncryptError error) {
        Log.e("Card Validation Error", error.getMessage());
    }
});

// nullable
final CardDetails valid = cardDetails.validate();

RavelinEncrypt().encryptCard(cardDetail, "RSA-Key",
    new EncryptCallback<CardDetails>() {
        public void failure(EncryptError error) {
            Log.d("Card encryption Error", error.getMessage())
        }
        public void success(CardDetails result) {
            Log.d("Card encryption Success", result.toString())
        }
    });

Tracking Activity

Using the Ravelin Android SDK, you can capture various built in events along with your own custom events that can later be viewed in the Ravelin dashboard. This can be very useful for analysts to gain additional context during an investigation. For example, if you can see that a user is going through unexpected parts of your customer journey at a set speed on a new device that could indicate suspicious activity.

Track events may be called with either a RavelinRequestCallback callback or no callback. Using a callback, the network request will be triggered immediately.

These are the available predefined events:

The full documentation is present on the javadocs to better help implementation.

trackFingerprint

To be used at checkout to profile the users device.

Sends the device Fingerprint to Ravelin. If a Fingerprint has not been generated by this point, it will be generated by calling this method.

Ensure that the customerId is set before trackFingerprint() is called.

Only takes an optional callback.

Kotlin

// set Customer ID
ravelin.customerId = "12346578"

// immediately call asynchronously
ravelin.trackPaste(pastedCharacters, "login activity", new RavelinRequestCallback() {
ravelin.trackFingerprint(object : RavelinRequestCallback() {
    override fun success() {
        Log.e("API Request Success", "hooray")
    }

    override fun failure(error: RavelinError) {
        Log.e("API Request Error", error.message)
    }
})

Java

// set Customer ID
ravelin.setCustomerId("12346578")
// immediately call asynchronously
ravelin.trackFingerprint(new RavelinRequestCallback() {
    @Override
    public void success() {
        Log.e("API Request Success", "hooray");
    }
    @Override
    public void failure(RavelinError error) {
        Log.e("API Request Error", error.getMessage());
    }
});

trackPage

To indicate when the user hits a new page. We would like this to be used for every new page or screen the user goes to.

Required pageName, optional payload to be serialized and optional callback.

Kotlin

// immediately call asynchronously
ravelin.trackPage("Product List - Toothbrushes", arrayOf("Custom", "Data"), object : RavelinRequestCallback() {
    override fun success() {
        Log.e("API Request Success", "hooray")
    }

    override fun failure(error: RavelinError) {
        Log.e("API Request Error", error.message)
    }
})

Java

// immediately call asynchronously
ravelin.trackPage("Product List - Toothbrushes", new String[]{"Custom", "Data"}, new RavelinRequestCallback() {
    @Override
    public void success() {
        Log.e("API Request Success", "hooray");
    }

    @Override
    public void failure(RavelinError error) {
        Log.e("API Request Error", error.getMessage());
    }
});

trackSearch

To be used when a user performs a search.

There is an optional searchValue property that can be added to let us know about the search term.

Required pageTitle, optional searchValue to be serialized and optional callback.

Kotlin

// immediately call asynchronously
ravelin.trackSearch("Product List - Toothbrushes", "search value", object : RavelinRequestCallback() {
    override fun success() {
        Log.e("API Request Success", "hooray")
    }

    override fun failure(error: RavelinError) {
        Log.e("API Request Error", error.message)
    }
})

Java

ravelin.trackSearch("Product List - Toothbrushes", "Search value", new RavelinRequestCallback() {
    @Override
    public void success() {
        Log.e("API Request Success", "hooray");
    }

    @Override
    public void failure(RavelinError error) {
        Log.e("API Request Error", error.getMessage());
    }
});

trackSelectOption

To be used when a user selects or changes a product option like colour, size or delivery option.

There is an optional option property that can be added to let us know about the what option was selected, we suggest using one of the following values colour, size, date, time, seat, ticketType, delivery option, but other values are accepted.

There is also an optional optionValue porperty that can be sent to let us know what value was selected.

Required pageTitle, optional option and optionValue to be serialized and optional callback.

Kotlin

// immediately call asynchronously
ravelin.trackSelectOption("Product Page", "Option", "Option Value", object : RavelinRequestCallback() {
    override fun success() {
        Log.e("API Request Success", "hooray")
    }

    override fun failure(error: RavelinError) {
        Log.e("API Request Error", error.message)
    }
})

Java

ravelin.trackSelectOption("Product Page", "Option", "Option Value", new RavelinRequestCallback() {
    @Override
    public void success() {
        Log.e("API Request Success", "hooray");
    }

    @Override
    public void failure(RavelinError error) {
        Log.e("API Request Error", error.getMessage());
    }
});

trackAddToCart and trackRemoveFromCart

To be used when an item is added or removed from the cart.

There are two optional properteis itemName and quantity that can be added to let us know the product name and the quantity.

Required pageTitle, optional itemName and quantity to be serialized and optional callback.

Kotlin

ravelin.trackAddToCart("Product Page", "Item Name", 5, object : RavelinRequestCallback() {
    override fun success() {
        Log.e("API Request Success", "hooray")
    }

    override fun failure(error: RavelinError) {
        Log.e("API Request Error", error.message)
    }
})

Java

ravelin.trackAddToCart("Product Page ", "Item Name", 5, new RavelinRequestCallback() {
    @Override
    public void success() {
        Log.e("API Request Success", "hooray");
    }

    @Override
    public void failure(RavelinError error) {
        Log.e("API Request Error", error.getMessage());
    }
});

trackAddToWishlist and trackRemoveFromWishlist

To be used when an item is added or removed from the wishlist.

There is an optional itemName property that can be added to let us know the product name.

Required pageTitle, optional itemName to be serialized and optional callback.

Kotlin

// immediately call asynchronously
ravelin.trackAddToWishlist("Product Page", "Item Name", object : RavelinRequestCallback() {
    override fun success() {
        Log.e("API Request Success", "hooray")
    }

    override fun failure(error: RavelinError) {
        Log.e("API Request Error", error.message)
    }
})

Java

ravelin.trackAddToWishlist("Product Page", "Item Name", new RavelinRequestCallback() {
    @Override
    public void success() {
        Log.e("API Request Success", "hooray");
    }

    @Override
    public void failure(RavelinError error) {
        Log.e("API Request Error", error.getMessage());
    }
});

trackViewContent

To be used when the user interacts with product content like plays a video, expands a photo, expands product details.

There is an optional contentType property to let us know what content the user intercated with, we suggest using one of the following values video, photo, productDescription, deliveryOptions, but other values are accepted.

Required pageTitle, optional contentType to be serialized and optional callback.

Kotlin

// immediately call asynchronously
ravelin.trackViewContent("Product Page", "Content Type", object : RavelinRequestCallback() {
    override fun success() {
        Log.e("API Request Success", "hooray")
    }

    override fun failure(error: RavelinError) {
        Log.e("API Request Error", error.message)
    }
})

java

ravelin.trackViewContent("Product Page", "Content Type", new RavelinRequestCallback() {
    @Override
    public void success() {
        Log.e("API Request Success", "hooray");
    }
    @Override
    public void failure(RavelinError error) {
        Log.e("API Request Error", error.getMessage());
    }
});

trackEvent

Tracks a user or app event.

Required eventType, optional pageTitle, optional payload to be serialized and optional callback.

Kotlin

// immediately call asynchronously
ravelin.trackEvent("app open", "login activity", arrayOf("Custom", "Data"), object : RavelinRequestCallback() {
    override fun success() {
        Log.e("API Request Success", "hooray")
    }

    override fun failure(error: RavelinError) {
        Log.e("API Request Error", error.message)
    }
})

Java

// immediately call asynchronously
ravelin.trackEvent("app open", "login activity", new String[]{"Custom", "Data"}, new RavelinRequestCallback() {
    @Override
    public void success() {
        Log.e("API Request Success", "hooray");
    }

    @Override
    public void failure(RavelinError error) {
        Log.e("API Request Error", error.getMessage());
    }
});

trackLogIn

Tracks a user login event.

Required customerId, optional pageTitle, optional payload to be serialized and optional callback.

Kotlin

// immediately call asynchronously
ravelin.trackLogIn("15464811", "login activity", mapOf("Class" to "Mage"), object : RavelinRequestCallback() {
    override fun success() {
        Log.e("API Request Success", "hooray")
    }

    override fun failure(error: RavelinError) {
        Log.e("API Request Error", error.message)
    }
})

Java

// immediately call asynchronously
final HashMap<String, String> map = new HashMap<>();
map.put("Class", "Mage");

ravelin.trackLogIn("app open", "login activity", map, new RavelinRequestCallback() {
    @Override
    public void success() {
        Log.e("API Request Success", "hooray");
    }

    @Override
    public void failure(RavelinError error) {
        Log.e("API Request Error", error.getMessage());
    }
});

trackLogOut

Tracks a user logout event.

pageTitle and payload are optional serialized parameters. callback is optional.

Kotlin

// immediately call asynchronously
ravelin.trackLogOut("User Account", mapOf("Class" to "Mage"), object : RavelinRequestCallback() {
    override fun success() {
        Log.e("API Request Success", "hooray")
    }

    override fun failure(error: RavelinError) {
        Log.e("API Request Error", error.message)
    }
})

Java

// immediately call asynchronously
final HashMap<String, String> map = new HashMap<>();
map.put("Class", "Mage");

ravelin.trackLogOut("login activity", map, new RavelinRequestCallback() {
    @Override
    public void success() {
        Log.e("API Request Success", "hooray");
    }

    @Override
    public void failure(@NotNull RavelinError error) {
        Log.e("API Request Error", error.getMessage());
    }
});

trackPaste

This method is used primarily by the Ravelin PasteEventListener but can be used directly if required.

Required value, optional pageTitle and optional callback.

Kotlin

// immediately call asynchronously
ravelin.trackPaste("checkout activity", pastedCharacters, object : RavelinRequestCallback() {
    override fun success() {
        Log.e("API Request Success", "hooray")
    }

    override fun failure(error: RavelinError) {
        Log.e("API Request Error", error.message)
    }
})

Java

// immediately call asynchronously
ravelin.trackPaste("login activity", pastedCharacters, new RavelinRequestCallback() {
    @Override
    public void success() {
        Log.e("API Request Success", "hooray");
    }
    @Override
    public void failure(RavelinError error) {
        Log.e("API Request Error", error.getMessage());
    }
});

Paste Event Listener

The PasteEventListener is a TextWatcher that reports back when a user has pasted into an input box through a PasteEventListener.OnPaste interface.

Internally, the PasteEventListener will report back to Ravelin the pasted text after obfuscating input. The input should be obfuscated automatically as part of PasteEventListener - this is important because we don’t want to be accidently sent sensitive information that may be copied and pasted (for example BINs).

This is primarily for use on PAN input fields but may be used anywhere.

Kotlin

val view = // Your EditText

view.addTextChangedListener(
    PasteListener("page", object : PasteListener.OnPaste() {
        fun pasted() {
            Log.d("Paste Event", "user has pasted some content")
        }
    })
)

Java

EditText view = // Your EditText

view.addTextChangedListener(
    new PasteListener("page", new PasteListener.OnPaste() {
        @Override
        public void pasted() {
            Log.d("Paste Event", "user has pasted some content");
        }
    })
);

End-to-End Example

In the following form, we collect card details from the customer, encrypt them and send that encrypted values (the cipher) back to your server.

Kotlin

class ShopApplication : Application() {
    override fun onCreate() {
        // Create instance referencing the application.
        // This can be done anywhere if the application does not extend Application
        RavelinSDK.createInstance(this, "api_key_123456789",
          object : RavelinCallback<RavelinSDK>() {

            override fun success(instance : RavelinSDK) {
                Log.e("Ravelin Setup Success", "hooray")
            }

            override fun failure(error: RavelinError) {
                Log.e("Ravelin Setup Error", error.message)
            }
        })
    }
}



class ShopActivity: AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val customerId = "1234" // get customerId from your login process

        val ravelin = RavelinSDK.getSharedInstance(object : RavelinCallback<RavelinSDK>() {
            override fun success(result : RavelinSDK) {
                result.customerId = customerId // set customer id either directly or via trackLogin method
                // this id will then be sent with all subsiquent tracking events
                result.orderId = "your own order ID" // set order id to your own order reference
                result.trackPage("Shopping Page")
            }

            override fun failure(error: RavelinError) {
                Log.e("Ravelin Setup Error", error.message)
            }
        })
        val cardNumberTextView = findViewById<TextView>(R.id.pan)
        val expirationMonthTextView = findViewById<TextView>(R.id.expiration_month)
        val expirationYearTextView = findViewById<TextView>(R.id.expiration_year)
        val nameOnCardTextView = findViewById<TextView>(R.id.name_on_card)

        findViewById<Button>(R.id.payButton).setOnClickListener {
            val pan = cardNumberTextView.text.toString()
            val month = expirationMonthTextView.text.toString()
            val year = expirationYearTextView.text.toString()
            val name = nameOnCardTextView.text.toString()

            val cardDetails = CardDetails(pan, month, year, name)

            if(ravelin != null) {
                ravelin.encryptCard(cardDetails, "RSA-KEY", object : RavelinCallback<EncryptedCard>() {
                    override fun success(result : EncryptedCard) {
                        Log.e("Card Encryption Success", "hooray")
                        sendEncryptedDetailsToYourServer(encryptedCardDetails)
                    }

                    override fun failure(error: RavelinError) {
                        Log.e("Card Encryption Error", error.message)
                    }
                })
            }
        }
    }
}

java

public class ShopApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        // Create instance referencing the application.
        // This can be done anywhere if the application does not extend Application
        RavelinSDK.Companion.createInstance(this, "api_key_123456789", new RavelinCallback<RavelinSDK>() {
            @Override
            public void success(RavelinSDK result) {
                Log.e("Ravelin Setup Success", "hooray")
            }

            @Override
            public void failure(@NotNull RavelinError error) {
                Log.e("Ravelin Setup Error", error.getMessage())
            }
        });
    }
}



public class ShopActivity extends AppCompatActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final String customerId = "1234"; // get customerId from your login process

        final RavelinSDK ravelin = RavelinSDK.Companion.getSharedInstance(new RavelinCallback<RavelinSDK>() {
            @Override
            public void success(RavelinSDK result) {
                result.setCustomerId(customerId); // set customer id either directly or via trackLogin method
                // this id will then be sent with all subsiquent tracking events
                result.setOrderId("your own order ID"); // set order id to your own order reference
                result.trackPage("Shopping Page");
            }

            @Override
            public void failure(RavelinError error) {
                Log.e("Ravelin Setup Error", error.getMessage());
            }
        });
        final TextView cardNumberTextView = findViewById(R.id.pan);
        final TextView expirationMonthTextView = findViewById(R.id.expiration_month);
        final TextView expirationYearTextView = findViewById(R.id.expiration_year);
        final TextView nameOnCardTextView = findViewById(R.id.name_on_card);

        findViewById(R.id.payButton).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String pan = cardNumberTextView.getText().toString();
                String month = expirationMonthTextView.getText().toString();
                String year = expirationYearTextView.getText().toString();
                String name = nameOnCardTextView.getText().toString();


                CardDetails cardDetails = new CardDetails(pan, month, year, name);

                if (ravelin != null) {
                    ravelin.encryptCard(cardDetails, "RSA-KEY", new RavelinCallback<EncryptedCard>() {
                        @Override
                        public void success(EncryptedCard result) {
                            Log.e("Card Encryption Success", "hooray");
                            sendEncryptedDetailsToYourServer(encryptedCardDetails);
                        }

                        @Override
                        public void failure(@NotNull RavelinError error) {
                            Log.e("Card Encryption Error", error.getMessage());
                        }
                    });
                }
            }
        });
    }
}

Once the cipher is received by your server, the API request to Ravelin in which a fraud recommendation is requested should use this cipher value:

/* Server-side */

var card = JSON.parse(request.params['ravelinCipherText']);
card.methodType = 'paymentMethodCipher';

var action = request('https://pci.ravelin.com/v2/checkout?score=true', {
    // ...
    'paymentMethod': card,
});

Class Methods


createInstance

createInstance(application: Application, apiKey: String, callback: RavelinCallback<RavelinSDK>? = null) : RavelinSDK?

Create a singleton instance of the Ravelin SDK with your Publishable API Key.

Parameters

Parameter Type Description
application Application The Android Application class that this instance is attached to
apiKey String Your Publishable API Key. See Authentication for where to find this.
callback RavelinCallback Optional callback

Return value

A nullable singleton instance of the class

Create a new instance of the RavelinSDK. If this is called a second time, no new instance is created.


getSharedInstance

getSharedInstance(callback: RavelinCallback<RavelinSDK>? = null): RavelinSDK?

Method for accessing the required methods for communicating with Ravelin APIs.

Only to be called after the Ravelin SDK has been first initialised using your Publishable API Key and/or RSA key otherwise the RavelinCallback.failure callback method is triggered.

Parameters

Parameter Type Description
callback Application An optional callback that is responsible to warn whether the RavelinSDK instance could be retrieved with success or not.

Return Value

An instance of a previously created RavelinSDK, null if it is not existent.


getDeviceId()

Utility method that allows user to know the unique identifier that represents users device.

Return value

A String identifying the device - persistent across Google accounts.


trackFingerprint

trackFingerprint(callback: RavelinRequestCallback? = null)

Fingerprints the device and sends results to Ravelin

Parameters

Parameter Type Description
callback RavelinRequestCallback Optional callback for the API response.

trackPage

trackPage(pageTitle: String, payload: Any? = null, callback: RavelinRequestCallback? = null)

Sends a track page event to Ravelin.

Parameters

Parameter Type Description
pageTitle String The title of the current page
payload Any Additional data to be sent to Ravelin
callback RavelinRequestCallback Optional callback for the API responses.

trackSearch

trackSearch(pageTitle: String, searchValue: String? = null, callback: RavelinRequestCallback? = null)

Sends a track search event to Ravelin

Parameters

Parameter Type Description
pageTitle String The title of the current page
searchValue String Optional string that was used to perform a search.
callback RavelinRequestCallback Optional callback for the API responses.

trackSelectOption

trackSelectOption(pageTitle: String, option: String? = null, optionValue: String? = null, callback: RavelinRequestCallback? = null)

Sends a track selected option event to Ravelin

Parameters

Parameter Type Description
pageTitle String The title of the current page
option String The name of the option, optional. Example: {colour, size, date, time, seat, ticketType}
optionValue String The value of the option, optional. Example: {blue, M, 14, first class}
callback RavelinRequestCallback Optional callback for the API responses

trackAddToCart

trackAddToCart(pageTitle: String, itemName: String? = null, quantity: Int? = 0, callback: RavelinRequestCallback? = null)

Sends a track add to cart event to Ravelin

Parameters

Parameter Type Description
pageTitle String The title of the current page
itemName String The name of the item, optional
quantity String The quantity of the item, optional
callback RavelinRequestCallback Optional callback for the API responses

trackRemoveFromCart

trackRemoveFromCart(pageTitle: String, itemName: String? = null, quantity: Int? = 0, callback: RavelinRequestCallback? = null)

Sends a track remove from cart event to Ravelin

Parameters

Parameter Type Description
pageTitle String The title of the current page
itemName String The name of the item, optional
quantity String The quantity of the item, optional
callback RavelinRequestCallback Optional callback for the API responses

trackAddToWishlist

trackAddToWishlist(pageTitle: String, itemName: String? = null, callback: RavelinRequestCallback? = null)

Sends a track add to wishlist event to Ravelin

Parameters

Parameter Type Description
pageTitle String The title of the current page
itemName String The name of the item, optional
callback RavelinRequestCallback Optional callback for the API responses

trackRemoveFromWishlist

trackRemoveFromWishlist(pageTitle: String, itemName: String? = null, callback: RavelinRequestCallback? = null)

Sends a track remove from wishlist event to Ravelin

Parameters

Parameter Type Description
pageTitle String The title of the current page
itemName String The name of the item, optional
callback RavelinRequestCallback Optional callback for the API responses

trackViewContent

trackViewContent(pageTitle: String, contentType: String? = null, callback: RavelinRequestCallback? = null)

Sends a track view content event to Ravelin

Parameters

Parameter Type Description
pageTitle String The title of the current page
contentType String The type of the content, optional. Examples: {video, photo, productDescription, deliveryOptions}
callback RavelinRequestCallback Optional callback for the API responses.

trackEvent

trackEvent(eventType: String, pageTitle: String? = null, payload: Any? = null, callback: RavelinRequestCallback? = null)

Sends a track event to Ravelin. Use this method to send custom events and data to analyse in your dashboard.

Parameters

Parameter Type Description
eventType String The type of triggered event
pageTitle String The title of the current page
payload Any Optional object to be serialized and transmitted with the event
callback RavelinRequestCallback Optional callback for the API request communication.

trackLogIn

trackLogIn(customerId: String, pageTitle: String? = null, payload: Any? = null, callback: RavelinRequestCallback? = null)

Sends a track login event to Ravelin

Parameters

Parameter Type Description
customerId String The Customer identifier as a String
pageTitle String The page where the login occurred
payload Any Additional data to be sent to Ravelin
callback RavelinRequestCallback Optional callback for the API responses.

trackLogOut

trackLogOut(pageTitle: String? = null, payload: Any? = null, callback: RavelinRequestCallback? = null)

Ends current Ravelin session and sends logout event to Ravelin

Parameters

Parameter Type Description
pageTitle String The page where the logout occurred
payload Any Additional data to be sent to Ravelin
callback RavelinRequestCallback Optional callback for the API responses.

trackPaste

trackPaste(value: String, pageTitle: String? = null, callback: RavelinRequestCallback? = null)`

Track a paste event with the content tracked.

Parameters

Parameter Type Description
value String Pasted text string.
pageTitle String Optional. The page where the pasting occurred.
callback RavelinRequestCallback Optional callback for the API responses.

Class Properties

Customer ID

Your chosen customer ID

Kotlin

ravelin.customerId

ravelin.customerId = "cust-1"

Java

ravelin.getCustomerId();

ravelin.setCustomerId("cust-1");

Temp Customer ID

A temporary customer ID that will always be non-blank. Setting to a null, blank or empty value will generate a new temporary customer ID.

Kotlin

ravelin.tempCustomerId

ravelin.tempCustomerId = "temp-1"

Java

ravelin.getTempCustomerId();

ravelin.setTempCustomerId("temp-1");

Order ID

The ID for this specific order.

Kotlin

ravelin.orderId

ravelin.orderId = "930393-BBB"

Java

ravelin.getOrderId();

ravelin.setOrderId("930393-BBB");

Session ID

A temporary session ID that will always be non-blank. Setting to a null, blank or empty value will generate a new session ID.

Kotlin

ravelin.sessionId

ravelin.sessionId = null

Java

ravelin.getSessionId();

ravelin.setSessionId(null);

Device ID

A unique device identifier that is calculated in runtime.

Kotlin

ravelin.getDeviceId()

Java

ravelin.getDeviceId();

Class Methods - Ravelin Encrypt


encryptCard

encryptCard(cardDetails: CardDetails, rsaKey: String, callback: RavelinCallback<EncryptedCard>? = null)

Encrypt provided [CardDetails] ready to be sent to Ravelin

Parameters

Parameter Type Description
cardDetails CardDetails the plain text [CardDetails] to be encrypted
rsaKey String the RSA key provided
callback RavelinCallback to handle null-safe results or handle errors

Return value

A nullable encrypted card details


Bundled Libraries

Providing this library would not have been possible without the stellar works upon which it relies:

Release Notes


v1.0.0 - September 16, 2020

  • Support for Android 11.
  • Security improvements.

v0.3.0 - May 15, 2020

  • SDK is now modularised into “Core” and “Encrypt” components.
    • ravelin-core - which is used for deviceId, fingerprinting and tracking activity.
    • ravelin-encrypt - for card details encryption.
    • The modules are independent.
  • Queueing and retrying events when no internet connection or server errors.
  • Collecting new device properties (Emulator and Rooted).
  • More events to track customer activity ( example: trackSearch, trackAddToWishList ).
  • Callbacks for any track function are now all optional.

v0.2.8 - November 25, 2019

  • Fixed a crash for null errors.
    • Fatal Exception: java.lang.IllegalStateException: error must not be null

v0.2.7 - October 29, 2019

  • Fixed a crash where sdk was trying to read a non-JSON error but treating it as if it was JSON.
    • Fatal Exception: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
  • Updated the build target to be android 10.

v0.2.6 - May 7, 2019

  • Added RSA OAEP Encryption.
  • Extracted Chilkat Encryption to external module ‘legacy-encryption’.
  • ‘Legacy-encryption’ created as an extension module/utility.
  • Created new method ‘legacyEncryptCard’.