Skip to main content

Android SDK

Overview​

The Android SDK enables secure collection and reveal of sensitive data in native Android applications, supporting both XML layouts and Jetpack Compose.

Download SDK

Requirements​

  • Minimum SDK: 23+
  • Target SDK: 36 (recommended)
  • Kotlin: 1.9+
  • Java Toolchain: 17 (recommended)
  • Theme: Must use AppCompatActivity theme

Installation​

  1. Download and extract the SDK package
  2. Move secureconnect-maven-0.0.1.zip contents to {project_root}/mavenLib
  3. Add the Maven repository to your settings.gradle.kts:
dependencyResolutionManagement {
repositories {
maven {
url = uri("${rootProject.projectDir}/mavenLib")
}
}
}
  1. Add the dependency to your module's build.gradle.kts:
dependencies {
implementation("com.financial.connect:secureconnect:0.0.1")
}

Configuration​

Initialize the SDK with your gateway URL:

import com.financial.connect.SecureConnectSdkFactory
import com.financial.connect.SecureConnectConfig

// Create SDK instance
val sdk = SecureConnectSdkFactory.create(
context = applicationContext,
config = SecureConnectConfig(gatewayUrl = "https://api.connect.financial")
)

// Initialize with auth token
sdk.initialize(authToken = "<auth-token>")

XML Layout Integration​

Layout Definition​

Add secure fields to your XML layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">

<com.financial.connect.ui.SecureEditText
android:id="@+id/ssnField"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter SSN"
app:fieldType="ssn" />

<Button
android:id="@+id/submitButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Submit" />

</LinearLayout>

Binding and Submission​

class CollectActivity : AppCompatActivity() {

private lateinit var sdk: SecureConnectSdk
private lateinit var ssnField: SecureEditText

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_collect)

// Initialize SDK
sdk = SecureConnectSdkFactory.create(
context = applicationContext,
config = SecureConnectConfig(gatewayUrl = "https://api.connect.financial")
)
sdk.initialize(authToken = "<auth-token>")

// Get field reference
ssnField = findViewById(R.id.ssnField)

// Bind the field to an operation
sdk.bindField(ssnField, Operation.SUBMIT_DOCUMENT_SSN)

// Add validation listener
ssnField.addOnFieldStateChangeListener { state ->
if (!state.isValid && !state.isEmpty) {
ssnField.setError("Invalid SSN format")
} else {
ssnField.setError(null)
}
}

// Handle submission
findViewById<Button>(R.id.submitButton).setOnClickListener {
submitData()
}
}

private fun submitData() {
lifecycleScope.launch {
val result = sdk.submit(
operation = Operation.SUBMIT_DOCUMENT_SSN,
customerId = "customer-uuid"
)
when (result) {
is Result.Success -> {
Log.d("SecureConnect", "Token: ${result.data.token}")
}
is Result.Error -> {
Log.e("SecureConnect", "Error: ${result.exception}")
}
}
}
}
}

Jetpack Compose Integration​

Basic Compose Usage​

@Composable
fun SecureSSNInput(
sdk: SecureConnectSdk,
onSubmitSuccess: (String) -> Unit
) {
var fieldState by remember { mutableStateOf<FieldState?>(null) }
var isSubmitting by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()

Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
SecureTextField(
sdk = sdk,
operation = Operation.SUBMIT_DOCUMENT_SSN,
modifier = Modifier.fillMaxWidth(),
placeholder = { Text("Enter SSN") },
onStateChange = { fieldState = it },
isError = fieldState?.let { !it.isValid && !it.isEmpty } ?: false
)

if (fieldState?.let { !it.isValid && !it.isEmpty } == true) {
Text(
text = "Invalid SSN format",
color = MaterialTheme.colorScheme.error,
style = MaterialTheme.typography.bodySmall
)
}

Spacer(modifier = Modifier.height(16.dp))

Button(
onClick = {
scope.launch {
isSubmitting = true
val result = sdk.submit(
operation = Operation.SUBMIT_DOCUMENT_SSN,
customerId = "customer-uuid"
)
isSubmitting = false
if (result is Result.Success) {
onSubmitSuccess(result.data.token)
}
}
},
enabled = fieldState?.isValid == true && !isSubmitting,
modifier = Modifier.fillMaxWidth()
) {
if (isSubmitting) {
CircularProgressIndicator(
modifier = Modifier.size(16.dp),
color = MaterialTheme.colorScheme.onPrimary
)
} else {
Text("Submit")
}
}
}
}

Revealing Card Data​

XML Approach​

<com.financial.connect.ui.SecureLabel
android:id="@+id/panLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
app:placeholder="•••• •••• •••• ••••" />

