NAV
Mobile SDK

Getting Started

Midtrans mobile SDK enable merchants to accept online payments natively in their mobile apps. We provide the drop-in User interface for making transactions on all the payment types supported by Midtrans. Watch the video for the default SDK example.

There are four parties involved in the payment process for making a payment:

  1. Merchant Server: The merchant backend implementation
  2. Customers
  3. Midtrans Backend (Payment Processor)
  4. Midtrans Mobile SDK

Transaction flow

Transaction Flow Figure

  1. Checkout: Customer clicks the Checkout button on the Host application and the app makes a request to the Merchant Server
  2. Token request: Merchant Server makes a request to Veritrans server with Order Information.
  3. Token response: Midtrans responds with a valid transaction token to Merchant server
  4. Token response: Merchant server forwards the token to the Mobile SDK
  5. Get transaction options: Mobile SDK requests payment/merchant information based on the token
  6. Transaction options response: Mobile SDK renders the payment Options and payment information to make the payment
  7. Pay: Customers selects the payment method and the payment details and clicks “Pay”
  8. Charge: Mobile SDK sends the Charge request to the Veritrans Backend for payment Processing.
  9. Charge response: Mobile SDK receives the response from the Veritrans Backend and triggers the handler on Mobile App with success/failure/pending status
  10. Charge notification: Midtrans Backend sends a notification to the Merchant backend confirming the completion of transaction.

Supported Payment Methods

  1. Credit/Debit Cards - Support for making payments via credit cards and or debit cards using our two-clicks feature. We support Visa, Mastercard, American Express and JCB
  2. Mandiri ClickPay
  3. CIMB Clicks
  4. ePay BRI
  5. Indosat Dompetku
  6. LINE Pay e-cash / mandiri e-cash
  7. Bank Transfer - Support payment using Permata Virtual Account and BCA Virtual Account.
  8. Mandiri Bill Payment
  9. Indomaret - Payment via convenience Stores
  10. BCA Klikpay
  11. KlikBCA
  12. Kioson
  13. Gift Card Indonesia

Security Aspects

Following are configurable parameters of SDK that can be used while performing transaction -

  1. Merchant server Endpoint / Base URL : URL of server to which transaction data will be sent. This will also be referred to as a merchant server.
  2. Transaction details - contains payment information like amount, order Id, payment method etc.
  3. Midtrans Client Key - token that specified by merchant server to enable the transaction using credit card. Available on the MAP

Prerequisites

  1. Create a merchant account in MAP
  2. In MAP, setup your merchant accounts settings, in particular Notification URL.
  3. Setup your merchant server. A server side implementation is required for midtrans mobile SDK to work. You can check the server implementation reference, and walk through the API’s that you may need to implement on your backend server.
  4. Minimum requirements: AndroidSDK: Android 4.0 Ice Cream Sandwich API Level 14 iOS SDK: iOS 7 and Xcode 8.0

Merchant Server Implementation

SDK Changes

There are some changes required on merchant server to make use latest SDK.

Merchants need to implement the following web services for SDK to work correctly. Note all the below accept and return Content-Type JSON

Mandatory

Create Token (Checkout) : This API proxies the request to Snap Backend. This process generates the token necessary for the secure communication between Mobile SDK and Midtrans.

Endpoint: POST on /charge

  • Add header in the request.
    • Authorization: Basic Base64(SERVER_KEY:)
  • Request will be sent to checkout / create transaction endpoint at Snap Backend.
  • Note the above request does not go to api.midtrans.com but to app.midtrans.com
    • Sandbox Endpoint: https://app.sandbox.midtrans.com/snap/v1/transactions
    • Production Endpoint: https://app.midtrans.com/snap/v1/transactions

Optional

We also additionally call a few endpoints if 1-Click or 2-Clicks is enabled :

The UserId refers to a generated UUID to associate card collection to each unique user. The mobile SDK generates this UUID during the initialization.

Store Credit Card Token

Endpoint: POST on /users/<userid>/tokens

Request Body

[
    {
        "status_code": "200",
        "cardhash": "481111-1114",
        "token_id": "481111ROMUdhBGMQhjVtEPNcsGee1114"
    },
    {
            "status_code": "200",
        "cardhash": "481111-1114",
        "token_id": "481111ROMUdhBGMQhjVtEPNcsGee1114"
    }
]

Response Code : 200 Response Body

Card is saved

List Credit Cards

Endpoint: GET on /users/<userid>/tokens

Request Body

None

Response Body

[
    {
        "token_id": "481111ROMUdhBGMQhjVtEPNcsGee1114",
        "cardhash": "481111-1114"
    },
    {
        "token_id": "481111ROMUdhBGMQhjVtEPNcsGee1114",
        "cardhash": "481111-1114"
    }
]

Android SDK

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

Latest Version

Download CircleCI

Latest Released version logs on Github release page.

Installation

Midtrans Bintray repository

repositories {
    jcenter()
        // Add the midtrans repository into the list of repositories
        maven { url "http://dl.bintray.com/pt-midtrans/maven" }
    }

Add SDK installation following into your build.gradle

You need to add Midtrans SDK inside your app’s module build.gradle.

SDK Sandbox Dependencies

dependencies {
    // For using the Midtrans Sandbox
    compile 'com.midtrans:uikit:$VERSION-SANDBOX'

SDK Production Dependencies

    // For using the Midtrans Production
    compile 'com.midtrans:uikit:$VERSION'
}

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

Midtrans SDK Initialization

SdkUIFlowBuilder.init(CONTEXT, CLIENT_KEY, BASE_URL, new TransactionFinishedCallback() {
            @Override
           public void onTransactionFinished(TransactionResult result) {
               // Handle finished transaction here.
           }
        })
        .buildSDK();

Note:

