First Developer Journey

This guide outlines the essential steps for integrating Ottu Android Checkout SDK into your mobile application. It provides a concise flow from setup to callback handling, helping developers achieve a seamless checkout experience.

This video guides you step-by-step through the Android SDK integration process. Watch it to quickly learn how to set up, configure, and see the key features in action.

1

Add JitPack Repository

In your settings.gradle.kts file, add JitPack to the repositories section under dependencyResolutionManagement:

maven { url = uri("https://jitpack.io") }
2

Add the SDK Dependency

Include the Ottu Checkout SDK in your app-level build.gradle.kts file:

implementation("com.github.ottuco:ottu-android-checkout:2.1.4")

1

Add FrameLayout to the Layout File

Inside activity_main.xml (located in the res/layout folder), add a FrameLayout with the ID ottuPaymentView: android:id="@+id/ottuPaymentView"

2

Import Required Modules

Usually, Android Studio automatically imports the necessary modules. However, for reference, the Ottu SDK requires the following imports:

import com.ottu.checkout.Checkout
import com.ottu.checkout.network.model.payment.ApiTransactionDetails
import com.ottu.checkout.ui.base.CheckoutSdkFragment
3

Extend the Activity Class

Ensure that the Activity integrating with the Checkout SDK inherits from AppCompatActivity:

class MainActivity : AppCompatActivity() {
4

Declare Checkout Fragment Variable

Add a member variable for the CheckoutSdkFragment object:

private var checkoutFragment: CheckoutSdkFragment? = null
5

Initialize Checkout SDK

Inside the onCreate function, add the SDK initialization code:

// populate the fields below with correct values
val merchantId = "" // your merchant base URL
val sessionId = "" // the transaction ID
val apiKey = "" // merchant public API Key
val amount = 10.0 // decimal number

// List mode just to look better
val paymentOptionsDisplaySettings = Checkout.PaymentOptionsDisplaySettings(
            Checkout.PaymentOptionsDisplaySettings.PaymentOptionsDisplayMode.List(5))

// Builder class is used to construct an object passed to the SDK initializing function
val builder = Checkout
  .Builder(merchantId!!, sessionId, apiKey!!, amount!!)
    .paymentOptionsDisplaySettings(paymentOptionsDisplaySettings)
    .logger(Checkout.Logger.INFO)
    .build()

if (Checkout.isInitialized) {
  Checkout.release()
}

lifecycleScope.launch {
  runCatching {
    Checkout.init(
      context = this@MainActivity,
        builder = builder,
        successCallback = {
          Log.e("TAG", "successCallback: $it")
          //showResultDialog(it)
        },
        cancelCallback = {
          Log.e("TAG", "cancelCallback: $it")
          //showResultDialog(it)
        },
        errorCallback = { errorData, throwable ->
          Log.e("TAG", "errorCallback: $errorData")
          //showResultDialog(errorData, throwable)
        },
    )
  }.onSuccess {
    checkoutFragment = it
    supportFragmentManager
      .beginTransaction()
      .replace(R.id.ottuPaymentView, it)
      .commit()
  }.onFailure {
    //showErrorDialog(it)
  }
}
6

(Optional) Implement Result and Error Dialogs

Uncomment showResultDialog and showErrorDialog in the code above and add their implementations as methods inside the same MainActivity:

private fun showResultDialog(result: JSONObject?, throwable: Throwable? = null) {
    val sb = StringBuilder()

    result?.let {
        sb.apply {
            append(("Status : " + result.opt("status")) + "\n")
            append(("Message : " + result.opt("message")) + "\n")
            append(("Session id : " + result.opt("session_id")) + "\n")
            append(("operation : " + result.opt("operation")) + "\n")
            append(("Reference number : " + result.opt("reference_number")) + "\n")
            append(("Challenge Occurred : " + result.opt("challenge_occurred")) + "\n")
            append(("Form of payment: " + result.opt("form_of_payment")) + "\n")
        }
    } ?: run {
        sb.append(throwable?.message ?: "Unknown Error")
    }

    AlertDialog.Builder(this)
        .setTitle("Order Information")
        .setMessage(sb)
        .setPositiveButton(
            android.R.string.ok
        ) { dialog, which ->
            dialog.dismiss()
        }
        .show()
}

private fun showErrorDialog(throwable: Throwable? = null) {
    if (throwable is SecurityException) return

    AlertDialog.Builder(this)
        .setTitle("Failed")
        .setMessage(throwable?.message ?: "Unknown Error")
        .setPositiveButton(
            android.R.string.ok
        ) { dialog, which ->
            finish()
            dialog.dismiss()
        }
    .show()
}
7

Clean Up Memory

To ensure proper resource management, override the onDestroy method:

override fun onDestroy() {
  super.onDestroy()
  if (isFinishing) {
    Checkout.release()
  }
}
8

Verify Imports

Finally, confirm that all required imports are present. Android Studio usually detects and adds them automatically.

Notes on Initialization Parameters

Not all parameters in Checkout.init are mandatory. The required parameters are:

  • sessionId – ID of the created transaction

  • merchantId – Same as the domain used in HTTP requests

  • apiKey – Public API key used for authorization

Recommended optional parameters:

  • formsOfPayment

  • setupPreload (to reduce initialization time)

setupPreload is an object taken from the transaction creation response. When passed to the SDK, it prevents it from requesting the transaction details on its own and therefore speed-ups the initialization process by several seconds. This setupPreload is a decoded JSON object to a TransactionDetails For reference, check the example: here

The SDK triggers three main callbacks:

  • successCallback – Invoked upon successful payment.

  • cancelCallback – Triggered when the user cancels the transaction.

  • errorCallback – Activated on errors during the checkout process.

Developers should customize the logic within these callbacks to handle transaction results appropriately.

Last updated