Save Card For Future Use
Step 1: Initialize MoneyHash SDK
Before proceeding, initialize the MoneyHash SDK with your Public API Key:
val moneyHashSDK = MoneyHashSDKBuilder()
.setPublicKey("<account_public_api_key>")
.build()
Explanation:
- SDK Initialization: This step involves initializing the MoneyHash SDK by providing your Public API Key. You will use the
MoneyHashSDKBuilder
to configure and build the SDK, which will be used for managing the card data and payments.
Step 2: Collect Card Data
Once the card form is set up, you can collect the card data. If you haven't set up the card form yet, follow the steps in the Collecting Card Information documentation.
Here's how you can collect the card data using the collect()
method:
class CardFormViewModel : ViewModel() {
var cardForm: CardForm? = null // Assume this is set up
suspend fun collectCardData(): VaultData? {
return try {
cardForm?.collect()
} catch (e: Exception) {
println("Error collecting card data: ${e.message}")
throw e
}
}
}
Explanation:
- The
collect()
method asynchronously gathers the entered card information from the form, returning the collected data as aVaultData
object. This data is essential for processing payments or creating a card token.
Step 3: Create a Card Token
Once the card data is collected, you can create a card token for future use by calling the createCardToken()
method:
class CardFormViewModel : ViewModel() {
var cardForm: CardForm? = null // Assume this is set up in the linked documentation
suspend fun createCardToken(cardIntentId: String, cardData: VaultData) {
try {
val intentStateDetails = cardForm?.createCardToken(cardIntentId, cardData)
when (intentStateDetails) {
is IntentStateDetails.CardIntentSuccess -> {
println("Card token created successfully.")
}
is IntentStateDetails.UrlToRender -> {
println("Card token creation pending. Open the URL to complete the flow: ${intentStateDetails.url}")
}
else -> {
println("Card token creation failed.")
}
}
} catch (e: Exception) {
println("Error creating card token: ${e.message}")
}
}
}
You can implement any additional business logic between collecting card data and tokenizing it.
Explanation:
- After collecting the card data, you can create a card token using the
createCardToken()
method. This token can be stored and used for future transactions.
Complete Example
Here is a complete example of how to integrate all the steps into your Android app using Kotlin and Jetpack Compose:
class CardFormViewModel : ViewModel() {
var cardForm: CardForm? = null
init {
setupCardForm()
}
private fun setupCardForm() {
cardForm = CardFormBuilder()
.setCardNumberField { state ->
println("Card Number Field State: $state")
}
.setCVVField { state ->
println("CVV Field State: $state")
}
.setCardHolderNameField { state ->
println("Card Holder Name Field State: $state")
}
.setExpireMonthField { state ->
println("Expire Month Field State: $state")
}
.setExpireYearField { state ->
println("Expire Year Field State: $state")
}
.setCardBrandChangeListener { brand ->
println("Card Brand Changed: $brand")
}
.build()
}
suspend fun saveCard(cardIntentId: String) {
try {
val cardData = cardForm?.collect()
if (cardData == null) {
println("Failed to collect card data.")
return
}
val intentStateDetails = cardForm?.createCardToken(cardIntentId, cardData)
when (intentStateDetails) {
is IntentStateDetails.CardIntentSuccess -> {
println("Card token created successfully.")
}
is IntentStateDetails.UrlToRender -> {
println("Card token creation pending. Open the URL to complete the flow: ${intentStateDetails.url}")
}
else -> {
println("Card token creation failed.")
}
}
} catch (e: Exception) {
println("Error during card token creation: ${e.message}")
}
}
}
class CardFormActivity : ComponentActivity() {
private val viewModel: CardFormViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
CardFormScreen(viewModel = viewModel)
}
}
}
@Composable
fun CardFormScreen(viewModel: CardFormViewModel) {
val coroutineScope = rememberCoroutineScope()
Scaffold(
topBar = {
TopAppBar(title = { Text("Payment Form") })
},
content = {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
SecureTextField(
cardForm = viewModel.cardForm,
type = FieldType.CARD_HOLDER_NAME,
placeholder = { Text("Cardholder Name") }
)
SecureTextField(
cardForm = viewModel.cardForm,
type = FieldType.CARD_NUMBER,
placeholder = { Text("Card Number") }
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
SecureTextField(
cardForm = viewModel.cardForm,
type = FieldType.EXPIRE_MONTH,
placeholder = { Text("MM") },
modifier = Modifier.weight(1f)
)
SecureTextField(
cardForm = viewModel.cardForm,
type = FieldType.EXPIRE_YEAR,
placeholder = { Text("YY") },
modifier = Modifier.weight(1f)
)
SecureTextField(
cardForm = viewModel.cardForm,
type = FieldType.CVV,
placeholder = { Text("CVV") },
modifier = Modifier.weight(1f)
)
}
Button(
onClick = { coroutineScope.launch { viewModel.saveCard("<card_intent_id>") } },
modifier = Modifier.fillMaxWidth()
) {
Text("Save Card")
}
}
}
)
}
Explanation:
-
ViewModel (
CardFormViewModel
):-
Purpose: Manages the
CardForm
instance, ensuring it is initialized and can be shared across the UI. -
Functions:
setupCardForm()
: Initializes the card form with field listeners.saveCard()
: Collects the card data and creates a card token.
-
-
Activity (
CardFormActivity
):- Purpose: Hosts the UI and integrates the
CardForm
with Jetpack Compose.
- Purpose: Hosts the UI and integrates the
-
Composable Function (
CardFormScreen
):- Purpose: Displays the form fields using
SecureTextField
for cardholder name, card number, expiry month, expiry year, and CVV.
- Purpose: Displays the form fields using
-
Button: Triggers the
saveCard()
function in the ViewModel to collect and save card data when clicked.
Updated about 2 months ago