Differentiate Sandbox and Production in one app (Optional)

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

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 {
  ...
  sandboxCompile 'com.midtrans:uikit:$VERSION-SANDBOX'
  productionCompile 'com.midtrans:uikit:$VERSION'
  ...
}

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

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

SdkUIFlowBuilder.init(CONTEXT, BuildConfig.CLIENT_KEY, BuildConfig.BASE_URL, new TransactionFinishedCallback() {
            @Override
           public void onTransactionFinished(TransactionResult result) {
               // Handle finished transaction here.
           }
        })
        .buildSDK();

Adding external card scanner (Optional)

We provide a plugin to integrate card.io to allow customers to read/scan the credit card/debit card information using the mobile phone camera.

You can add external card scanner using ScanCardLibrary implementation by midtrans scan card library into your app’s dependencies in build.gradle.

Scan card SDK Dependencies

   //..other dependencies
   compile ('com.midtrans:scancard:$VERSION'){
      exclude module: 'uikit'
   }

Then, when initializing the SDK you can setExternalScanner(new ScanCard()) on SdkUIFlowBuilder

initialize SDK with ScanCard library

SdkUIFlowBuilder.init(...)
        // initialization for using external scancard
        .setExternalScanner(new ScanCard())
        .buildSDK();

Prepare Transaction Details

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

Create Transaction Request object

TransactionRequest transactionRequest = new TransactionRequest(TRANSACTION_ID, TOTAL_AMOUNT);

Item Details

Item details is 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

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);

Note:

Bill Info

Bill Info is optional for Mandiri Bill payment only.

BillInfoModel class holds information about billing information that will be shown in billing details.

Bill Info object

BillInfoModel billInfoModel = new BillInfoModel(BILL_INFO_KEY, BILL_INFO_VALUE);
// Set the bill info on transaction details
transactionRequest.setBillInfoModel(billInfoModel);

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

MidtransSDK.getInstance().setTransactionRequest(transactionRequest);

Starting Payment

Starting Payment

CreditCard creditCardOptions = new CreditCard();
// Set to true if you want to save card to Snap
creditCardOptions.setSaveCard(false);
// Set to true to save card token as `one click` token
creditCardOptions.setSecure(false);
// Set acquiring bank (Optional)
creditCardOptions.setBank(BankType.BANK_NAME);
// Set MIGS channel (ONLY for BCA and Maybank Acquiring bank)
creditCardOptions.setChannel(CreditCard.MIGS);
// Set Credit Card Options
transactionRequest.setCreditCard(creditCardOptions);
// Set transaction request into SDK instance
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.

Start payment method select screen

MidtransSDK.getInstance().startPaymentUiFlow(ACTIVITY_CONTEXT);

Direct payment screen

Users can directly go to payment screen and skip the default payment method screen.

Note: Please make sure the payment method is activated via Setting -> Snap Preferences in MAP.

Start Direct Payment Screen

we provide a method API to make direct payment for all payment methods on android sdk java startPaymentUiFlow(CONTEXT, PAYMENT_METHOD) example : Credit card payment

MidtransSDK.getInstance().startPaymentUiFlow(MainActivity.this, PaymentMethod.CREDIT_CARD);

For other payment methods you just need to change the parameter of payment method.

Payment Result

TransactionResult is wrapper for UI flow finished transaction object. It contains:

Here are the steps:

Additional Payment Features

Credit card payment on this SDK can be customized to save customer credit card details so user can use it on their next transactions.

Two Clicks Payment

Two clicks feature allows you to capture customer’s card number, expiry date, email and phone number as a TWO_CLICKS_TOKEN. For successive payments by the same customer the TWO_CLICKS_TOKEN can be utilized to pre-fill the details. Customer just needs to fill out the cvv number to finish the payment.

You need to setup this configuration to enable the two clicks mode.

Two clicks payment configuration

CreditCard creditCardOptions = new CreditCard();
// Set to true if you want to save card as two click payment
creditCardOptions.setSaveCard(true);
// Set secure option to enable or disable 3DS secure
creditCardOptions.setSecure(false);
// Set Credit Card Options
transactionRequest.setCreditCard(creditCardOptions);
// Set transaction request into SDK instance
MidtransSDK.getInstance().setTransactionRequest(transactionRequest);

To support two clicks configuration, merchant can use both default token storage on Midtrans backend or use their server to store their customer credentials.

Using Default Token Storage

By default this SDK will use Midtrans token storage to save customer credential so you don’t need to setup anything on your backend.

Store Token on Merchant Server

Please take a look at this guide to see save card feature implementation in your own server.

Then you need to configure SDK to disable the built-in token storage.

Disable built-in token storage

SdkUIFlowBuilder.init(CONTEXT, CLIENT_KEY, BASE_URL, CALLBACK)
                    // disable built in token storage
                    .useBuiltInTokenStorage(false)
                    .buildSDK();

One Click Payment

In addition to two clicks feature, SNAP also supports one click transaction which will also capture card cvv. With this, customer can directly proceed to charge without input any information.

To ease card saving process, SNAP provides card token storage feature. So, merchants don’t have to store and manage credit card token by themselves. Merchants can easily integrate credit card token storage feature to SNAP by providing unique user_id that associate with customer account on merchant’s system, in addition to enabling credit_card.save_card flag.

SNAP will then decide to store credit card token as one click token based on two criteria:

For one click payment, you can only use the built token storage as credentials storage option.

One click payment configuration

CreditCard creditCardOptions = new CreditCard();
// Set to true if you want to save card as One Clcik
creditCardOptions.setSaveCard(true);
// Set to true to save card token as `one click` token
creditCardOptions.setSecure(true);
// Set Credit Card Options
transactionRequest.setCreditCard(creditCardOptions);
// Set transaction request into SDK instance
MidtransSDK.getInstance().setTransactionRequest(transactionRequest);

Custom Expiry

