Android SDK

This SDK provides an UI to take required information from user to execute transaction.

Sample Project to implement the Android SDK here.


Latest Version

Download the latest version here.

Latest Released version logs on Github release page.




Download Demo App


If you want to have a look at SDK in more convenient manner, you can download latest version of our demo app from Google Play Store. This app is using the latest version of SDK.

Get it on Google Play




Android SDK Changes


version 1.28.0:


  • If using UIKit and the device is going to use 3G/4G internet (Data network), it is required on Android to have READ_PHONE_STATE permission in order to access network type of the device. the purpose of READ_PHONE_STATE permission is to capture network on event tracker. Therefore, before launching the UI kit, it is mandatory to check if this permission has been granted or not. If it has not been granted, we need to keep asking user. It is not needed for WIFI connection and version below 1.28.0.

Request Permission before launching UI kit for Android SDK version 1.28.0 and above

if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
     ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 101);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
  ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 101);
}
  • If the Host app got build error with message Invoke-customs are only supported starting with Android O a block of code to specify java version is needed on build.gradle.

compileOptions {
       sourceCompatibility JavaVersion.VERSION_1_8
	   targetCompatibility JavaVersion.VERSION_1_8
	}
compileOptions {
  sourceCompatibility JavaVersion.VERSION_1_8
  targetCompatibility JavaVersion.VERSION_1_8
}

Starting version 1.29.0:

  • To avoid crash in SDK Version 1.29.0, it will make optional to implement READ_PHONE_STATE permission, so the host app is not required to ask the user to give the permission.

  • Since we increase the localizationVersion to 1.2.10 it required to add multiDexEnabled true in Host App build.gradle


[Important] Starting version 1.34.0:


  • To avoid inconsistencies for e-money method on tablet, starting from version 1.34.0 the payment type for gopay on tablet is no longer gopay but changed to qris same as ShopeePay using qris
  • The JSON fields format response is different between "payment_type": "qris" and "payment_type": "gopay" . This will affect Webhook/HTTP Notification and Get Status API Response. Refer to the notification example section for details.
  • Due to the difference in response between qris and gopay, you need to remap the response for the Notification and Get Status API. So please ensure that your system’s implementation can handle this behavior without breaking your system & its payment flow. Especially on the following parts (if applicable):
    • Your Notifications Handler implementation logic.
    • Get Status API implementation logic.
    • Reconciliation implementation logic.
  • For more details regarding QRIS related behavior, please refer to this section

[Important] Starting version 2.0.0:


  • Midtrans SDK 2.0.0 is a major revamp for Midtrans SDK that includes UI changes and updates to improve user experience.
  • There are two scenarios for the existing users to write code using this Revamp SDK:
    • Using Existing Code: For existing users who want to continue using their existing code, simply upgrade the SDK version in the build.gradle file. This revamp supports backward compatibility, so there is no need to make any changes to the existing code.
    • Using Revamped Code: For existing users who want to take advantage of the new UI changes and improvements, we recommend using the revamped code. This approach will ensure that future updates to the SDK, since the next updates will released with the revamp-first mindset.
  • For new users who are just starting to use the Midtrans Mobile SDK, we highly recommend using the revamped approach. This will ensure that you have access to the latest updates and improvements to the SDK.

🚧

Please make sure to follow the setup instructions and guidelines provided in the Snap SDK documentation to ensure a smooth integration process. If you have any questions or concerns, don't hesitate to reach out to our support team.




Android Permission


UI KIT

  • ACCESS_NETWORK_STATE
  • READ_PHONE_STATE

Core KIT

  • ACCESS_NETWORK_STATE
  • INTERNET



Installation


Add SDK installation following into your build.gradle


Midtrans Maven Repository

repositories {
    jcenter()
        maven { url "https://jitpack.io" }
    }
repositories {
  jcenter()
  	maven { url "https://jitpack.io" }
  }

Sample SDK Sandbox Dependencies

dependencies {
    // For using the Midtrans Sandbox
    implementation 'com.midtrans:uikit:2.0.0-SANDBOX' // change the number to the latest version
  }
dependencies {
	// For using the Midtrans Sandbox
    implementation 'com.midtrans:uikit:2.0.0-SANDBOX' // change the number to the latest version
  }

