How to use MoneyHash V2 Flutter
Welcome to the MoneyHash SDK documentation for Flutter! This guide provides an overview of the core functionalities of the MoneyHash SDK, including intent states, API methods, and models.
Intent States and Corresponding Actions
Here's a summary of the different intent states defined in the Flutter SDK and the actions associated with them:
State | Action |
---|---|
MethodSelection | Handle this state by rendering the payment methods provided in methods . After user selection, proceed with the selected method by calling moneyHashSDK.proceedWithMethod . |
FormFields | Handle this state by rendering form fields from billingFields , shippingFields , and tokenizeCardInfo . Submit the completed data using moneyHashSDK.submitForm . |
UrlToRender | Use the moneyHashSDK.renderForm to display the embed based on the URL provided. |
SavedCardCVV | Render a CVV input field using cvvField . Optionally, display card information from cardTokenData . Submit the CVV using moneyHashSDK.submitCardCVV . |
IntentForm | Display the MoneyHash embed form using moneyHashSDK.renderForm . |
IntentProcessed | Render a success confirmation UI indicating the payment or payout completion with provided intent details. |
TransactionWaitingUserAction | Show a UI element indicating the transaction awaits user action. If available, show any external action message required from Transaction . |
TransactionFailed | Display a UI element indicating transaction failure. If recommendedMethods are provided, show these as alternative options for the user to retry the payment or payout. |
Expired | Show a message indicating that the intent has expired. |
Closed | Show a message indicating that the intent has been closed and no further actions can be taken. |
How to Handle Method Selection
Handling method selection is a crucial part of integrating the MoneyHash SDK. This process involves rendering available payment methods and managing the user's choice. Here's how you can handle method selection effectively:
Steps to Handle Method Selection
-
Display Payment Methods:
- When the SDK state is
MethodSelection
, extract themethods
object which contains the available payment options for the intent. - Use your UI components to render these payment methods in a list or grid format, allowing the user to choose one.
- When the SDK state is
-
Capture User Selection:
- Implement an interactive element for each payment method. When a user selects a method, capture this selection and prepare to proceed with that method.
-
Proceed with the Selected Method:
- Use the
moneyHashSDK.proceedWithMethod
API call to initiate the payment process with the selected method. - Pass the necessary parameters, such as
intentId
,intentType
,selectedMethodId
, andmethodType
to this function. Optionally, include anymethodMetaData
if required by the payment process.
- Use the
Example Implementation
Here’s an example of how you might implement this in your Flutter application:
try {
// Assume you have already defined 'intentId' and 'intentType'
var result = await moneyHashSDK.proceedWithMethod(
intentId: "currentIntentId",
intentType: IntentType.payment, // or payout based on your application flow
selectedMethodId: method.id,
methodType: method.type,
);
print("Method proceeded successfully: $result");
} catch (e) {
print("Error proceeding with method: $e");
}
Handling the formFields
State
When handling the FormFields
state in MoneyHash, you will deal with two primary scenarios: managing billing or shipping data and handling card tokenization. These scenarios are broken down into steps for clarity.
Handling Billing or Shipping Data
-
Rendering Input Fields:
- Use
InputField
data to render form fields. Each field type corresponds to an attribute like name, address, etc., and comes with specific properties to guide the rendering.
- Use
-
Collecting User Input:
- Capture input from these fields in the form of map of key as the field name and value is the user value.
Example of handling billing data:
Map<String, String> billingData = {
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com"
};
Handling card tokenization effectively within the MoneyHash SDK for Flutter involves a few critical steps that integrate secure data handling with user interaction. Below, We'll outline a comprehensive approach using the SecureTextField
and CardCollector
classes to manage card data securely.
Handling Card Tokenization
Overview
Card tokenization in the MoneyHash SDK involves capturing sensitive card information securely and converting it into a token that can be safely stored and transmitted. This process reduces PCI compliance requirements and enhances security.
Step 1: Configure the Card Form Builder
This step involves initializing the CardFormBuilder
and setting up listeners for each card field. These listeners will handle real-time validation and state updates for each input.
CardFormBuilder configureCardFormBuilder() {
// Initialize the builder
CardFormBuilder cardFormBuilder = CardFormBuilder();
// Set up listeners for each field
cardFormBuilder
.setCardNumberField((CardFieldState? state) {
if (state?.isValid ?? false) {
print("Card number is valid");
} else {
print("Card number error: ${state?.errorMessage}");
}
})
.setCVVField((CardFieldState? state) {
if (state?.isValid ?? false) {
print("CVV is valid");
} else {
print("CVV error: ${state?.errorMessage}");
}
})
.setCardHolderNameField((CardFieldState? state) {
if (state?.isValid ?? false) {
print("Card holder name is valid");
} else {
print("Card holder name error: ${state?.errorMessage}");
}
})
.setExpiryMonthField((CardFieldState? state) {
if (state?.isValid ?? false) {
print("Expiry month is valid");
} else {
print("Expiry month error: ${state?.errorMessage}");
}
})
.setExpiryYearField((CardFieldState? state) {
if (state?.isValid ?? false) {
print("Expiry year is valid");
} else {
print("Expiry year error: ${state?.errorMessage}");
}
})
.setCardBrandChangeListener((cardBrand) {
print("CardBrand: ${cardBrand?.brand}");
print("CardBrand: ${cardBrand?.brandIconUrl}");
print("CardBrand: ${cardBrand?.first6Digits}");
});
// You will get the tokenized card info from `FormFields` state, and you need to pass it here
TokenizeCardInfo tokenizeCardInfo = TokenizeCardInfo(/* parameters */);
cardFormBuilder.setTokenizeCardInfo(tokenizeCardInfo);
return cardFormBuilder;
}
Step 2: Build the Card Collector
After configuring the CardFormBuilder
, the next step is to build the CardCollector
from it. The CardCollector
aggregates all card data fields and manages their states, allowing for secure data collection.
CardCollector buildCardCollector(CardFormBuilder cardFormBuilder) {
// Build the CardCollector from the configured CardFormBuilder
CardCollector cardCollector = cardFormBuilder.build();
return cardCollector;
}
-
Implement Secure Text Fields:
- For each card detail (holder name, number, CVV, expiry year, expiry month), implement a
SecureTextField
that binds to theCardCollector
. SecureTextField
should handle user inputs, validate them, and update their respective field state in theCardCollector
.
- For each card detail (holder name, number, CVV, expiry year, expiry month), implement a
-
Collect and Validate Data:
- Before attempting to tokenize the card data, validate all fields using the
CardCollector
'sisValid
method. - If validation passes, proceed to collect the data for tokenization.
- Before attempting to tokenize the card data, validate all fields using the
-
Tokenize and Handle Response:
- Call the
collect
method on theCardCollector
to initiate the tokenization process. - Handle the response which includes either a token (on success) or error handling logic (on failure).
- Call the
Example Implementation
class CardDetailsForm extends StatelessWidget {
final CardCollector cardCollector;
CardDetailsForm({Key? key, required this.cardCollector}) : super(key: key);
@override
Widget build(BuildContext context) {
// Card number field
SecureTextField cardNumberField = SecureTextField(
cardFormCollector: cardCollector,
type: CardFieldType.cardNumber,
placeholder: "Card Number",
label: "Card Number",
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
);
// Card holder name field
SecureTextField cardHolderNameField = SecureTextField(
cardFormCollector: cardCollector,
type: CardFieldType.cardHolderName,
placeholder: "Card Holder Name",
label: "Card Holder Name",
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
);
// CVV field
SecureTextField cvvField = SecureTextField(
cardFormCollector: cardCollector,
type: CardFieldType.cvv,
placeholder: "CVV",
label: "CVV",
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
);
// Expiry month field
SecureTextField expiryMonthField = SecureTextField(
cardFormCollector: cardCollector,
type: CardFieldType.expiryMonth,
placeholder: "MM",
label: "Expiry Month",
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
);
// Expiry year field
SecureTextField expiryYearField = SecureTextField(
cardFormCollector: cardCollector,
type: CardFieldType.expiryYear,
placeholder: "YY",
label: "Expiry Year",
keyboardType: TextInputType.number,
textInputAction: TextInputAction.done,
);
return Column(
children: [
cardNumberField,
cardHolderNameField,
cvvField,
expiryMonthField,
expiryYearField,
ElevatedButton(
onPressed: () async {
if (await cardCollector.isValid()) {
try {
VaultData? vaultData = await cardCollector.collect("intentId");
print("Tokenization successful: ${vaultData?.cardScheme}");
} catch (e) {
print("Tokenization failed: $e");
}
} else {
print("Validation failed");
}
},
child: Text('Tokenize and Submit'),
),
],
);
}
}
Explanation:
- SecureTextField Widgets: Each field is implemented as a
SecureTextField
, which is tied to theCardCollector
. The fields handle user input, with the card number, card holder name, CVV, and expiry year, expiry month managed separately. - Validation and Tokenization: Before tokenization, the form checks if all fields are valid. If valid, it proceeds with tokenization; otherwise, it alerts the user to correct the inputs.
- Handling Responses: Upon successful tokenization, the token should be used to initiate the payment. If tokenization fails, the error is handled appropriately.
Additional requirements for Android
To use the MoneyHash SDK on Android, you must include the following activities in your AndroidManifest.xml file:
<activity android:name="com.moneyhash.sdk.android.payment.PaymentActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar.FullScreen"/>
<activity android:name="com.moneyhash.sdk.android.payout.PayoutActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar.FullScreen"/>
To ensure these activities are displayed in full-screen mode, you can define a custom style in your styles.xml file, as shown below:
<style name="Theme.AppCompat.Light.NoActionBar.FullScreen" parent="@style/Theme.AppCompat.Light.NoActionBar">
<item name="android:windowNoTitle">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
For a detailed guide to all available APIs in the MoneyHash SDK for Flutter, including parameters, return types, and usage examples, refer to this document. This includes methods for handling payments, retrieving intent details, submitting forms, and more.
Overview of MoneyHash APIs
For a detailed guide to all available APIs in the MoneyHash SDK for Flutter, including parameters, return types, and usage examples, refer to this document. This includes methods for handling payments, retrieving intent details, submitting forms, and more.
Overview of MoneyHash Models
The MoneyHash SDK for Flutter features various models to represent data structures like intents, payment methods, transactions, and card information. For comprehensive details on these models, including their properties and usage within the SDK, see the this document.
Questions and Issues
Please provide any feedback via a GitHub Issue.
Libraries
- data/card/card_brand
- data/card/card_field_state
- data/card/card_field_type
- data/card_token_data
- data/discount/discount_data
- data/discount/discount_item
- data/discount/discount_type
- data/fee/fee_data
- data/fee/fee_item
- data/input_field
- data/intent_details
- data/intent_methods
- data/intent_result
- data/intent_state
- data/intent_type
- data/language/language
- data/method_metadata
- data/native_pay_data
- data/product_item
- data/render_strategy
- data/tokenize_card_info
- data/vault_data
- error/mh_exception
- log/log_level
- moneyhash_payment
- style/embed_input_style
- style/embed_input_view_style
- style/embed_loader_style
- style/embed_style
- vault/card_collector
- vault/card_form_builder
- vault/widget/secure_text_field