There is a feature on mobile SDK to enable custom transaction lifetime. To use this feature you need to add an ExpiryModel object into TransactionRequest.

Custom Expiry

// set expiry time
ExpiryModel expiryModel = new ExpiryModel();

// set start time
long timeInMili = System.currentTimeMillis();
// format the time
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("Asia/Jakarta"));
// format the time as a string
String nowAsISO = df.format(new Date(time));
// set the formatted time to expiry model
expiryModel.setStartTime(Utils.getFormattedTime();
expiryModel.setDuration(1);
// set time unit
expiryModel.setUnit(ExpiryModel.UNIT_MINUTE);
//set expiry time object to transaction request
transactionRequest.setExpiry(expiryModel);
Parameter Description
start_time
String(255) (optional) Timestamp in yyyy-MM-dd HH:mm:ss Z format. If not specified, transaction time will be used as start time (when customer charge)
duration
Integer (required for expiry) Expiry duration
unit
String (required for expiry) Expiry unit. Options: day, hour, minute (plural term also accepted)

Custom Field

Custom field consists of custom_field1, custom_field2 and custom_field3.

These 3 fields will be brought at payment so it will be available at MAP and HTTP notification sent to merchant.

Set up custom field

TransactionRequest transactionRequest = MidtransSDK.getInstance().getTransactionRequest();
transactionRequest.setCustomField1(CUSTOM_FIELD_1);
transactionRequest.setCustomField2(CUSTOM_FIELD_2);
transactionRequest.setCustomField3(CUSTOM_FIELD_3);
MidtransSDK.getInstance().setTransactionRequest(transactionRequest);

Pre Authorization

Pre Authorization is a feature to set credit card transaction type into authorize.

If the transaction type is authorize then merchant need to capture the payment in MAP.

To use this feature you need to add a settings into credit card options in transaction request.

Set up authorize transaction

CreditCard creditCard = new CreditCard();
creditCard.setType(CardTokenRequest.TYPE_AUTHORIZE);

// Set into transaction Request
TransactionRequest transactionRequest = MidtransSDK.getInstance().getTransactionRequest();
transactionRequest.setCreditCard(creditCard);

// Set into SDK instance
MidtransSDK.getInstance().setTransactionRequest(transactionRequest());

Custom VA Number

Mobile SDK Provides a feature that allows to customize VA Number for BCA Bank transfer and Permata Bank Transfer payment methods. The Custom VA number must consist of numbers. To use this feature on Android SDK, you need to set your custom VA number to TransactionRequest object.

Note - Custom VA Number for Permata Bank Transfer must be 10 digits

Custom VA Number Permata Bank

// ....

TransactionRequest transactionRequest = MidtransSDK.getInstance().getTransactionRequest();
// custom va number for Permata Bank Transfer must be 10 digits
String PERMATA_VA_NUMBER = "1234512345";
// Set into transaction Request
transactionRequest.setPermataVa(
        new BankTransferRequestModel(PERMATA_VA_NUMBER);
// ...

);

Custom VA Number BCA Bank

// ....

TransactionRequest transactionRequest = MidtransSDK.getInstance().getTransactionRequest();
// custom va number
String BCA_VA_NUMBER = "1234512345";
// Set into transaction Request
transactionRequest.setBcaVa(
        new BankTransferRequestModel(BCA_VA_NUMBER);
);
// ...

);

UI Customization

Custom Fonts

To apply Custom fonts, you can use this code.

Custom Fonts

MidtransSDK midtransSDK = MidtransSDK.getInstance();
midtransSDK.setDefaultText("open_sans_regular.ttf");
midtransSDK.setSemiBoldText("open_sans_semibold.ttf");
midtransSDK.setBoldText("open_sans_bold.ttf");

Note: open_sans_regular.ttf, open_sans_semibold.ttf, open_sans_bold.ttf is path of the custom font on the assets directory.

Custom Themes

By default, SDK will use color settings provided in Snap Preferences in MAP.

To set custom theme in this SDK you just need to provide 3 colors:

Create Custom Color Theme Object

// Create Custom Color Theme
String examplePrimary = "#ffffff";
String examplePrimaryDark = "#ffffff";
String exampleSecondary = "#ffffff";
CustomColorTheme colorTheme = new CustomColorTheme(examplePrimary, examplePrimaryDark, exampleSecondary);

Set Theme on Builder

SdkUIFlowBuilder.init(this, BuildConfig.CLIENT_KEY, BuildConfig.BASE_URL, this)
                    .setColorTheme(colorTheme)
                    .build();

Set Theme on Initialized SDK

// Set on Midtrans SDK
MidtransSDK midtransSDK = MidtransSDK.getInstance();
midtransSDK.setColorTheme(colorTheme)

Skip Customer Details Screen (Optional)

On the first SDK usage, user needs to fill customer details required to make payment.

You can skip this screen if you want by following this guide.

Skip Customer Details

// Set user details
UserDetail userDetail = new UserDetail();
userDetail.setUserFullName(FULL_NAME);
userDetail.setEmail(EMAIL);
userDetail.setPhoneNumber(PHONE_NUMBER);
userDetail.setUserId(USER_ID);

// Initiate address list
ArrayList<UserAddress> userAddresses = new ArrayList<>();

// Initiate and add shipping address
UserAddress shippingUserAddress = new UserAddress();
shippingUserAddress.setAddress(shippingAddress);
shippingUserAddress.setCity(shippingCity);
shippingUserAddress.setCountry(shippingCountry);
shippingUserAddress.setZipcode(shippingZipcode);
shippingUserAddress.setAddressType(Constants.ADDRESS_TYPE_SHIPPING);
userAddresses.add(shippingUserAddress);

