Android SDK
SDK Guide for Android
Demo project
- Use Android source files for the demo project.
SDK Android Installation / Usage
1- Add mavenCentral()
under allprojects/repositories
and buildscript/repositories
in the project Gradle file.
2-Add the following dependency in the app Gradle file:
implementation 'com.myfatoorah:myfatoorah:3.0.4'
Add bellow line in the onCreate()
method of your Application
class:
// set up your My Fatoorah Merchant details
MFSDK.init("Put you Token API Key here", MFCountry.KUWAIT, MFEnvironment.TEST)
// set up your My Fatoorah Merchant details
MFSDK.INSTANCE.init("Put you Token API Key here", MFCountry.KUWAIT, MFEnvironment.TEST);
Add bellow code in the onCreate()
method of your Activity
:
// You can custom your action bar, but this is optional not required to set this line
MFSDK.setUpActionBar("MyFatoorah Payment", R.color.toolbar_title_color, R.color.toolbar_background_color, true)
// To hide action bar
// MFSDK.setUpActionBar(isShowToolBar = false)
// You can custom your action bar, but this is optional not required to set this line
MFSDK.INSTANCE.setUpActionBar("MyFatoorah Payment", R.color.toolbar_title_color, R.color.toolbar_background_color, true);
After Testing
Once your testing is finished, simply replace environment from TEST to LIVE and the API URL with the live, click here for more information.
Initiate/Execute Payment
As described earlier for the Gateway Integration, we are going to have the SDK integrated with the same steps to make a successful integration with the SDK.
Initiate Payment
As a good practice, you don't have to call the Initiate Payment function every time you need to execute payment, but you have to call it at least once to save the PaymentMethodId that you will need to call Execute Payment
// initiatePayment
val request = MFInitiatePaymentRequest(0.100, MFCurrencyISO.KUWAIT_KWD)
MFSDK.initiatePayment(
request,
MFAPILanguage.EN
) { result: MFResult<MFInitiatePaymentResponse> ->
when (result) {
is Success ->
Log.d(TAG, "Response: " + Gson().toJson(result.response))
is Fail ->
Log.d(TAG, "Fail: " + Gson().toJson(result.error))
}
}
// executePayment
val request = MFExecutePaymentRequest(1, 0.100)
MFSDK.executePayment(
this,
request,
MFAPILanguage.EN,
onInvoiceCreated = {
Log.d(TAG, "invoiceId: $it")
}
) { invoiceId: String, result: MFResult<MFGetPaymentStatusResponse> ->
when (result) {
is Success ->
Log.d(TAG, "Response: " + Gson().toJson(result.response))
is Fail ->
Log.d(TAG, "Fail: " + Gson().toJson(result.error))
}
}
// initiatePayment
MFInitiatePaymentRequest request = new MFInitiatePaymentRequest(0.100, MFCurrencyISO.KUWAIT_KWD);
MFSDK.INSTANCE.initiatePayment(
request,
MFAPILanguage.EN,
(MFResult<MFInitiatePaymentResponse> result) -> {
if (result instanceof Success) {
Log.d(TAG, "Response: " + new Gson().toJson(
((Success<MFInitiatePaymentResponse>) result).getResponse()));
} else if (result instanceof Fail) {
Log.d(TAG, "Error: " + new Gson().toJson(((Fail) result).getError()));
}
return Unit.INSTANCE;
});
// executePayment
MFExecutePaymentRequest request = new MFExecutePaymentRequest(1, 0.100);
MFSDK.INSTANCE.executePayment(
this,
request,
MFAPILanguage.EN,
(String invoiceId) -> {
Log.d(TAG, "invoiceId: " + invoiceId);
return Unit.INSTANCE;
},
(String invoiceId, MFResult<MFGetPaymentStatusResponse> result) -> {
if (result instanceof Success)
Log.d(TAG, "Response: " + new Gson().toJson(((Success<MFGetPaymentStatusResponse>) result).getResponse()));
else if (result instanceof Fail)
Log.d(TAG, "Error: " + new Gson().toJson(((Fail) result).getError()));
return Unit.INSTANCE;
});
Direct Payment/Tokenization
As we have explained earlier in the [Direct Payment] integration and how it works, it also has the same scenario for the SDK implementation, you have to know the following steps to understand how it works:
- Get the payment method that allows Direct Payment by calling initiatePayment to get paymentMethodId
- Collect card info from user MFCardInfo(cardNumber: "51234500000000081", cardExpiryMonth: "05", cardExpiryYear: "21", cardSecurityCode: "100", saveToken: false)
- If you want to save your credit card info and get a token for next payment you have to set saveToken: true and you will get the token in the response read more in Tokenization
- If you want to execute a payment through a saved token you have use MFCardInfo(cardToken: "put your token here")
- Now you are ready to execute the payment, please check the following sample code
val request = MFExecutePaymentRequest(2, 0.100)
// val mfCardInfo = MFCardInfo("Your token here")
val mfCardInfo = MFCardInfo("5123450000000008", "09", "21", "100", true)
MFSDK.executeDirectPayment(
this,
request,
mfCardInfo,
MFAPILanguage.EN,
onInvoiceCreated = {
Log.d(TAG, "invoiceId: $it")
}
) { invoiceId: String, result: MFResult<MFDirectPaymentResponse> ->
when (result) {
is Success ->
Log.d(TAG, "Response: " + Gson().toJson(result.response))
is Fail ->
Log.d(TAG, "Fail: " + Gson().toJson(result.error))
}
}
MFExecutePaymentRequest request = new MFExecutePaymentRequest(2, 0.100);
// MFCardInfo mfCardInfo = new MFCardInfo("Your token here");
MFCardInfo mfCardInfo = new MFCardInfo("5123450000000008", "09", "21", "100", false);
MFSDK.INSTANCE.executeDirectPayment(
this,
request,
mfCardInfo,
MFAPILanguage.EN,
(String invoiceId) -> {
Log.d(TAG, "invoiceId: " + invoiceId);
return Unit.INSTANCE;
},
(String invoiceId, MFResult<MFDirectPaymentResponse> result) -> {
if (result instanceof Success)
Log.d(TAG, "Response: " + new Gson().toJson(((Success<MFDirectPaymentResponse>) result).getResponse()));
else if (result instanceof Fail)
Log.d(TAG, "Error: " + new Gson().toJson(((Fail) result).getError()));
return Unit.INSTANCE;
});
Send Payment
We have explained in the Send Payment section earlier, the different usage cases for it and how it works, here we are going to embed some sample code for calling it through the SDK on the different platforms
val request = MFSendPaymentRequest(0.100, "Customer name", MFNotificationOption.LINK)
MFSDK.sendPayment(request, MFAPILanguage.EN) { result: MFResult<MFSendPaymentResponse> ->
when(result){
is MFResult.Success ->
Log.d(TAG, "Response: " + Gson().toJson(result.response))
is MFResult.Fail ->
Log.d(TAG, "Fail: " + Gson().toJson(result.error))
}
}
MFSendPaymentRequest request = new MFSendPaymentRequest(0.100, "Customer name", MFNotificationOption.LINK);
MFSDK.INSTANCE.sendPayment(request, MFAPILanguage.EN, (MFResult<MFSendPaymentResponse> result) -> {
if (result instanceof MFResult.Success)
Log.d(TAG, "Response: " + new Gson().toJson(((MFResult.Success<MFSendPaymentResponse>) result).getResponse()));
else if (result instanceof MFResult.Fail)
Log.d(TAG, "Error: " + new Gson().toJson(((MFResult.Fail) result).getError()));
return Unit.INSTANCE;
});
Payment Inquiry
We have explain the main usage for the Payment Inquiry function, that will enable your application to get the full details about a certain invoice / payment. You can use this function within your application on the different platforms as well. Here we are explaining some samples of its usage through the SDK.
val request = MFGetPaymentStatusRequest("12345", MFKeyType.INVOICE_ID)
MFSDK.getPaymentStatus(request, "en", object: MFCallback<MFGetPaymentStatusResponse>{
override fun onResponse(isSuccess: Boolean, response: MFGetPaymentStatusResponse?, error: MFError?) {
if(isSuccess)
Log.d(TAG, "Response: " + Gson().toJson(response))
else
Log.d(TAG, "Error: " + Gson().toJson(error))
}
})
MFGetPaymentStatusRequest request = new MFGetPaymentStatusRequest("12345", MFKeyType.INVOICE_ID);
MFSDK.INSTANCE.getPaymentStatus(request, "en", new MFCallback<MFGetPaymentStatusResponse>() {
@Override
public void onResponse(boolean isSuccess, @Nullable MFGetPaymentStatusResponse response, @Nullable MFError error) {
if (isSuccess)
Log.d(TAG, "Response: " + new Gson().toJson(response));
else
Log.d(TAG, "Error: " + new Gson().toJson(error));
}
});
Android Embedded Payment Usage
Step 1:
Add MFPaymentCardView
in your xml
layout like the following:
<com.myfatoorah.sdk.views.embeddedpayment.MFPaymentCardView
android:id="@+id/mfPaymentView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Note:
you could custom a lot of properties of the payment card view like the following:
<com.myfatoorah.sdk.views.embeddedpayment.MFPaymentCardView
android:id="@+id/mfPaymentView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:inputColor="@color/paymentCardViewTextColor"
app:labelColor="@color/paymentCardViewLabelColor"
app:errorColor="@color/paymentCardViewValidateTextColor"
app:cardHolderNameHint="cardHolderNameHint"
app:cardNumberHint="cardNumberHint"
app:expiryDateHint="expiryDateHint"
app:cvvHint="cvvHint"
app:showLabels="false"
app:cardHolderNameLabel="cardHolderNameLabel"
app:cardNumberLabel="cardNumberLabel"
app:expiryDateLabel="expiryDateLabel"
app:cvvLabel="cvvLabel"/>
(Alternative Option) You could custom a lot of properties of the payment card view in code behind like the following:
mfPaymentView.cardStyle = MFCardViewStyle(
hideCardIcons = false,
direction = "ltr",
cardHeight = 230,
input = MFCardViewInput(
color = getColorFromRes(R.color.cardview_input_text_color),
fontSize = 13f,
fontFamily = MFFontFamily.Tahoma,
inputHeight = 32f,
inputMargin = 0f,
borderColor = getColorFromRes(R.color.cardview_input_border_color),
borderWidth = 2f,
borderRadius = 8f,
boxShadow = MFBoxShadow(10, 10, 5, 0, getColorFromRes(R.color.cardview_input_boxshadow_color)),
placeHolder = MFCardViewPlaceHolder(
holderName = "Name On Card test",
cardNumber = "Number test",
expiryDate = "MM / YY",
securityCode = "CVV test"
)
),
label = MFCardViewLabel(
display = true,
color = getColorFromRes(R.color.cardview_label_text_color),
fontSize = 13f,
fontFamily = MFFontFamily.CourierNew,
fontWeight = MFFontWeight.Bold,
text = MFCardViewText(
holderName = "Card Holder Name test",
cardNumber = "Card Number test",
expiryDate = "Expiry Date test",
securityCode = "Security Code test"
)
),
error = MFCardViewError(
borderColor = getColorFromRes(R.color.cardview_error_border_color),
borderRadius = 8f,
boxShadow = MFBoxShadow(10, 10, 5, 0, getColorFromRes(R.color.cardview_error_boxshadow_color))
)
)
MFCardViewInput cardViewInput = new MFCardViewInput(
getColorFromRes(R.color.cardview_input_text_color),
13f,
MFFontFamily.Tahoma,
32f,
0f,
getColorFromRes(R.color.cardview_input_border_color),
2f,
8f,
new MFBoxShadow(10, 10, 5, 0, getColorFromRes(R.color.cardview_input_boxshadow_color)),
new MFCardViewPlaceHolder("Name On Card test", "Number test", "MM / YY", "CVV test")
);
MFCardViewLabel cardViewLabel = new MFCardViewLabel(
true,
getColorFromRes(R.color.cardview_label_text_color),
13f,
MFFontFamily.CourierNew,
MFFontWeight.Bold,
new MFCardViewText("Card Holder Name test", "Card Number test", "Expiry Date test", "Security Code test")
);
MFCardViewError cardViewError = new MFCardViewError(
getColorFromRes(R.color.cardview_error_border_color),
8f,
new MFBoxShadow(10, 10, 5, 0, getColorFromRes(R.color.cardview_error_boxshadow_color))
);
MFCardViewStyle cardViewStyle =
new MFCardViewStyle(false, "ltr", 230, cardViewInput, cardViewLabel, cardViewError);
mfPaymentView.setCardStyle(cardViewStyle);
Step 2:
You need to call initiateSession()
function to create session. You need to do this for each payment separately. Session is valid for only one payment. and inside it's success state, call load()
function and pass it the session response, to load the payment card view on the screen, like the following:
Note:
If you want to use saved card option with embedded payment, send the parameter customerIdentifier
in the MFInitiateSessionRequest
with a unique value for each customer. This value cannot be used for more than one Customer. Check commented lines in the following code.
// val request = MFInitiateSessionRequest(customerIdentifier = "12345")
// MFSDK.initiateSession(request)
MFSDK.initiateSession {
when (it) {
is MFResult.Success -> {
mfPaymentView.load(
it.response,
onCardBinChanged = { bin ->
Log.d(TAG, "bin: $bin")
}
)
}
is MFResult.Fail -> {
Log.d(TAG, "Fail: " + Gson().toJson(it.error))
}
}
}
// MFInitiateSessionRequest request = new MFInitiateSessionRequest("12332212");
// MFSDK.INSTANCE.initiateSession(request, (MFResult<MFInitiateSessionResponse> result) -> {
MFSDK.INSTANCE.initiateSession(null, (MFResult<MFInitiateSessionResponse> result) -> {
if (result instanceof MFResult.Success) {
mfPaymentView.load(
((Success<MFInitiateSessionResponse>) result).getResponse(),
(String bin) -> {
Log.d(TAG, "bin: " + bin);
return Unit.INSTANCE;
});
}
if (result instanceof MFResult.Fail) {
Log.d(TAG, "Fail: " + new Gson().toJson(((Fail) result).getError()));
}
return Unit.INSTANCE;
});
Note:
The initiateSession()
function should called after MFSDK.init()
function (that we mentioned above).
Step 3:
Finally, you need to handle your Pay
button to call the pay()
function, copy the below code to your pay event handler section:
val request = MFExecutePaymentRequest(0.100)
mfPaymentView.pay(
this,
request,
MFAPILanguage.EN,
onInvoiceCreated = {
Log.d(TAG, "invoiceId: $it")
}
) { invoiceId: String, result: MFResult<MFGetPaymentStatusResponse> ->
when (result) {
is MFResult.Success -> {
Log.d(TAG, "Response: " + Gson().toJson(result.response))
}
is MFResult.Fail -> {
Log.d(TAG, "Fail: " + Gson().toJson(result.error))
}
}
Log.d(TAG, "invoiceId: $invoiceId")
}
MFExecutePaymentRequest request = new MFExecutePaymentRequest(0.100);
mfPaymentView.pay(
this,
request,
MFAPILanguage.EN,
(String invoiceId) -> {
Log.d(TAG, "invoiceId: " + invoiceId);
return Unit.INSTANCE;
},
(String invoiceId, MFResult<MFGetPaymentStatusResponse> result) -> {
if (result instanceof MFResult.Success) {
Log.d(TAG, "Response: " + new Gson().toJson(((Success<MFGetPaymentStatusResponse>) result).getResponse()));
}
else if (result instanceof MFResult.Fail) {
String error = new Gson().toJson(((Fail) result).getError());
Log.d(TAG, "Fail: " + error);
}
Log.d(TAG, "invoiceId:" + invoiceId);
return Unit.INSTANCE;
});
(Alternative Option) You can validate the session first and complete the payment if the session is valid
val request = MFExecutePaymentRequest(0.100)
mfPaymentView.validate { result: MFResult<String> ->
when (result) {
is MFResult.Success -> {
Log.d(TAG, "Response: " + Gson().toJson(result.response))
mfPaymentView.pay(
this,
request,
MFAPILanguage.EN,
onInvoiceCreated = { Log.d(TAG, "invoiceId: $it") })
{ invoiceId: String, result: MFResult<MFGetPaymentStatusResponse> ->
when (result) {
is MFResult.Success -> {
Log.d(TAG, "Response: " + Gson().toJson(result.response))
}
is MFResult.Fail -> {
Log.d(TAG, "Fail: " + Gson().toJson(result.error))
}
}
}
}
is MFResult.Fail -> Log.d(TAG, "Fail: " + Gson().toJson(result.error))
}
}
MFExecutePaymentRequest request = new MFExecutePaymentRequest(0.100);
mfPaymentView.validate((MFResult<String> resultValidate) -> {
if (resultValidate instanceof MFResult.Success) {
Log.d(TAG, "Response: " + new Gson().toJson(((Success<String>) resultValidate).getResponse()));
mfPaymentView.pay(
this,
request,
MFAPILanguage.EN,
(String invoiceId) -> {
Log.d(TAG, "invoiceId: " + invoiceId);
return Unit.INSTANCE;
},
(String invoiceId, MFResult<MFGetPaymentStatusResponse> resultPay) -> {
if (resultPay instanceof MFResult.Success) {
Log.d(TAG, "Response: " + new Gson().toJson(((Success<MFGetPaymentStatusResponse>) resultPay).getResponse()));
} else if (resultPay instanceof MFResult.Fail) {
Log.d(TAG, "Fail: " + new Gson().toJson(((Fail) resultPay).getError()));
}
return Unit.INSTANCE;
});
} else if (resultValidate instanceof MFResult.Fail) {
Log.d(TAG, "Fail: " + new Gson().toJson(((Fail) resultValidate).getError()));
}
return Unit.INSTANCE;
});
Read Card with NFC (Optional)
Add the following code if you want to add the feature of a reading card with NFC.
binding.mfPaymentView.load(
initiateSessionResponse,
onCardBinChanged = { bin ->
Log.d(TAG, "bin: $bin")
},
onCardHeightChanged = { height ->
Log.d(TAG, "height: $height")
},
showNFCReadCardIcon = true
)
mfPaymentView.enableCardNFC(this)
override fun onResume() {
super.onResume()
mfPaymentView.enableCardNFC(this)
}
public override fun onPause() {
super.onPause()
mfPaymentView.disableCardNFC(this)
}
mfPaymentCardView.load(
initiateSessionResponse,
(String bin) -> {
Log.d("TAG", bin);
return Unit.INSTANCE;
}, (Float height) -> {
Log.d("TAG", height.toString());
return Unit.INSTANCE;
}, true);
mfPaymentCardView.enableCardNFC(this);
@Override
protected void onResume() {
super.onResume();
mfPaymentView.enableCardNFC(this);
}
@Override
protected void onPause() {
super.onPause();
mfPaymentView.disableCardNFC(this);
}
Google Pay
This section guides you through the integration of Google Pay using the MyFatoorah SDK for Android applications. The provided example demonstrates how to set up and handle payments with Google Pay within your app.
Step 1: Initiating Session for Google Pay:
Before making any Google Pay transactions, initiate session for transactions.
MFSDK.initiateSession(MFInitiateSessionRequest(customerIdentifier = "your_customer_identifier")) {
when (it) {
is MFResult.Success -> setupGooglePayHelper(it.response.sessionId)
is MFResult.Fail -> Log.d(TAG, "Session initiation failed: " + Gson().toJson(it.error))
else -> {}
}
}
Step 2: Setting Up GooglePayRequest:
Configure Google Pay with necessary details such as the merchant ID, merchant name, country code, and currency.
val googlePayRequest = GooglePayRequest(
totalPrice = "1", // Total price for the transaction
merchantId = "your_merchant_id",
merchantName = "your_merchant_name",
countryCode = MFCountry.KUWAIT.code,
currencyIso = MFCurrencyISO.UAE_AED
)
Step 3: Setting Up MFGooglePayHelper:
Set the Google Pay button in your layout to initiate payments. Use the MFGooglePayHelper to handle the transaction process and results.
mfGooglePayHelper = MFGooglePayHelper(
activity = this,
googlePayRequestCODE = googlePayRequestCODE,
sessionId = sessionId,
googlePayRequest = googlePayRequest,
onInvoiceCreated = { invoiceId -> Log.d(TAG, "Invoice Created: $invoiceId") },
callback = { invoiceId, mfResult ->
when (mfResult) {
is MFResult.Success -> Log.d(TAG, "Payment Success: " + Gson().toJson(mfResult.response))
is MFResult.Fail -> Log.d(TAG, "Payment Failed: " + Gson().toJson(mfResult.error))
else -> {}
}
}
)
mfGooglePayHelper.setGooglePayButton(binding.mfGooglePayButton)
Step 4: Handling Activity Results:
Ensure to handle the result from the Google Pay activity in your onActivityResult.
private val googlePayRequestCODE: Int = 991 // Any unique requestCode specified for GooglePay
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == googlePayRequestCODE) {
mfGooglePayHelper.onActivityResult(requestCode, resultCode, data)
}
}
Step 5: Add MFGooglePayButton:
Use MFGooglePayButton
Add MFGooglePayButton in your layout.xml
<com.myfatoorah.sdk.views.embeddedpayment.googlepay.MFGooglePayButton
android:id="@+id/mfGooglePayButton"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Another option
- Add a Google Pay button to your layout:
<com.google.android.gms.wallet.button.PayButton
android:id="@+id/googlePayButton"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
- Ensure you have the necessary dependencies in your build.gradle file:
// Google Wallet
implementation 'com.google.android.gms:play-services-wallet:19.4.0'
- Update your AndroidManifest.xml to include the necessary permissions and metadata:
<uses-permission android:name="android.permission.INTERNET"/>
<application ...>
<meta-data
android:name="com.google.android.gms.wallet.api.enabled"
android:value="true"/>
</application>
Step 6: Going Live with google pay:
- Complete your google Business Profile and get your Merchant ID.
- Request production access from Google Pay & Wallet Console.
Updated about 2 months ago