Sample SDK Production Dependencies

dependencies {
    // For using the Midtrans Production
    implementation 'com.midtrans:uikit:2.0.0' // change the number to the latest version
}
dependencies {
	// For using the Midtrans Production
	implementation 'com.midtrans:uikit:1.34.0' // change the number to the latest version
}

You need to add Midtrans SDK inside your app’s module build.gradle. Make sure to use the proper environment (SANDBOX / PRODUCTION).


Midtrans SDK Initialization

UiKitApi.Builder()
        .withMerchantClientKey(CLIENT_KEY) // client_key is mandatory
        .withContext(CONTEXT) // context is mandatory
        .withMerchantUrl(BASE_URL) // set transaction finish callback (sdk callback)
        .enableLog(true) // enable sdk log (optional)
        .withFontFamily(ASSET_FONT)
        .withColorTheme(CustomColorTheme("#FFE51255", "#B61548", "#FFE51255"))
        .build()
setLocaleNew("en") //`en` for English and `id` for Bahasa

...

// function to set the SDK language
private fun setLocaleNew(languageCode: String?) {
    val locales = LocaleListCompat.forLanguageTags(languageCode)
    AppCompatDelegate.setApplicationLocales(locales)
}
SdkUIFlowBuilder.init()
  .setClientKey(CLIENT_KEY) // client_key is mandatory
  .setContext(CONTEXT) // context is mandatory
  .setTransactionFinishedCallback(new TransactionFinishedCallback() {
    @Override
    public void onTransactionFinished(TransactionResult result) {
    	// Handle finished transaction here.
    }
  }) // set transaction finish callback (sdk callback)
  .setMerchantBaseUrl(BASE_URL) //set merchant url (required)
  .enableLog(true) // enable sdk log (optional)
  .setColorTheme(new CustomColorTheme("#FFE51255", "#B61548", "#FFE51255")) // set theme. it will replace theme on snap theme on MAP ( optional)
  .setLanguage("en") //`en` for English and `id` for Bahasa
  .buildSDK();

Then you need to initialize it on your activity or application class.


Note:

  • CONTEXT: Application/activity context
  • CLIENT_KEY: Your midtrans client key (provided in MAP)
  • BASE_URL: Your merchant server URL

Differentiate Sandbox and Production in one app (Optional)


Differentiate Sandbox and Production Flavors

android {
  ...
  // Define Merchant BASE URL and CLIENT KEY for each flavors
  productFlavors {
          sandbox {
              buildConfigField "String", "BASE_URL", "\"https://merchant-url-sandbox.com/\""
              buildConfigField "String", "CLIENT_KEY", "\"VT-CLIENT-sandbox-client-key\""
          }

          production {
              buildConfigField "String", "BASE_URL", "\"https://merchant-url-production.com/\""
              buildConfigField "String", "CLIENT_KEY", "\"VT-CLIENT-production-client-key\""
         }
  }
  ...
}

// Define Midtrans SDK dependencies for each flavors
dependencies {
  ...
  sandboxImplementation 'com.midtrans:uikit:2.0.0-SANDBOX' // change the version to latest one
  productionImplementation 'com.midtrans:uikit:2.0.0' // change the version to latest one
  ...
}
android {
  ...
  // Define Merchant BASE URL and CLIENT KEY for each flavors
  productFlavors {
    sandbox {
      buildConfigField "String", "BASE_URL", "\"https://merchant-url-sandbox.com/\""
      buildConfigField "String", "CLIENT_KEY", "\"VT-CLIENT-sandbox-client-key\""
    }

    production {
      buildConfigField "String", "BASE_URL", "\"https://merchant-url-production.com/\""
      buildConfigField "String", "CLIENT_KEY", "\"VT-CLIENT-production-client-key\""
    }
  }
  ...
}

// Define Midtrans SDK dependencies for each flavors
dependencies {
  ...
  sandboxImplementation 'com.midtrans:uikit:1.34.0-SANDBOX' // change the version to latest one
  productionImplementation 'com.midtrans:uikit:1.34.0' // change the version to latest one
  ...
}

You can support two payment environments in your app by defining two flavors in your build.gradle.