// Initiate and add billing address
UserAddress billingUserAddress = new UserAddress();
billingUserAddress.setAddress(billingAddress);
billingUserAddress.setCity(billingCity);
billingUserAddress.setCountry(country);
billingUserAddress.setZipcode(zipcode);
billingUserAddress.setAddressType(Constants.ADDRESS_TYPE_BILLING);
userAddresses.add(billingUserAddress);

// if shipping address is same billing address
// you can user type Constants.ADDRESS_TYPE_BOTH
// NOTE: if you use this, skip initiate shipping and billing address above
UserAddress userAddress = new UserAddress();
userAddress.setAddress(billingAddress);
userAddress.setCity(billingCity);
userAddress.setCountry(country);
userAddress.setZipcode(zipcode);
userAddress.setAddressType(Constants.ADDRESS_TYPE_BOTH);
userAddresses.add(userAddress);

// Set user address to user detail object
userDetail.setUserAddresses(userAddresses);

// Save the user detail. It will skip the user detail screen
LocalDataHandler.saveObject("user_details", userDetail);

Note:

UIKitCustomSetting

We provide UIKitCustomSetting to handle more customizable UI in our SDK.

Skip Payment Status

You can skip payment status provided by Midtrans SDK if you want to show your own status page.

Skip Payment Status

// Init custom settings
UIKitCustomSetting uisetting = new UIKitCustomSetting();
uisetting.setShowPaymentStatus(true);
MidtransSDK.getInstance().setUIKitCustomSetting(uiKitCustomSetting);

Set Default save card options to true

In credit card payment page, there is a checkbox to save card and it’s not checked by default. You can make this checkbox checked by default by using this settings.

Set default save card options to true

// Init custom settings
UIKitCustomSetting uisetting = new UIKitCustomSetting();
uiKitCustomSetting.setSaveCardChecked(true);
MidtransSDK.getInstance().setUIKitCustomSetting(uiKitCustomSetting);

Enable Auto Read OTP

There is an option to enable auto read OTP for credit card payment. You can enable this option by using following settings.

Enable Auto Read SMS OTP

// Init custom settings
UIKitCustomSetting uisetting = new UIKitCustomSetting();
// enable auto read SMS
uiKitCustomSetting.setEnableAutoReadSms(true);
// set custom setting to SDK
MidtransSDK.getInstance().setUIKitCustomSetting(uiKitCustomSetting);

iOS SDK

Latest Version

MidtransKit

Latest released version logs on Github release page.

Integration

Prequisite

Please install Cocoapods version 1.0.0. You can find the installation guide here

Instalation

Instalation - Podfile

def shared_pods
    pod 'MidtransCoreKit'
    pod 'MidtransKit'
end

target 'MyBeautifulApp' do
    shared_pods
end

Installation - install command

pod install --verbose

Integration

Integration

//AppDelegate.m
#import <MidtransKit/MidtransKit.h>

[CONFIG setClientKey:@"VT-CLIENT-sandbox-client-key"
         environment:MidtransServerEnvironmentSandbox
   merchantServerURL:@"https://merchant-url-sandbox.com"];

Once you have completed installation of MidtransKit, configure it with your clientKey, merchant server URL and server environment in your AppDelegate.h

Making Transactions

Generate TransactionTokenResponse object

Generate TransactionTokenResponse

//ViewController.m
MidtransItemDetail *itemDetail =
[[MidtransItemDetail alloc] initWithItemID:@"item_id"
                                      name:@"item_name"
                                     price:item_price
                                  quantity:item_quantity];

MidtransCustomerDetails *customerDetail =
[[MidtransCustomerDetails alloc] initWithFirstName:@"user_firstname"
                                          lastName:@"user_lastname"
                                             email:@"user_email"
                                             phone:@"user_phone"
                                   shippingAddress:ship_address
                                    billingAddress:bill_address];

MidtransTransactionDetails *transactionDetail =
[[MidtransTransactionDetails alloc] initWithOrderID:@"order_id"
                                     andGrossAmount:items_gross_amount];

[[MidtransMerchantClient shared]
 requestTransactionTokenWithTransactionDetails:transactionDetail
 itemDetails:self.itemDetails
 customerDetails:customerDetail
 completion:^(MidtransTransactionTokenResponse *token, NSError *error)
 {
     if (token) {

     }
     else {

     }
 }];

To create this object, you need to prepare required objects like item object etc.

Present the MidtransUIPaymentViewController

Present payment page

MidtransUIPaymentViewController *vc = [[MidtransUIPaymentViewController alloc] initWithToken:token];
[self presentViewController:vc animated:YES completion:nil];

We provide you a MidtransUIPaymentViewController to handle all the payment. Use the generated TransactionTokenResponse as required parameter.

Get Notified

Conform with MidtransUIPaymentViewControllerDelegate

//ViewController.m

#import <MidtransKit/MidtransKit.h>

@interface ViewController () <MidtransUIPaymentViewControllerDelegate>
//other code

SDK will give callback/ delegate transaction response to host app. To be able to do so, please follow these steps:

Set the delegate

//ViewController.m

MidtransUIPaymentViewController *vc = [[MidtransUIPaymentViewController alloc] initWithToken:token];
//set the delegate
vc.paymentDelegate = self;

Implement the functions of delegate

//ViewController.m

#pragma mark - MidtransUIPaymentViewControllerDelegate

- (void)paymentViewController:(MidtransUIPaymentViewController *)viewController paymentSuccess:(MidtransTransactionResult *)result {
    NSLog(@"success: %@", result);
}

- (void)paymentViewController:(MidtransUIPaymentViewController *)viewController paymentFailed:(NSError *)error {
    [self showAlertError:error];
}

- (void)paymentViewController:(MidtransUIPaymentViewController *)viewController paymentPending:(MidtransTransactionResult *)result {
    NSLog(@"pending: %@", result);
}

- (void)paymentViewController_paymentCanceled:(MidtransUIPaymentViewController *)viewController {
    NSLog(@"canceled");
}