<com.financial.connect.ui.SecureLabel
android:id="@+id/cvvLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:placeholder="•••" />

<com.financial.connect.ui.SecureLabel
android:id="@+id/expiryLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:placeholder="••/••" />

Binding and Revealing​

class RevealActivity : AppCompatActivity() {

private lateinit var sdk: SecureConnectSdk

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_reveal)

sdk = SecureConnectSdkFactory.create(
context = applicationContext,
config = SecureConnectConfig(gatewayUrl = "https://api.connect.financial")
)
sdk.initialize(authToken = "<auth-token>")

// Bind reveal fields
val panLabel = findViewById<SecureLabel>(R.id.panLabel)
val cvvLabel = findViewById<SecureLabel>(R.id.cvvLabel)
val expiryLabel = findViewById<SecureLabel>(R.id.expiryLabel)

sdk.bindRevealField(panLabel, RevealOperation.REVEAL_CARD_PAN)
sdk.bindRevealField(cvvLabel, RevealOperation.REVEAL_CARD_CVV)
sdk.bindRevealField(expiryLabel, RevealOperation.REVEAL_CARD_EXPIRY)

// Reveal button
findViewById<Button>(R.id.revealButton).setOnClickListener {
revealCardData()
}
}

private fun revealCardData() {
lifecycleScope.launch {
// Reveal PAN with formatting
sdk.reveal(
operation = RevealOperation.REVEAL_CARD_PAN,
cardId = "card-uuid",
serializer = PanSerializer.WITH_DASHES
)

// Reveal CVV
sdk.reveal(
operation = RevealOperation.REVEAL_CARD_CVV,
cardId = "card-uuid"
)

// Reveal expiry with formatting
sdk.reveal(
operation = RevealOperation.REVEAL_CARD_EXPIRY,
cardId = "card-uuid",
serializer = ExpirySerializer.SHORT // MM/YY format
)
}
}
}

Compose Reveal Example​

@Composable
fun CardRevealScreen(sdk: SecureConnectSdk, cardId: String) {
var isRevealed by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()

Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
SecureRevealLabel(
sdk = sdk,
operation = RevealOperation.REVEAL_CARD_PAN,
cardId = cardId,
serializer = PanSerializer.WITH_SPACES,
placeholder = "•••• •••• •••• ••••",
modifier = Modifier.fillMaxWidth()
)

Spacer(modifier = Modifier.height(8.dp))

Row(
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
SecureRevealLabel(
sdk = sdk,
operation = RevealOperation.REVEAL_CARD_EXPIRY,
cardId = cardId,
serializer = ExpirySerializer.SHORT,
placeholder = "••/••"
)

SecureRevealLabel(
sdk = sdk,
operation = RevealOperation.REVEAL_CARD_CVV,
cardId = cardId,
placeholder = "•••"
)
}

Spacer(modifier = Modifier.height(16.dp))

Button(
onClick = {
scope.launch {
if (isRevealed) {
sdk.hideAll()
} else {
sdk.revealAll(cardId = cardId)
}
isRevealed = !isRevealed
}
},
modifier = Modifier.fillMaxWidth()
) {
Text(if (isRevealed) "Hide" else "Reveal")
}
}
}

Serializers (Formatting)​

The SDK supports serializers for formatting revealed data:

SerializerOutput FormatExample
PanSerializer.WITH_DASHESXXXX-XXXX-XXXX-XXXX4111-1111-1111-1111
PanSerializer.WITH_SPACESXXXX XXXX XXXX XXXX4111 1111 1111 1111
ExpirySerializer.SHORTMM/YY12/25
ExpirySerializer.FULLMM/YYYY12/2025

Supported Operations​

Collect Operations​

OperationDescription
Operation.SUBMIT_DOCUMENT_IDSubmit government-issued ID
Operation.SUBMIT_DOCUMENT_SSNSubmit Social Security Number
Operation.SUBMIT_DOCUMENT_DRIVERS_LICENCESubmit driver's license
Operation.SUBMIT_DOCUMENT_PASSPORTSubmit passport

Reveal Operations​

OperationDescription
RevealOperation.REVEAL_DOCUMENT_IDReveal government-issued ID
RevealOperation.REVEAL_DOCUMENT_SSNReveal Social Security Number
RevealOperation.REVEAL_DOCUMENT_DRIVERS_LICENCEReveal driver's license
RevealOperation.REVEAL_DOCUMENT_PASSPORTReveal passport
RevealOperation.REVEAL_CARD_PANReveal card number
RevealOperation.REVEAL_CARD_CVVReveal card CVV
RevealOperation.REVEAL_CARD_EXPIRYReveal card expiry date