Kotlin with XML Views
Add the FiatPe Partner SDK to a Kotlin Android app using XML layouts.
Requirements
Kotlin integrations require a compiler that can read the SDK dependencies' Kotlin 2.3 metadata. Use Kotlin 2.2 or a compatible newer version supported by the app's build tools.
Prepare the API keys
FiatPe publishable key
Request a publishable key for the partner account and environment. Use ak_test_… for test/preproduction and ak_live_… for production. Never package a secret or server credential in the Android app.
Google Maps and Places key
- Enable billing, Maps SDK for Android, and Places API (New) in Google Cloud.
- Restrict the key to the application ID and signing-certificate SHA-1 used by each build.
- Add the Google key to the user-level Gradle properties file.
- For CI, provide the Gradle project environment variable. Do not commit either key.
# ~/.gradle/gradle.properties
MAPS_API_KEY=YOUR_GOOGLE_MAPS_PLACES_KEYORG_GRADLE_PROJECT_MAPS_API_KEY=YOUR_GOOGLE_MAPS_PLACES_KEYAdd the SDK and required configuration
Ensure the existing repositories include google() and mavenCentral(). Merge only these additions into the app module and retain its existing plugins, compiler configuration, UI dependencies, namespace, application ID, and target SDK.
android {
compileSdk = 37
defaultConfig {
minSdk = 24
manifestPlaceholders["MAPS_API_KEY"] =
providers.gradleProperty("MAPS_API_KEY").orElse("").get()
}
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
}
dependencies {
implementation("com.fiatpe:partner:1.0.0")
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5")
}Add this metadata inside the existing <application>, or reuse an existing Google key that has the required APIs and restrictions. Keep the app's existing Activity declaration.
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />Register in your existing Activity
Merge these fields and methods into the Activity that already owns the screen. MainActivity is only an example name. Creating the instance registers the result callback; it does not open the SDK.
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import com.fiatpe.partner.FiatPePartner
import com.fiatpe.partner.FiatPePartnerResult
class MainActivity : ComponentActivity() {
private lateinit var partner: FiatPePartner
private var isPartnerOpen = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Register early on every Activity creation, including recreation.
partner = FiatPePartner.create(
activity = this,
publishableApiKey = "ak_test_REPLACE_WITH_PUBLISHABLE_KEY",
callback = ::handlePartnerResult,
)
// Keep your existing screen setup here.
}
private fun openPartnerSdk() {
if (isPartnerOpen) {
return
}
isPartnerOpen = true
partner.start()
}
private fun handlePartnerResult(result: FiatPePartnerResult) {
isPartnerOpen = false
val message = when (result) {
FiatPePartnerResult.Closed -> "Returned from FiatPe Partner"
is FiatPePartnerResult.Failure -> "Unable to open FiatPe Partner. Please contact support."
}
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
}Start from your existing UI action
Call openPartnerSdk() from the app's existing button, menu item, or another user action. No particular XML layout, widget, or view ID is required.
// Use the ID of your own launch control.
findViewById<android.view.View>(R.id.openPartnerButton).setOnClickListener {
openPartnerSdk()
}Optional branding and Fragment integration
Pass FiatPePartnerTheme while creating the instance to set an opaque ARGB primary color and explicit light/dark appearance. The key and theme are fixed for that instance.
theme = com.fiatpe.partner.FiatPePartnerTheme(
primaryColor = 0xFF2458A6.toInt(), // Opaque ARGB color.
isDarkMode = false, // true selects dark appearance.
),For an AndroidX Fragment, register from its onCreate using the Fragment overload (fragment = this for Kotlin or FiatPePartner.create(this, key, callback) for Java). Connect the UI action after view creation and forward results to a state holder instead of accessing a destroyed Fragment view.
Handle results correctly
| Result | Meaning | Host app action |
|---|---|---|
Closed | The user left the SDK. | Re-enable launch and return to the host UI. |
Failure(code, message) | The SDK could not open or returned an unusable result. | Re-enable launch, handle the code, and show safe guidance. |
A user may close before or after an onboarding or CPV operation. This SDK version has no business-success callback and returns no merchant ID, documents, VPA, or QR data. Confirm completion through the separate business-status integration agreed with FiatPe.
Failure codes
INVALID_MAPS_CONFIGURATION: fix a missing or blank Google key.LAUNCH_FAILED: verify lifecycle, dependencies, and manifest configuration.INVALID_REQUEST: verify the issued FiatPe key and partner configuration.INVALID_RESULT: return safely and contact FiatPe with sanitized diagnostics.
Exceptions raised by integration errors
- A blank key or unsupported key prefix causes
IllegalArgumentExceptionduringcreate(...). - A non-opaque custom theme color causes
IllegalArgumentException. - Registering after the owner has started causes a lifecycle registration error.
- Calling
start()while the same instance is already open causesIllegalStateException.
Lifecycle, permissions, and security
- Create the SDK in Activity or Fragment
onCreate, beforeSTARTED, on the main thread. - Register after every owner recreation, including rotation. Do not guard registration with
savedInstanceState == null. - Start only after a user action, block repeated taps, and never relaunch automatically from
onResume. - Keep the instance with its Activity or Fragment, not a singleton or retained ViewModel.
- The SDK requests camera, microphone, and coarse/fine location permissions only in relevant flows. Internet access is required.
- Do not duplicate SDK Activity or provider declarations. Include permission and data-use explanations in the host app privacy disclosures.
Troubleshooting
When contacting support, include SDK version, app version, Android version, device model, reproduction steps, and a sanitized failure code/message. Remove keys, documents, and personal data.