Collect Card Information
Getting Started
To create a Card Form using the MoneyHash Payment SDK for Android, you will use the CardFormBuilder
class to configure the card form's fields and set up listeners to monitor changes in their states. This setup allows you to handle events such as when a user updates the card number, CVV, cardholder name, expiry month, or expiry year fields.
The CardFormBuilder
provides methods to set listeners (handlers) for each card input field. These listeners are lambda functions that will be called every time the user updates the respective field. The listener function receives a CardInputFieldState
object, which contains information about the field’s validity, error message (if any), and the input length.
CardInputFieldState
Each time the user updates a field, the corresponding listener will be invoked with a CardInputFieldState
object. The CardInputFieldState
model represents the current state of a card input field, such as the card number, CVV, or expiration date. It includes information about whether the field is valid, any error message associated with it, whether the field is currently focused, and the length of the input entered by the user.
data class CardInputFieldState(
val isValid: Boolean? = null,
val errorMessage: String? = null,
val isOnFocused: Boolean = false,
val inputLength: Int = 0
)
Properties:
- isValid: A Boolean indicating whether the current input in the field is valid. If the input has not been validated yet, this can be
null
. - errorMessage: An optional string containing an error message if the input is invalid. If the input is valid or no validation has occurred yet, this will be
null
. - isOnFocused: A Boolean indicating whether the input field is currently focused (i.e., the user is actively entering or editing the field).
- inputLength: An integer representing the length of the input currently entered in the field.
Example Usage:
val cardInputState = CardInputFieldState(
isValid = true,
errorMessage = null,
isOnFocused = true,
inputLength = 16
)
println("Card Number is valid: ${cardInputState.isValid}")
Default State:
The default state of the card input field can be accessed using:
val defaultState = CardInputFieldState()
In the default state, the field is not focused, and the input length is 0
, with no validation performed (isValid
and errorMessage
are null
).
Creating the CardForm
CardForm
To collect card details, you will use the CardFormBuilder
to configure the card input fields and their respective listeners. These listeners handle state changes for each field, such as card number, CVV, cardholder name, expiry month, and expiry year, allowing you to monitor user input and validation in real-time.
Example:
class CardFormViewModel : ViewModel() {
lateinit var cardForm: CardForm
init {
setupCardForm()
}
private fun setupCardForm() {
cardForm = createCardForm()
}
private fun createCardForm(): CardForm {
return CardFormBuilder()
.setCardNumberField { state ->
println("Card Number State: $state")
}
.setCVVField { state ->
println("CVV State: $state")
}
.setCardHolderNameField { state ->
println("Card Holder Name State: $state")
}
.setExpireMonthField { state ->
println("Expiry Month State: $state")
}
.setExpireYearField { state ->
println("Expiry Year State: $state")
}
.setCardBrandChangeListener { brand ->
println("Card Brand Changed: $brand")
}
.build()
}
}
Explanation:
-
Listeners for Input Fields: Each field—such as card number, CVV, cardholder name, expiry month, and expiry year—has a listener associated with it. These listeners use closures to receive the updated state (
CardInputFieldState
) whenever the user modifies the respective field.-
For instance, in the
setCardNumberField
closure, the state of the card number input is printed, and this state includes information such as whether the input is valid, the formatted value, and any error messages. -
The
setCardBrandChangeHandler
closure listens for changes to the card brand, allowing you to track when the card type (e.g., Visa, MasterCard) changes based on the user's input.
-
-
build()
Method: After configuring the field listeners, thebuild()
method finalizes the creation of theCardForm
instance, which is then assigned to thecardForm
property. This form can now be used in your UI to display secure card input fields and manage the payment process.
Integrating SecureTextField
SecureTextField
The SecureTextField
is a Jetpack Compose @Composable
function that represents a secure input field for card data. You can integrate it into your Compose-based UI by placing it within your composable layouts. Below is an example of how to integrate SecureTextField
into your Android application using Jetpack Compose.
Example:
class CardFormActivity : ComponentActivity() {
private val viewModel: CardFormViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
CardFormScreen(cardForm = viewModel.cardForm)
}
}
}
@Composable
fun CardFormScreen(cardForm: CardForm) {
val coroutineScope = rememberCoroutineScope()
Scaffold(
topBar = {
TopAppBar(title = { Text("Payment Form") })
},
content = { padding ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(padding)
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
SecureTextField(
cardForm = cardForm,
type = FieldType.CARD_HOLDER_NAME,
placeholder = { Text("Cardholder Name") },
label = { Text("Cardholder Name") }
)
SecureTextField(
cardForm = cardForm,
type = FieldType.CARD_NUMBER,
placeholder = { Text("Card Number") },
label = { Text("Card Number") }
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
SecureTextField(
cardForm = cardForm,
type = FieldType.EXPIRE_MONTH,
placeholder = { Text("MM") },
label = { Text("Expiry Month") },
modifier = Modifier.weight(1f)
)
SecureTextField(
cardForm = cardForm,
type = FieldType.EXPIRE_YEAR,
placeholder = { Text("YY") },
label = { Text("Expiry Year") },
modifier = Modifier.weight(1f)
)
SecureTextField(
cardForm = cardForm,
type = FieldType.CVV,
placeholder = { Text("CVV") },
label = { Text("CVV") },
modifier = Modifier.weight(1f)
)
}
Button(
onClick = { processPayment(cardForm) },
modifier = Modifier.fillMaxWidth()
) {
Text("Process Payment")
}
}
}
)
}
Explanation:
-
ViewModel (
CardFormViewModel
): Initializes theCardForm
usingCardFormBuilder
and sets up listeners for each card input field and card brand changes. Each listener handles state changes, such as displaying error messages when input is invalid. -
Composable Function (
CardFormScreen
): Utilizes Jetpack Compose to create the UI for the card form. It integrates theSecureTextField
composable for each card input field and includes a button to process the payment. -
Processing Payment (
processPayment
): Demonstrates how to collect the card data and process the payment using thepay
method ofCardForm
. It handles success and error scenarios, providing feedback viaprintln
statements (which can be replaced with appropriate UI feedback mechanisms likeToast
or dialog messages).
Updated about 1 month ago