Initialize Midtrans SDK using provided base URL and client key in BuildConfig

UiKitApi.Builder()
        .withMerchantClientKey(CLIENT_KEY) // client_key is mandatory
        .withContext(CONTEXT) // context is mandatory
        .withMerchantUrl(BASE_URL) // set transaction finish callback (sdk callback)
        .enableLog(true) // enable sdk log (optional)
        .withFontFamily(ASSET_FONT) // set font family
        .withColorTheme(CustomColorTheme("#FFE51255", "#B61548", "#FFE51255")) // set theme. it will replace theme on snap theme on MAP ( optional)
        .build()
SdkUIFlowBuilder.init()
  .setClientKey(CLIENT_KEY) // client_key is mandatory
  .setContext(CONTEXT) // context is mandatory
  .setTransactionFinishedCallback(new TransactionFinishedCallback() {
    	@Override
      public void onTransactionFinished(TransactionResult result) {
      	// Handle finished transaction here.
      }
    }) // set transaction finish callback (sdk callback)
  .setMerchantBaseUrl(BASE_URL) //set merchant url (required)
  .enableLog(true) // enable sdk log (optional)
  .setColorTheme(new CustomColorTheme("#FFE51255", "#B61548", "#FFE51255")) // set theme. it will replace theme on snap theme on MAP ( optional)
  .buildSDK();

Initialize your SDK using merchant BASE_URL and CLIENT_KEY provided by BuildConfig data.




Starting Payment


Use Snap Token Flow


The easiest way to use the SDK - what you need to do will be to integrate to Midtrans' backend and retrieve the Snap Token, then pass Snap token as argument of startPaymentUiFlow method. SDK will then show the payment page immediately; no need to create any transaction object on the SDK.


[[MidtransMerchantClient shared] requestTransacationWithCurrentToken:{{string token}}
  completion:^(MidtransTransactionTokenResponse * _Nullable regenerateToken, NSError * _Nullable error) {
  	MidtransUIPaymentViewController *paymentVC = [[MidtransUIPaymentViewController alloc] initWithToken:token];
  	paymentVC.paymentDelegate = self;
  	[self.navigationController presentViewController:paymentVC animated:YES completion:nil];
}];

val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result?.resultCode == RESULT_OK) {
        result.data?.let {
            val transactionResult = it.getParcelableExtra<TransactionResult>(UiKitConstants.KEY_TRANSACTION_RESULT)
            Toast.makeText(this,"${transactionResult?.transactionId}", Toast.LENGTH_LONG).show()
        }
    }
}

UiKitApi.getDefaultInstance().startPaymentUiFlow(
    this@MainActivity, // Activity
    launcher, // ActivityResultLauncher
    "25e3659b-f00c-4d98-bfff-9f72978c8df5" // Snap Token
)
MidtransSDK.getInstance().startPaymentUiFlow(ACTIVITY_CONTEXT, SNAP_TOKEN);

Use SDK Flow


SDK flow is another way to start the SDK where merchant needs to create all the transaction details (transaction request object) through the SDK e.g. : Customer Details, Item Details etc. Then SDK will request for a Snap token based on the transaction details and start the payment after.


Prepare Transaction Details


TRANSACTION_ID and TOTAL_AMOUNT are required to create a transaction request for each payment.


Create Transaction Request object

//TransactionRequest on revamp is included in the startPayment Constructor

val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result?.resultCode == RESULT_OK) {
        result.data?.let {
            val transactionResult = it.getParcelableExtra<TransactionResult>(UiKitConstants.KEY_TRANSACTION_RESULT)
            Toast.makeText(this,"${transactionResult?.transactionId}", Toast.LENGTH_LONG).show()
        }
    }
}
val itemDetails = listof(ItemDetails("Test01", 50000.00, 1, "lalalala"))

