Integrate the Android Native SDK
The TingeePaySDK (AAR) library lets you integrate the Tingee payment gateway into a native Android app written in Kotlin or Java.
1. Install the SDK
Follow these steps to add the AAR file to your app:
- Download the library file: tingeepaysdk-release.aar.
- Copy the downloaded
tingeepaysdk-release.aarfile into your project'sapp/libs/folder (create thelibsfolder if it does not exist). - Open your app's build configuration file (in the
appmodule) and add the dependencies for the Gradle DSL you use:
- Kotlin DSL (build.gradle.kts)
- Groovy DSL (build.gradle)
dependencies {
// Add the local AAR file
implementation(files("libs/tingeepaysdk-release.aar"))
// Libraries the SDK requires (add them if missing)
implementation("androidx.appcompat:appcompat:1.3.0")
implementation("com.google.android.material:material:1.6.1")
implementation("androidx.constraintlayout:constraintlayout:2.0.0")
implementation("androidx.activity:activity:1.8.0")
}
dependencies {
// Add the local AAR file
implementation files('libs/tingeepaysdk-release.aar')
// Libraries the SDK requires (add them if missing)
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0'
implementation 'androidx.activity:activity:1.8.0'
}
- Sync your project by clicking File → Sync Project with Gradle Files.
2. Declare app permissions
The SDK needs an Internet connection to load the payment gateway. Make sure you have declared the INTERNET permission in your app's AndroidManifest.xml file:
<manifest xmlns:android="http://schemas.microsoft.com/apk/res/android"
package="your.package.name">
<!-- Add this line if it is missing -->
<uses-permission android:name="android.permission.INTERNET" />
<application ...>
...
</application>
</manifest>
3. Launch the payment screen
The payment gateway offers two main display modes: Full screen (FullScreen) or Half screen (Bottom Sheet).
Before opening the SDK, you need to get the paymentUrl from your server (Backend) (via the Create payment link API) and prepare your registered returnUrl.
3.1. Call from an Activity (recommended)
Use ActivityResultLauncher to launch the payment screen and receive the result the modern way.
Step 1: Register the Launcher in your Activity
private val paymentResultLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data = result.data
val status = data?.getStringExtra("EXTRA_PAYMENT_STATUS")
val orderId = data?.getStringExtra("EXTRA_ORDER_ID")
val transactionCode = data?.getStringExtra("EXTRA_TRANSACTION_CODE")
val errorCode = data?.getStringExtra("EXTRA_ERROR_CODE")
val errorMessage = data?.getStringExtra("EXTRA_ERROR_MESSAGE")
val rawJson = data?.getStringExtra("EXTRA_PAYMENT_DATA_JSON")
when (status) {
"success" -> { /* Payment succeeded */ }
"failed" -> { /* Payment failed */ }
"cancelled" -> { /* The user cancelled the transaction on the gateway */ }
"expired" -> { /* The payment code expired */ }
"error" -> { /* A system error occurred */ }
}
} else {
// The user closed the SDK screen (by swiping or with the hardware back button) without a result
}
}
Step 2: Open the payment gateway once you have the URL
val intent = TingeePaySDK.createIntent(
context = this,
paymentUrl = paymentUrl, // Payment URL from your Backend API
returnUrl = returnUrl, // Registered return URL/deep link
isEmbedded = true, // true: Hide the web page's unnecessary header/footer (recommended)
immediateResult = true, // true: Send the result back as soon as it completes
primaryColor = "#1E88E5", // Brand color in Hex (null = use the default)
isFullScreen = true // true: Full screen | false: Show as a Bottom Sheet (half screen)
)
paymentResultLauncher.launch(intent)
3.2. Call from a Fragment
When you open the SDK from a Fragment, keep these two important points in mind:
registerForActivityResultmust be declared as a class-level property of the Fragment. Do not declare it inside callbacks such asonViewCreated(),onStart(), or inside click listeners (doing so throws anIllegalStateExceptionat runtime).- Use
requireContext()instead ofthiswhen passing the context parameter.
class CheckoutFragment : Fragment() {
// ✅ Declare the Launcher as a class-level property
private val paymentResultLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val status = result.data?.getStringExtra("EXTRA_PAYMENT_STATUS")
val orderId = result.data?.getStringExtra("EXTRA_ORDER_ID")
// Handle the result...
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnPay.setOnClickListener {
// ✅ Create the Intent and launch it from the click event
val intent = TingeePaySDK.createIntent(
context = requireContext(), // Use requireContext()
paymentUrl = paymentUrl,
returnUrl = returnUrl,
isEmbedded = true,
immediateResult = true,
primaryColor = "#1E88E5",
isFullScreen = false // Example: open as a Bottom Sheet
)
paymentResultLauncher.launch(intent)
}
}
}
4. Configuration parameters
TingeePaySDK.createIntent supports the following configuration parameters:
| Parameter | Data type | Default | Description |
|---|---|---|---|
context | Context | — | Context of the calling Activity/Fragment. |
paymentUrl | String | — | Required. Payment URL created by your Backend API. |
returnUrl | String? | null | URL or deep link to redirect the app to after completion. |
isEmbedded | Boolean | true | If true, the SDK hides the payment gateway web page's default header and footer for a native feel. |
immediateResult | Boolean | true | true to send the result immediately when the payment gateway finishes processing. |
primaryColor | String? | null | Primary color of the payment interface as a Hex string (e.g. "#E53935"). If null, the gateway's default color is used. |
isFullScreen | Boolean | true | Display mode: - true: Full screen.- false: Bottom Sheet (about 50% of the screen height, swipe down to close). |
5. Data returned by the SDK
When the payment screen finishes, the SDK calls setResult(RESULT_OK, intent) and closes automatically. You can read the following data from the result Intent:
| Data key | Data type | Description |
|---|---|---|
EXTRA_PAYMENT_STATUS | String | Returned transaction status: success / failed / cancelled / expired / error |
EXTRA_ORDER_ID | String | The corresponding order ID in your system. |
EXTRA_TRANSACTION_CODE | String | Transaction code recorded on the Tingee payment gateway. |
EXTRA_ERROR_CODE | String | Detailed error code (if an error occurred). |
EXTRA_ERROR_MESSAGE | String | Detailed error message (if an error occurred). |
EXTRA_PAYMENT_DATA_JSON | String | The full original JSON payload from the payment gateway. |
[!NOTE] If the user closes the SDK screen (e.g. by swiping the Bottom Sheet down) before a final status is available,
resultCodeisRESULT_CANCELED(0) and the Intent contains no extra data.
6. Minimum system requirements
| Category | Requirement |
|---|---|
| Minimum Android SDK | API 24 (Android 7.0 or later) |
| Target SDK | API 36 |
| Java compatibility | Java 11 |
| Network permission | The INTERNET permission is required |
| Development language | Kotlin or Java |
7. Important integration notes
- Link creation flow: The mobile SDK does not call the API that creates the payment link. Your app is responsible for calling your own Backend to get the
paymentUrlbefore passing it to the SDK. - Automatic deep links: When the user chooses to pay with a banking app, the SDK automatically detects and opens a compatible banking app installed on the device. If that banking app is not installed, the SDK shows a friendly popup so the user can try again or choose another payment method.
- Memory: The SDK automatically releases resources and clears the WebView cache when the payment screen closes, to avoid memory leaks.