Customisation

Theme Customisation

UI Customisation

MidtransUIFontSource fontSource =
[[MidtransUIFontSource alloc] initWithFontNameBold:font_name
                                   fontNameRegular:font_name
                                     fontNameLight:font_name];
[MidtransUIThemeManager applyCustomThemeColor:themeColor
                                    themeFont:fontSource];

We’ve created MidtransUIThemeManager to configure the theme color and font of the veritrans payment UI.

Class MidtransUIThemeManager needs UIColor object so you need to convert your HEX or RGB to UIColor, here is some nice tool to generate UIColor code.

Note: If you didn’t configure this MidtransUIThemeManager, your theme color will follow SNAP color configuration on MAP -> SNAP settings preference.

Skipping Transaction Result Page

Skip UI result page

UICONFIG.hideStatusPage = YES;

If you don’t want to show our payment result page because you prefer to use your own design, we give you the flexibility to hide it.

Set Save Checkbox Checked By Default

Save Card By Default

CC_CONFIG.setDefaultCreditSaveCardEnabled = YES;

You can set the save card checkbox on Credit Card payment page to be checked by default.

Enable Card Scanner (using Card.IO library)

Podfile for CardIO

platform :ios, '7.0'

def shared_pods
    pod 'MidtransKit'
    pod 'MidtransKit/CardIO'
end

target 'MyBeautifulApp' do
    shared_pods
end

We provide a plugin to integrate card.io to allow customers to read/scan the credit card/debit card information using the mobile phone camera. If you want to support this external card scanner, follow these steps

Update Cocoapods

pod update --verbose

Directly Call CreditCard Page

MidtransUIPaymentViewController *paymentVC =
[[MidtransUIPaymentViewController alloc] initWithToken:token
                                     andPaymentFeature:MidtransPaymentFeatureCreditCard];

We provide the flexibility to call directly to a specific payment method. If you want to show only credit card payment page you follow the example code.

Additional Payment Features

One-Click

Configuration for 1-Click

CC_CONFIG.paymentType = MTCreditCardPaymentTypeOneclick;
CC_CONFIG.saveCardEnabled = YES;

//1-click need token storage enabled
CC_CONFIG.tokenStorageEnabled = YES;

//1-click need 3ds enabled
CC_CONFIG.secure3DEnabled = YES;

Please see the configuration on the example code, then implement it before presenting the payment page

Two-Clicks

Configuration for 2-Clicks

CC_CONFIG.paymentType = MTCreditCardPaymentTypeTwoclick;
CC_CONFIG.saveCardEnabled = YES;

Please see the configuration on the example code, then implement it before presenting the payment page

Custom Acquiring Bank

Config Acquiring Bank

/* available acquiring banks
MTAcquiringBankBCA,
MTAcquiringBankBRI,
MTAcquiringBankCIMB,
MTAcquiringBankMandiri,
MTAcquiringBankBNI,
MTAcquiringBankMaybank
*/

CC_CONFIG.acquiringBank = MTAcquiringBankMaybank; //ex. maybank

We’ve already supported these banks

Custom Field

Custom field consists of custom_field1, custom_field2 and custom_field3.

These 3 fields will be brought at payment so it will be available at MAP and HTTP notification sent to merchant.

Set custom field

    NSMutableArray *arrayOfCustomField = [NSMutableArray new];
    [arrayOfCustomField addObject:@{MIDTRANS_CUSTOMFIELD_1:@"custom134"}];
    [arrayOfCustomField addObject:@{MIDTRANS_CUSTOMFIELD_2:@"custom3332"}];
    [arrayOfCustomField addObject:@{MIDTRANS_CUSTOMFIELD_3:@"custom3333"}];

an then

 [[MidtransMerchantClient shared] requestTransactionTokenWithTransactionDetails:self.transactionDetails
                                                                       itemDetails:self.itemDetails
                                                                   customerDetails:self.customerDetails
                                                                       customField:arrayOfCustomField
                                                             transactionExpireTime:nil
                                                                        completion:^(MidtransTransactionTokenResponse * _Nullable token, NSError * _Nullable error)
     {
         ...
}];

Pre Authorization

Set up authorize transaction

CC_CONFIG.preauthEnabled = YES;

Pre Authorization is a feature to set credit card transaction type into authorize.

If the transaction type is authorize then merchant need to capture the payment in MAP.

To use this feature you need to set preauthEnabled on credit card configuration to YES

Custom VA Number

Set up custom va number

CONFIG.customBCAVANumber = @"your va string";
CONFIG.customPermataVANumber = = @"your va string";

Custom VA number is Midtrans feeature to determina your va number instead of generated VA number from Midtrans, currently still only support BCA and PERMATA bank VA

Testing Credentials

Here is a list of dummy transaction credentials that can be used for transaction in the Sandbox Environment.

Credit Card

General Testing Card Number

Normal Transaction

VISA Description
No Authentication
Merchant disables 3DS
Accept Transaction: 4011 1111 1111 1112
Challenge by FDS Transaction: 4111 1111 1111 1111
Denied by FDS Transaction: 4211 1111 1111 1110
Denied by Bank Transaction: 4311 1111 1111 1119
MASTERCARD Description
No Authentication
Merchant disables 3DS
Accept Transaction: 5481 1611 1111 1081
Challenge by FDS Transaction: 5110 1111 1111 1119
Denied by FDS Transaction: 5210 1111 1111 1118
Denied by Bank Transaction: 5310 1111 1111 1117

3D Secure Transaction