UiKitApi.getDefaultInstance().startPaymentUiFlow(
    this@MainActivity, // activity
    launcher, //ActivityResultLauncher 
    SnapTransactionDetail(UUID.randomUUID().toString(), 50000.00, "IDR"), // Transaction Details 
    CustomerDetails("budi-6789", "Budi", "Utomo", "[email protected]", "0213213123", null, null), // Customer Details
    itemDetails, // Item Details
    CreditCard(false, null, false, null, null, null, null, null, null, null, null), // Credit Card
    "customerIdentifier", // User Id
    PaymentCallback("mysamplesdk://midtrans"), // UobEzpayCallback
    GopayPaymentCallback("mysamplesdk://midtrans"), // GopayCallback
    PaymentCallback("mysamplesdk://midtrans"), // ShopeepayCallback
    Expiry(getFormattedTime(System.currentTimeMillis()), Expiry.UNIT_HOUR, 5), // expiry (null: default expiry time)
    PaymentMethod.CREDIT_CARD, // Direct Payment Method Type
    listOf(PaymentType.CREDIT_CARD, PaymentType.GOPAY, PaymentType.SHOPEEPAY, PaymentType.UOB_EZPAY), // Enabled Payment (null: enabled all available payment)
    BankTransferRequest(vaNumber = "1234567890"), // Permata Custom VA (null: default va)
    BankTransferRequest(vaNumber = "12345"), // BCA Custom VA (null: default va)
    BankTransferRequest(vaNumber = "12345"), // BNI Custom VA (null: default va)
    BankTransferRequest(vaNumber = "12345"), // BRI Custom VA (null: default va)
    "Cash1", // Custom Field 1
    "Debit2", // Custom Field 2
    "Credit3"  // Custom Field 3
)
TransactionRequest transactionRequest = new TransactionRequest(TRANSACTION_ID, TOTAL_AMOUNT);

Adding Customer Detail (Optional)


Create CustomerDetails object

val shippingAddress = Address(
    null,  // First Name
    null,  // Last Name
    "Jalan Andalas Gang Sebelah No. 1",  // Address
    "Jakarta",  // City
    "10220",  // PostCode
    null,  // Phone Number
    null // Country Code
)
val billingAddress = Address(
    null,  // First Name
    null,  // Last Name
    "Jalan Andalas Gang Sebelah No. 1",  // Address
    "Jakarta",  // City
    "10220",  // PostCode
    null,  // Phone Number
    null // Country Code
)
val customerDetails = CustomerDetails(
    "budi-6789",  // Customer Identifier
    "Budi",  // First Name
    "Utomo",  // Last Name
    "[email protected]",  // Email
    "0213213123",  // Phone Number
    shippingAddress,  // Shipping Address
    billingAddress // Billing Address
)
CustomerDetails customerDetails = new CustomerDetails();
customerDetails.setCustomerIdentifier("budi-6789");
customerDetails.setPhone("08123456789");
customerDetails.setFirstName("Budi");
customerDetails.setLastName("Utomo");
customerDetails.setEmail("[email protected]");

ShippingAddress shippingAddress = new ShippingAddress();
shippingAddress.setAddress("Jalan Andalas Gang Sebelah No. 1");
shippingAddress.setCity("Jakarta");
shippingAddress.setPostalCode("10220");
customerDetails.setShippingAddress(shippingAddress);

BillingAddress billingAddress = new BillingAddress();
billingAddress.setAddress("Jalan Andalas Gang Sebelah No. 1");
billingAddress.setCity("Jakarta");
billingAddress.setPostalCode("10220");
customerDetails.setBillingAddress(billingAddress);

transactionRequest.setCustomerDetails(customerDetails);

By default, SDK expect you to supply it with customer detail. Customer detail usually consists of first and last name, email, phone number, billing address, and shipping address. For addresses, you can set billing and shipping as one address. If you want to send customer detail to your merchant server during checkout, please create CustomerDetails object and supply it into SDK in Transaction Request object.

If you don't want to supply customer detail at all, you can use UIKitCustomSetting to skip this process.


NOTE : Before running the project, please make sure that host app doesn’t use action bar in its theme because it will be clash with toolbar used in Midtrans SDK. For example, we can use this config in styles.xml :


<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

Item Details


Item details are required for Mandiri Bill and BCA KlikPay payment; it is optional for other payment methods.

ItemDetails class holds information about item purchased by user. TransactionRequest takes an array list of item details.


Item Details Object