VISA Description
Full Authentication
Cardholder is 3DS ready
Accept Transaction: 4811 1111 1111 1114
Denied by Bank Transaction: 4911 1111 1111 1113
Attempted Authentication
Cardholder is not enrolled for 3DS
Accept Transaction: 4411 1111 1111 1118
Challenge by FDS Transaction: 4511 1111 1111 1117
Denied by FDS Transaction: 4611 1111 1111 1116
Denied by Bank Transaction: 4711 1111 1111 1115
MASTERCARD Description
Full Authentication
Cardholder is 3DS ready
Accept Transaction: 5211 1111 1111 1117
Denied by Bank Transaction: 5111 1111 1111 1118
Attempted Authentication
Cardholder is not enrolled for 3DS
Accept Transaction: 5410 1111 1111 1116
Challenge by FDS Transaction: 5510 1111 1111 1115
Denied by FDS Transaction: 5411 1111 1111 1115
Denied by Bank Transaction: 5511 1111 1111 1114

Bank-Specific Testing Card

Accepted 3D Secure Card

Bank Card Number
Mandiri
Full Authentication 4617 0069 5974 6656
5573 3810 7219 6900
Attempted Authentication 4617 0017 4194 2101
5573 3819 9982 5417
CIMB
Full Authentication 4599 2078 8712 2414
5481 1698 1883 2479
Attempted Authentication 4599 2039 9705 2898
5481 1671 2103 2563
BNI
Full Authentication 4105 0586 8948 1467
5264 2210 3887 4659
Attempted Authentication 4105 0525 4151 2148
5264 2249 7176 1016
BCA
Full Authentication 4773 7760 5705 1650
5229 9031 3685 3172
Attempted Authentication 4773 7738 1098 1190
5229 9073 6430 3610
BRI
Full Authentication 4365 0263 3573 7199
5520 0298 7089 9100
Attempted Authentication 4365 0278 6723 2690
5520 0254 8646 8439
Maybank
Full Authentication 4055 7720 2603 6004
5520 0867 5210 2334
Attempted Authentication 4055 7713 3514 4012
5520 0867 7490 8452

Accepted Normal Card

Bank Card Number
Mandiri 4617 0030 8177 8145
5573 3899 1384 3648
Mandiri Debit 4097 6658 2970 8136
CIMB 4599 2043 5516 9092
5481 1620 3830 7406
BNI 4105 0568 6475 0672
5264 2282 3919 2765
BNI Private Label 1946 4159 8148 7684
BCA 4773 7781 0290 6680
5229 9028 2076 4661
BRI 4365 0299 9362 0368
5520 0219 0920 3008
Maybank 4055 7796 2846 0474
5520 0883 1465 3770

Denied Card

Bank Card Number
Mandiri 4617 0085 6083 1760
5573 3840 4322 4447
Mandiri Debit 4097 6676 7217 8631
CIMB 4599 2060 0973 3090
5481 1691 9178 2739
BNI 4105 0541 4854 1363
5264 2235 3013 171
BNI Private Label 1946 4102 7193 1269
BCA 4773 7752 0201 1809
5229 9034 0542 3830
BRI 4365 0299 9362 0368
5520 0219 0920 3008
Maybank 4055 7796 2846 0474
5520 0883 1465 3770

Expiry Date and CVV

Input Value
Expiry Month 01
Expiry Year 2020
CVV 123

Bank Transfer

Payment Methods Description
Permata Virtual Account midtrans will generate a dummy 16 digits Permata Virtual Account Number. To perform a test transaction, use the Permata Virtual Account Simulator
BCA Virtual Account midtrans will generate a dummy 11 digits BCA Virtual Account Number. To perform a test transaction, use the BCA Virtual Account Simulator
Mandiri Bill Payment midtrans will generate a 6 digits Payment Code to complete payment via Mandiri e-channel (Internet Banking, SMS Banking, Mandiri ATM). To perform a test transaction, use the Mandiri Bill Payment Simulator

Direct Debit

Payment Methods Description
Mandiri Clickpay Card Number: 4111 1111 1111 1111
Accept Token: 000000
Deny Token: 111111
CIMB Clicks midtrans will redirect CIMB Clicks test transaction to a payment simulator.
Success Transaction: testuser00
Failure Transaction: testuser01
ePay BRI midtrans will redirect ePay BRI test transaction to a payment simulator.
Success Transaction: testuser00
Failure Transaction: testuser03
BCA Klikpay midtrans will redirect BCA Klikpay test transaction to a payment simulator.
Klik BCA midtrans will register user id filled in KlikBCA input. To perform a test transaction, use the KlikBca Simulator

e-Wallet

Payment Methods Description
Telkomsel cash Accept Customer: 0811111111
Deny Customer: 0822222222
XL Tunai midtrans will generate a dummy XL Tunai Merchant Code and Order ID. To perform a test transaction, use the XL Tunai Simulator
Indosat Dompetku Accept number: 08123456789
Deny number: other than 08123456789
LINE Pay e-cash / mandiri e-cash Accept number: 0987654321
PIN: 12345
OTP: 12123434

Convenience Store

Payment Methods Description
Indomaret midtrans will generate a dummy Indomaret Payment Code. To perform a test transaction, use the Indomaret Simulator
Kioson midtrans will generate a dummy Kioson Payment Code. To perform a test transaction, use the Kioson Simulator

Status Codes

Goal: Understand all status codes used by API. For more inquiries, please contact us at support@midtrans.com or visit our support web page.

Status Codes used by midtrans API are categorized into 2xx, 3xx, 4xx dan 5xx.

Code 2xx

Status Description
200 Credit Card: Success. Request is successful, and transaction is successful (authorize, capture, settlement, cancel, get order, approve challenge transactions), accepted by midtrans and bank.
Other payment methods: Success. Transaction is successful/settlement.
201 Credit Card: Challenge. Transaction successfully sent to bank but the process has not been completed, need manual action from merchant to complete the transaction process. If the merchant does not perform any action until settlement time (H+1 16:00) midtrans will cancel the transaction.
Bank Transfer: Pending. Transaction successfully sent to bank but the process has not been completed by the customer. By default the transaction will expire within 24 hours.
CIMB Clicks: Pending. Transaction successfully sent to bank but the process has not been completed by the customer. By default the transaction will expire within 2 hours.
BRI ePay: Pending. Transaction successfully sent to bank but the process has not been completed by the customer. By default the transaction will expire within 2 hours.
Klik BCA: Pending. Transaction successfully sent to bank but the process has not been completed by the customer. By default the transaction will expire within 2 hours.
BCA Klikpay: Pending. Transaction successfully sent to bank but the process has not been completed by the customer. By default the transaction will expire within 2 hours.
Mandiri Bill Payment: Pending. Transaction successfully sent to bank but the process has not been completed by the customer. By default the transaction will expire within 2 hours.
XL Tunai: Pending. Transaction successfully sent to provider but the process has not been completed by the customer. By default the transaction will expire within 2 hours.
Indomaret: Pending. Transaction successfully sent to provider but the process has not been completed by the customer. By default the transaction will expire within 2 hours.
202 Credit Card: Denied. Transaction has been processed but is denied by payment provider or midtrans’ fraud detection system.
Other payment methods: Denied. Transaction has been processed but is denied by payment provider.

Code 3xx

Status Description
300 Move Permanently, current and all future requests should be directed to the new URL

Code 4xx

Status Description
400 Validation Error, merchant sent bad request data example; validation error, invalid transaction type, invalid credit card format, etc.
401 Access denied due to unauthorized transaction, please check client key or server key
402 Merchant doesn’t have access for this payment type
403 The requested resource is only capable of generating content not acceptable according to the accepting headers that sent in the request
404 The requested resource is not found
405 HTTP method is not allowed
406 Duplicate order ID. Order ID has already been utilized previously
407 Expired transaction
408 Merchant sent the wrong data type
409 Merchant has sent too many transactions for the same card number
410 Merchant account is deactivated. Please contact midtrans support
411 Token id is missing, invalid, or timed out
412 Merchant cannot modify status of the transaction
413 The request cannot be processed due to malformed syntax in the request body

Code 5xx

Status Description
500 Internal Server Error
501 The feature has not finished yet, it will be available soon
502 Internal Server Error: Bank Connection Problem
503 Internal Server Error
504 Internal Server Error: Fraud detection is unavailable

Going Live With Mobile SDK

Android

To use production version in Android, please use production version of the library and also production client key you can get from MAP.

Latest Corekit Production version

compile 'com.midtrans:corekit:1.4.1'

Latest Uikit Production version

compile 'com.midtrans:uikit:1.4.1'

iOS

To use production version in iOS, please use production environment when initializing SDK and also production client key you can get from MAP.

Production setup in Objective-C

[CONFIG setClientKey:@"merchant clientkey"
                 environment:MidtransServerEnvironmentProduction
           merchantServerURL:@"merchant server production URL"];

Production setup in Swift

MidtransConfig.shared().setClientKey("merchant clientkey", environment: .production, merchantServerURL: "merchant server URL")

Merchant Server

To use production version of Snap, please use production endpoint of Snap and also production server key you can get from MAP.

Production Endpoint: https://app.midtrans.com/snap/v1/

Frequently Asked Questions

What is a merchant server?

Veritrans Mobile SDK requires merchant to have a server-side implementation to store SERVER_KEY and make charge request. As an implementation reference, please take a look at this wiki.

What is MERCHANT_BASE_URL?

It is the URL of your merchant server (backend).

Why did I get Mixpanel token error?

This error will not happen if you use the build that we have provided on bintray. If for some reason you don’t want to use the build that we have provided, you need to add your own mixpanel token by signing up to mixpanel first.

Why did I get this error “Access denied due to unauthorized transaction, please check client or server key”?

Please check whether you have used the correct client key and server key. The keys should also match the environment such that sandbox keys are used for sandbox environment, and production keys for production. If the keys are already correct but you still get the same error, make sure you have put the correct merchant server URL (MERCHANT_BASE_URL).

Features

Installment

Prerequisites

There are few things that needs to be checked before installment can be used.

  1. MID for installment must be activated (please contact support@midtrans.com to activate MID)
  2. Setup merchant server to handle checkout request. (Please see this wiki)

Provide Installment Data

In order to use installment in mobile SDK, merchant server must intercept mobile SDK’s request and add installment data that sent to Midtrans backend (snap).

Example of installment data.

"installment": {
      "required": false,
      "terms": {
        "bni": [3, 6, 12],
        "mandiri": [3, 6, 12],
        "cimb": [3],
        "bca": [3, 6, 12],
        "offline": [6, 12]
      }
    }

To filter only selected card that can use the installment, whitelist_bins must be added too.

Example of whitelist bins

"whitelist_bins": [
      "48111111",
      "41111111"
    ],

Mobile SDK and Midtrans backend (snap) will check if the card number first n digits number contains one of bins available in whitelist_bins.


This installment object and whitelist bins need to be added at credit_card object on mobile SDK’s request. So full example of installment data sent to Snap was like this.

Complete JSON request

{
    "transaction_details": {
        "order_id": "ORDER-ID",
        "gross_amount": 10000
    },
    "credit_card": {
        "secure": true,
        "channel": "migs",
        "bank": "bca",
        "installment": {
            "required": false,
            "terms": {
                "bni": [
                    3,
                    6,
                    12
                ],
                "mandiri": [
                    3,
                    6,
                    12
                ],
                "cimb": [
                    3
                ],
                "bca": [
                    3,
                    6,
                    12
                ],
                "offline": [
                    6,
                    12
                ]
            }
        },
        "whitelist_bins": [
            "48111111",
            "41111111"
        ]
    },
    "item_details": [
        {
            "id": "ITEM1",
            "price": 10000,
            "quantity": 1,
            "name": "Midtrans Bear"
        }
    ],
    "customer_details": {
        "first_name": "TEST",
        "last_name": "MIDTRANSER",
        "email": "test@midtrans.com",
        "phone": "+628123456",
        "billing_address": {
            "first_name": "TEST",
            "last_name": "MIDTRANSER",
            "email": "test@midtrans.com",
            "phone": "081 2233 44-55",
            "address": "Sudirman",
            "city": "Jakarta",
            "postal_code": "12190",
            "country_code": "IDN"
        },
        "shipping_address": {
            "first_name": "TEST",
            "last_name": "MIDTRANSER",
            "email": "test@midtrans.com",
            "phone": "0 8128-75 7-9338",
            "address": "Sudirman",
            "city": "Jakarta",
            "postal_code": "12190",
            "country_code": "IDN"
        }
    }
}