val itemDetails1 = ItemDetails(ITEM_ID_1, ITEM_PRICE_1, ITEM_QUANTITY_1, ITEM_NAME_1)
val itemDetails2 = ItemDetails(ITEM_ID_2, ITEM_PRICE_2, ITEM_QUANTITY_2, ITEM_NAME_2)
val itemDetails = listOf(itemDetails1, itemDetails2)
ItemDetails itemDetails1 = new ItemDetails(ITEM_ID_1, ITEM_PRICE_1, ITEM_QUANTITY_1, ITEM_NAME_1);
ItemDetails itemDetails2 = new ItemDetails(ITEM_ID_2, ITEM_PRICE_2, ITEM_QUANTITY_2, ITEM_NAME_2);

// Create array list and add above item details in it and then set it to transaction request.
ArrayList<ItemDetails> itemDetailsList = new ArrayList<>();
itemDetailsList.add(itemDetails1);
itemDetailsList.add(itemdetails2);

// Set item details into the transaction request.
transactionRequest.setItemDetails(itemDetailsList);

📘

  • This goes with the assumption that you have created transactionRequest object using required parameters.
  • ITEM_NAME maximum character length is 50.

Set Transaction Request into SDK Instance


After creating transaction request with optional fields above, you must set it into SDK instance.


Set Transaction Request into SDK Instance

TransactionRequest on revamp is included in the startPayment Constructor
MidtransSDK.getInstance().setTransactionRequest(transactionRequest);

Start payment method screen


Default mode for Android SDK is showing payment method screen.
This screen will show all of your available payment methods.

You can enable/disable payment methods via Snap Preferences in MAP.


val itemDetails = listof(ItemDetails("Test01", 50000.00, 1, "lalalala"))

UiKitApi.getDefaultInstance().startPaymentUiFlow(
    this@MainActivity, // activity
    launcher, //ActivityResultLauncher 
    SnapTransactionDetail(UUID.randomUUID().toString(), 50000.00, "IDR"), // Transaction Details 
    CustomerDetails("budi-6789", "Budi", "Utomo", "[email protected]", "0213213123", null, null), // Customer Details
    itemDetails, // Item Details
    CreditCard(false, null, false, null, null, null, null, null, null, null, null), // Credit Card
    "customerIdentifier", // User Id
    PaymentCallback("mysamplesdk://midtrans"), // UobEzpayCallback
    GopayPaymentCallback("mysamplesdk://midtrans"), // GopayCallback
    PaymentCallback("mysamplesdk://midtrans"), // ShopeepayCallback
    Expiry(getFormattedTime(System.currentTimeMillis()), Expiry.UNIT_HOUR, 5), // expiry (null: default expiry time)
    PaymentMethod.CREDIT_CARD, // Direct Payment Method Type
    listOf(PaymentType.CREDIT_CARD, PaymentType.GOPAY, PaymentType.SHOPEEPAY, PaymentType.UOB_EZPAY), // Enabled Payment (null: enabled all available payment)
    BankTransferRequest(vaNumber = "1234567890"), // Permata Custom VA (null: default va)
    BankTransferRequest(vaNumber = "12345"), // BCA Custom VA (null: default va)
    BankTransferRequest(vaNumber = "12345"), // BNI Custom VA (null: default va)
    BankTransferRequest(vaNumber = "12345"), // BRI Custom VA (null: default va)
    "Cash1", // Custom Field 1
    "Debit2", // Custom Field 2
    "Credit3"  // Custom Field 3
)
MidtransSDK.getInstance().startPaymentUiFlow(ACTIVITY_CONTEXT);

Acquiring Bank


We provide acquiring bank option that can be used to make payment using credit card :

  • bca (channel: MIGS)
  • bri (channel: MIGS)
  • maybank (channel: MIGS)
  • bni
  • mandiri
  • cimb
  • danamon
  • mega

If you are using bca, bri, or maybank as your acquiring bank (MIGS channel), you have to define its channel explicitly.