Bin Promo

To use bin promo or whitelist bin feature, merchant server must intercept mobile SDK’s request and add list of whitelist bin into request.

Whitelist bin object will be like this:

"whitelist_bins": [
      "48111111",
      "41111111"
    ]

This object needs to be added into credit_card field.

So complete bin promo request will be like this:

{
    "transaction_details": {
        "order_id": "ORDER-ID",
        "gross_amount": 10000
    },
    "credit_card": {
        "secure": true,
        "whitelist_bins": [
            "48111111",
            "41111111"
        ]
    },
    "item_details": [
        {
            "id": "ITEM1",
            "price": 10000,
            "quantity": 1,
            "name": "Midtrans Bear"
        }
    ],
    "customer_details": {
        "first_name": "TEST",
        "last_name": "MIDTRANSER",
        "email": "test@midtrans.com",
        "phone": "+628123456",
        "billing_address": {
            "first_name": "TEST",
            "last_name": "MIDTRANSER",
            "email": "test@midtrans.com",
            "phone": "081 2233 44-55",
            "address": "Sudirman",
            "city": "Jakarta",
            "postal_code": "12190",
            "country_code": "IDN"
        },
        "shipping_address": {
            "first_name": "TEST",
            "last_name": "MIDTRANSER",
            "email": "test@midtrans.com",
            "phone": "0 8128-75 7-9338",
            "address": "Sudirman",
            "city": "Jakarta",
            "postal_code": "12190",
            "country_code": "IDN"
        }
    }
}

Handle Async Payment

There are some async payment supported by Midtrans:

If you’re using payment methods from above list, you will not get the latest transaction status after doing the charge using the SDK. SDK only returns the pending status when doing the charge to Midtrans Payment API.

Midtrans will update the transaction status after they receive notification from bank when the transaction is really completed.

There are two ways to know the latest transaction status:

Handling HTTP Notification

In order to increase security aspect, there are several ways to ensure notification received from Midtrans.

Handle HTTP Notification (Using Veritrans PHP)

<?php

require_once('Veritrans.php');
Veritrans_Config::$isProduction = false;
Veritrans_Config::$serverKey = '<your serverkey>';
$notif = new Veritrans_Notification();

$transaction = $notif->transaction_status;
$type = $notif->payment_type;
$order_id = $notif->order_id;
$fraud = $notif->fraud_status;

if ($transaction == 'capture') {
  // For credit card transaction, we need to check whether transaction is challenge by FDS or not
  if ($type == 'credit_card'){
    if($fraud == 'challenge'){
      // TODO set payment status in merchant's database to 'Challenge by FDS'
      // TODO merchant should decide whether this transaction is authorized or not in MAP
      echo "Transaction order_id: " . $order_id ." is challenged by FDS";
      }
      else {
      // TODO set payment status in merchant's database to 'Success'
      echo "Transaction order_id: " . $order_id ." successfully captured using " . $type;
      }
    }
  }
else if ($transaction == 'settlement'){
  // TODO set payment status in merchant's database to 'Settlement'
  echo "Transaction order_id: " . $order_id ." successfully transfered using " . $type;
  }
  else if($transaction == 'pending'){
  // TODO set payment status in merchant's database to 'Pending'
  echo "Waiting customer to finish transaction order_id: " . $order_id . " using " . $type;
  }
  else if ($transaction == 'deny') {
  // TODO set payment status in merchant's database to 'Denied'
  echo "Payment using " . $type . " for transaction order_id: " . $order_id . " is denied.";
  }
  else if ($transaction == 'expire') {
  // TODO set payment status in merchant's database to 'expire'
  echo "Payment using " . $type . " for transaction order_id: " . $order_id . " is expired.";
  }
  else if ($transaction == 'cancel') {
  // TODO set payment status in merchant's database to 'Denied'
  echo "Payment using " . $type . " for transaction order_id: " . $order_id . " is canceled.";
}
?>

Challenge Response

An additional mechanism we provide to verify the content and the origin of the notification is to challenge. This can be achieved by calling the get status API. The response is the same as the notification status.

Challenge Response

Signature Key

We add signature key information in our notification. The purpose of this signature key is to validate whether the notification is originated from Midtrans or not. Should the notification is not genuine, merchants can disregard the notification. Please find on the side, the logic of the signature key and the sample code to generate signature key.

Signature Key Logic

SHA512(order_id + status_code + gross_amount + serverkey)

Sample code generate signature key

<?php
$orderId = "1111";
$statusCode = "200";
$grossAmount = "100000.00";
$serverKey = "askvnoibnosifnboseofinbofinfgbiufglnbfg";
$input = $orderId.$statusCode.$grossAmount.$serverKey;
$signature = openssl_digest($input, 'sha512');
echo "INPUT: " , $input."<br/>";
echo "SIGNATURE: " , $signature;
?>

Best Practice to Handle notification

Following are the standard types of notifications. Note different types of notifications can be added in addition to the below. Also new fields may be added to the existing notification, please confirm with the latest documentation for the exact fields.

Get Transaction Status

Please refer to this docs.