val creditCardOptions = CreditCard(
    false, // Save Card, // Set to true if you want to save card to Snap
    null, // TokenId
    Authentication.AUTH_3DS, // Authentications
    CreditCard.MIGS, // Channel, Set MIGS channel (ONLY for BCA, BRI and Maybank Acquiring bank)
    BankType.BRI, // Bank, Set bank name when using MIGS channel. for example bank BRI.
    null, // Saved Tokens
    null, // Whitelist Bins
    null, // Blacklist Bins
    null, // Installment
    null, // Type
)
CreditCard creditCardOptions = new CreditCard();
//...
// Set bank name when using MIGS channel. for example bank BRI
creditCardOptions.setBank(BankType.BRI);
// Set MIGS channel (ONLY for BCA, BRI and Maybank Acquiring bank)
creditCardOptions.setChannel(CreditCard.MIGS);
//...



Transaction Finished Callback


In order to get the Transaction Result, you can subscribe for a Transaction Finished Callback by overriding onTransactionFinished method. The method will provide TransactionResult object which has several states.

When response is not null:

  • TransactionResult.STATUS_SUCCESS
  • TransactionResult.STATUS_PENDING
  • TransactionResult.STATUS_FAILED

When transaction is canceled, it can be checked with result.isTransactionCanceled()

When response is null:

  • TransactionResult.STATUS_INVALID

//In revamp we use launcher instead of callback, the transaction result will send to the launcher.

val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result?.resultCode == RESULT_OK) {
        result.data?.let {
            val transactionResult = it.getParcelableExtra<TransactionResult>(UiKitConstants.KEY_TRANSACTION_RESULT)
            Toast.makeText(this,"${transactionResult?.transactionId}", Toast.LENGTH_LONG).show()
        }
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (resultCode == RESULT_OK) {
        val transactionResult = data?.getParcelableExtra<TransactionResult>(
            UiKitConstants.KEY_TRANSACTION_RESULT
        )
        if (transactionResult != null) {
            when (transactionResult.status) {
                STATUS_SUCCESS -> {
                    Toast.makeText(this, "Transaction Finished. ID: " + transactionResult.transactionId, Toast.LENGTH_LONG).show()
                }
                STATUS_PENDING -> {
                    Toast.makeText(this, "Transaction Pending. ID: " + transactionResult.transactionId, Toast.LENGTH_LONG).show()
                }
                STATUS_FAILED -> {
                    Toast.makeText(this, "Transaction Failed. ID: " + transactionResult.transactionId, Toast.LENGTH_LONG).show()
                }
                STATUS_CANCELED -> {
                    Toast.makeText(this, "Transaction Cancelled", Toast.LENGTH_LONG).show()
                }
                STATUS_INVALID -> {
                    Toast.makeText(this, "Transaction Invalid. ID: " + transactionResult.transactionId, Toast.LENGTH_LONG).show()
                }
                else -> {
                    Toast.makeText(this, "Transaction ID: " + transactionResult.transactionId + ". Message: " + transactionResult.status, Toast.LENGTH_LONG).show()
                }
            }
        } else {
            Toast.makeText(this, "Transaction Invalid", Toast.LENGTH_LONG).show()
        }
    }
    super.onActivityResult(requestCode, resultCode, data)
}
@Override
  public void onTransactionFinished(TransactionResult result) {
    if (result.getResponse() != null) {
        switch (result.getStatus()) {
          case TransactionResult.STATUS_SUCCESS:
          	Toast.makeText(this, "Transaction Finished. ID: " + result.getResponse().getTransactionId(), Toast.LENGTH_LONG).show();
          break;
          case TransactionResult.STATUS_PENDING:
          	Toast.makeText(this, "Transaction Pending. ID: " + result.getResponse().getTransactionId(), Toast.LENGTH_LONG).show();
          break;
          case TransactionResult.STATUS_FAILED:
          	Toast.makeText(this, "Transaction Failed. ID: " + result.getResponse().getTransactionId() + ". Message: " + result.getResponse().getStatusMessage(), Toast.LENGTH_LONG).show();
          break;
        }
        result.getResponse().getValidationMessages();
      } else if (result.isTransactionCanceled()) {
      	Toast.makeText(this, "Transaction Canceled", Toast.LENGTH_LONG).show();
      } else {
        if (result.getStatus().equalsIgnoreCase(TransactionResult.STATUS_INVALID)) {
        	Toast.makeText(this, "Transaction Invalid", Toast.LENGTH_LONG).show();
        } else {
        	Toast.makeText(this, "Transaction Finished with failure.", Toast.LENGTH_LONG).show();
        }
    }
  }