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 payment types supported by Midtrans. Watch the video for the default SDK example.
There are four parties involved in the payment process:
- Merchant Server: The merchant backend implementation
- Customers
- Midtrans Backend (Payment Processor)
- Midtrans Mobile SDK
Transaction flow
- Checkout: Customer clicks the Checkout button on the Host application and the app makes a request to the Merchant Server
- Token request: Merchant Server makes a request to Midtrans server with Order Information.
- Token response: Midtrans responds with a valid transaction token to Merchant server
- Token response: Merchant server forwards the token to the Mobile SDK
- Get transaction options: Mobile SDK requests payment/merchant information based on the token
- Transaction options response: Mobile SDK renders the payment options and payment information to make the payment
- Pay: Customers selects the payment method and the payment details and clicks “Pay”
- Charge: Mobile SDK sends the Charge request to the Midtrans Backend for payment Processing.
- Charge response: Mobile SDK receives the response from Midtrans Backend and triggers the handler on Mobile App with success/failure/pending status
- Charge notification: Midtrans Backend sends a notification to the Merchant backend confirming the completion of transaction.
Security Aspects
- There are 2 separate keys CLIENT_KEY and SERVER_KEY (available on MAP)
- CLIENT_KEY is used for tokenizing the credit card. It can only be used from the Client(mobile device)
- SERVER_KEY is used for acquiring the token from the Midtrans server. It is not to be used from the device, all API requests that use the SERVER_KEY need to be made from the Merchant Server.
- We use strong encryption for making connections to Merchant server, please make sure it has valid https Certificate.
The following are configurable parameters of SDK that can be used while performing transaction -
- 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.
- Transaction details - contains payment information like amount, order Id, payment method etc.
- Midtrans Client Key - token that is specified by merchant server to enable the transaction using
credit card
. Available on the MAP
Prerequisites
- Create a merchant account in MAP
- In MAP, setup your merchant account settings, in particular the Notification URL.
- 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 for implementation on your backend server.
- Minimum requirements:
- AndroidSDK: Android 4.0 Ice Cream Sandwich API Level 14
- iOS SDK: iOS 7 and Xcode 8.0
Merchant Server Implementation
Sample Project to implement Merchant Server sample merchant server.
SDK Changes
There are some changes required on merchant server to make use of the latest SDK.
1.0.x
SDK needs merchant server to redirect the request to/pay
in Snap endpoint.1.1.x
SDK needs merchant server to redirect the request to/transactions
in Snap endpoint.
Merchants need to implement the following web services for SDK to work correctly. Note the below points, accept and return Content-Type JSON
- Content-Type: application/json
- Accept: application/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 toapp.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 :
- To Store Credit Card Tokens: We explicitly invoke
POST
on/users/<userid>/tokens
to allow the backend to store generated credit card token after a successful Credit card charge. - To Retrieve Credit card Tokens : We explicitly invoke
GET
GET /users/<user_id>/tokens
to retrieve saved card list.
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"
}
]
Supported Payment Methods
Credit/Debit Cards
Support for making payments via credit cards and or debit cards. We support Visa
, Mastercard
, American Express
and JCB
. We also support additional features like two clicks, one click, installment, and pre-authorization.
Bank Transfer
Support payment using BCA Virtual Account, Permata Virtual Account, BNI Virtual Account, BRI Virtual Account and Mandiri Bill Payment.
BCA Virtual Account
BCA Virtual Account is a virtual payment method offered by Bank BCA. Users can pay using their BCA Bank account. Payment can be made through all of Bank BCA’s channels (KlikBCA, m-BCA, and ATM).
Permata Virtual Account
Permata Virtual Account is a virtual payment method facilitated by Bank Permata. Users can pay using any Indonesian Bank account. Payment can be made through ATM Bersama, Prima, or Alto ATM networks.
BNI Virtual Account
BNI Virtual Account is a virtual payment method facilitated by Bank BNI. Users can pay using any Indonesian Bank account. Payment can be made through ATM Bersama, Prima, or Alto ATM networks.
BRI Virtual Account
BRI Virtual Account is a virtual payment method facilitated by Bank BRI. Users can pay using any Indonesian Bank account. Payment can be made through all of Bank BRI’s channels (Internet Banking, Mobile Banking, and ATM).
Mandiri Bill Payment
Mandiri Bill is a virtual payment method offered by Bank Mandiri. Users can pay using their Mandiri bank account. Payment can be made through all of Bank Mandiri’s channels (Internet Banking, SMS Banking & ATM).
GoPay
GoPay is an e-Wallet payment method by Gojek. Users will pay using the Gojek app.
The user flow varies when using a tablet compared to a smartphone.
When users make a purchase using GoPay on a tablet
- Users see a QR code on their tablet.
- Users open the Gojek app on their phone.
- Users tap the Scan QR function on the Gojek app.
Note : The Scan QR button won’t appear if your GoPay balance is less than Rp10,000. - Users point their camera to the QR Code.
- Users check their payment details on the Gojek app and then tap Pay.
- The transaction is complete and the users’ GoPay balance is deducted.
When users make a purchase on their smartphone
- Users are automatically redirected to the Gojek app when making purchases on their smartphone.
- Users finish the payment on the Gojek app.
- The transaction is complete and their GoPay balance is deducted.
To enable GoPay in Midtrans Mobile SDK, all you need to do is enable GoPay payment method on your Merchant Dashboard (MAP). If you want to use it explicitly by applying direct payment, please take a look at this sample code.
ShopeePay
ShopeePay is an e-Wallet payment method by Shopee. Users will pay using the Shopee app.
Similar to GoPay, The user flow varies when using a tablet compared to a smartphone.
When users make a purchase using ShopeePay on a tablet
- Users see a QR code (QRIS) on their tablet.
- Users open the Shopee app on their phone.
- Users tap the Scan QR function on the Shopee app.
- Users point their camera to the QR Code.
- Users check their payment details on the Shopee app and then tap Pay.
- The transaction is complete and the users’ ShopeePay balance is deducted.
When users make a purchase on their smartphone
- Users are automatically redirected to the Shopee app when making purchases on their smartphone.
- Users finish the payment on the Shopee app.
- The transaction is complete and their ShopeePay balance is deducted.
To enable ShopeePay in Midtrans Mobile SDK, all you need to do is enable Shopee payment method on your Merchant Dashboard (MAP).
KlikBCA
Internet banking direct payment method by Bank BCA. User will be redirected to the KlikBCA website for payment.
BCA Klikpay
Internet banking direct payment method by Bank BCA. User will be redirected to the BCA KlikPay website for payment.
CIMB Clicks
Internet banking direct payment method by Bank CIMB. User will be redirected to the CIMB Clicks website for payment.
Danamon Online Banking
Internet banking direct payment method by Bank Danamon. User will be redirected to the Danamon Online Banking website for payment.
ePay BRI
Internet banking direct payment method by Bank BRI. User will be redirected to the BRI ePay website for payment.
LINE Pay / Mandiri e-cash
E-Wallet payment method by Bank Mandiri. User will pay through their LINE PAY / Mandiri e-cash account.
Indomaret - Payment via convenience Stores
Convenience store payment method by Indomaret. User will pay through the physical Indomaret convenience store.
Akulaku
Akulaku is payment using Akulaku. It uses Webview to handle the payment.
Alfamart - Payment via convenience Stores
Convenience store payment method by Alfamart. User will pay through the physical Alfamart convenience store.
Transaction status
For the synchronous payment methods, the latest status will be provided on the response of payment step.
And for asynchronous payment methods, Your merchant server needs to implement Midtrans /status
endpoint
in here for your mobile application to work correctly since Midtrans SDK does not have your server_key
. Note the below points, accept and return Content-Type JSON
Headers :
- Content-Type: application/json
- Accept: application/json
- Authorization : Basic Base64(SERVER_KEY:)
Request
GET
MIDTRANS_API_BASE_URL/v2/{order_id & transaction_id}/status
Android SDK
This SDK provides an UI to take required information from user to execute transaction.
Sample Project to implement SDK sample project.
Latest Version
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.
Installation
Add SDK installation following into your build.gradle
Midtrans Bintray repository
repositories {
jcenter()
// Add the midtrans repository into the list of repositories
maven { url "http://dl.bintray.com/pt-midtrans/maven" }
maven { url "https://jitpack.io" }
}
Sample SDK Sandbox Dependencies
dependencies {
// For using the Midtrans Sandbox
implementation 'com.midtrans:uikit:1.26.0-SANDBOX' // change the number to the latest version
}
Sample SDK Production Dependencies
dependencies {
// For using the Midtrans Production
implementation 'com.midtrans:uikit:1.26.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
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:1.26.0-SANDBOX' // change the version to latest one
productionImplementation 'com.midtrans:uikit:1.26.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
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.
Let Us Know Your Thoughts
Is our wizard (or setup assistant, using Devsupport AI) helpful? Do you have any feedback? Please share your feedback here.
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);
Adding Customer Detail (Optional)
Create CustomerDetails object
CustomerDetails customerDetails = new CustomerDetails();
customerDetails.setCustomerIdentifier("budi-6789");
customerDetails.setPhone("08123456789");
customerDetails.setFirstName("Budi");
customerDetails.setLastName("Utomo");
customerDetails.setEmail("budi@utomo.com");
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
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:
- This goes with the assumption that you have created
transactionRequest
object using required parameters. ITEM_NAME
maximum character length is 50.
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 bank name when using MIGS channel
creditCardOptions.setBank(BankType.BANK_NAME);
// Set MIGS channel (ONLY for BCA, BRI 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);
Start payment by using snap token
We provide SDK method to allow you to make payment by using snap token
without initialize transaction request first. You just need to pass snap token as argument of startPaymentUiFlow
method
Start payment by using snap token
MidtransSDK.getInstance().startPaymentUiFlow(ACTIVITY_CONTEXT, SNAP_TOKEN);
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.
Acquiring Bank Configuration
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
Transaction Finish Callback
@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();
}
}
}
iOS SDK
Latest Version
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
- Navigate to your project’s root directory and run
pod init
to create a Podfile. - Open up the Podfile and add MidtransKit to your project’s target.
Installation - install command
pod install --verbose
- Save the file and run
pod install
to install MidtransKit. - Cocoapods will download and install MidtransKit and also create a .xcworkspace project.
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
Important: if you use Swift as your project language, you will need to add -ObjC
to your Xcode project.
Navigate to your .xcodeproj
file in Xcode, choose you app main target in Targets
, and in Build Settings
tab, search for Other Linker Flags
, double click and add -ObjC
.
Show Customer Detail Form
CC_CONFIG.showFormCredentialsUser = YES;
If you want to show Customer Details form at Credit Card payment page, you can set showFormCredentialsUser
to YES
.
Starting Payment
How to start payment by using snap token on iOS
From iOS SDK v1.12.0, we provide SDK method to allow you to make payment by using snap token
without initialize transaction request first. You just need to pass snap token as argument of requestTransacationWithCurrentToken:
method
Charging using SNAP token
[[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];
}];
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 your view controller to conform with
MidtransUIPaymentViewControllerDelegate
Set the delegate
//ViewController.m
MidtransUIPaymentViewController *vc = [[MidtransUIPaymentViewController alloc] initWithToken:token];
//set the delegate
vc.paymentDelegate = self;
- Set the delegate of
MidtransUIPaymentViewController
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");
}
//This delegate methods is added on ios sdk v1.16.4 to handle the new3ds flow
- (void)paymentViewController:(MidtransUIPaymentViewController *)viewController paymentDeny:(MidtransTransactionResult *)result{
NSLog(@"Deny %@", result);
}
- Implement the
MidtransUIPaymentViewControllerDelegate
functions
Custom Acquiring Bank
Config Acquiring Bank
/* available acquiring banks
MTAcquiringBankBCA,
MTAcquiringBankBRI,
MTAcquiringBankCIMB,
MTAcquiringBankMandiri,
MTAcquiringBankBNI,
MTAcquiringBankMaybank
*/
CC_CONFIG.acquiringBank = MTAcquiringBankMaybank; //ex. maybank
We already support these banks
- BCA
- BRI
- CIMB
- Mandiri
- BNI
- Maybank
Features
Two Clicks Payment
Two clicks feature allows you to capture the 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. The customer just needs to fill out the cvv number to finish the payment. Please see the configuration on the example code to enable the two clicks mode.
CreditCard creditCardOptions = new CreditCard();i
// 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.setAuthentication(Authentication.AUTH_3DS;
// Set Credit Card Options
transactionRequest.setCreditCard(creditCardOptions);
// Set transaction request into SDK instance
MidtransSDK.getInstance().setTransactionRequest(transactionRequest);
// You can set Authentication.AUTH_3DS / Authentication.AUTH_RBA / Authentication.AUTH_NONE
CC_CONFIG.paymentType = MTCreditCardPaymentTypeTwoclick;
CC_CONFIG.saveCardEnabled = YES;
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.
SdkUIFlowBuilder.init(CONTEXT, CLIENT_KEY, BASE_URL, CALLBACK)
// disable built in token storage
.useBuiltInTokenStorage(false)
.buildSDK();
CC_CONFIG.paymentType = MTCreditCardPaymentTypeTwoclick;
One Click Payment
In addition to two clicks feature, SNAP also supports one click transaction which will also capture the card’s cvv. With this, customers can directly proceed to pay without input any information.
One click payment configuration
CreditCard creditCardOptions = new CreditCard();
// Set to true if you want to save card as one click
creditCardOptions.setSaveCard(true);
// Set to true to save card token as `one click` token
// Set Credit Card Options
transactionRequest.setCreditCard(creditCardOptions);
// Set transaction request into SDK instance
MidtransSDK.getInstance().setTransactionRequest(transactionRequest);
CC_CONFIG.paymentType = MTCreditCardPaymentTypeOneclick;
CC_CONFIG.saveCardEnabled = YES;
//1-click need 3ds enabled
CC_CONFIG.authenticationType = MTAuthenticationType3DS;
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 associates with customers’ 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:
- Merchant has recurring MID enabled
- Initial transaction is 3DS-enabled
Installment
Prerequisites
There are few things that needs to be checked before installment can be used.
- MID for installment must be activated (please contact support@midtrans.com to activate MID)
- Setup merchant server to handle checkout request. (Please see this wiki)
Enable installment & add terms
Installment installment = new Installment();
Map<String, ArrayList<Integer>> bankTerms = new HashMap<>();
ArrayList<Integer> termBri = new ArrayList<>();
termBri.add(3);
termBri.add(6);
termBri.add(12);
//set bank and term
bankTerms.put("bri", termBri);
ArrayList<Integer> termOffline = new ArrayList<>();
termOffline.add(3);
termOffline.add(6);
termOffline.add(12);
//set bank and term
bankTerms.put("offline", termOffline);
installment.setTerms(bankTerms);
installment.setRequired(true);
// assume you already declare CreditCard() as creditCard
creditCard.setInstallment(installment);
// assume you already declare TransactionRequest() as transactionRequest then assign to TransactionRequest
transactionRequest.setCreditCard(creditCard)
NSDictionary *terms = @{@"offline": @[@3, @6, @12],
@"bni": @[@6, @12]
};
CC_CONFIG.predefinedInstallment = [MidtransPaymentRequestV2Installment modelWithTerms:terms isRequired:YES];
Setup the SDK
Before request token, enable installment and add your installment terms
required
–> the installment payment required.terms
-> array of available installment terms of supported bank.
Setup whitelist bins
// assume you already declare CreditCard() as creditCard
ArrayList<String> whiteList = new ArrayList<>(Arrays.asList("493496","451197","493497","493498"));
creditCard.setWhiteListBins(whiteList);
// assume you already declare TransactionRequest() as transactionRequest then assign to TransactionRequest
transactionRequest.setCreditCard(creditCard)
NSArray *whitelistBins = @[@"493496", @"451197", @"493497", @"493498"];
[[MidtransMerchantClient shared] requestTransactionTokenWithTransactionDetails:trx
itemDetails:<item details>
customerDetails:<customer details>
customField:<custom field>
binFilter:whitelistBins
blacklistBinFilter:<blacklist bins>
transactionExpireTime:<expire time>
completion:^(MidtransTransactionTokenResponse * _Nullable token, NSError * _Nullable error)
{
if (error) {
}
else {
}
}];
Optionally whitelist_bins
can be used to accept only card numbers within the specified BIN numbers. (whitelist_bins
is required for offline
installment type).
Mobile SDK and Midtrans backend (snap) will check if the card numbers’ first n
digit numbers contain one of bins available in whitelist_bins
.
This installment object and whitelist bins need to be added at credit_card
object when the server accepts the transaction request from mobile SDK. A full example of installment data sent to Snap is like this.
BNI Point
BNI Point is special feature for BNI Bank customers. This feature allows users to redeem their point to be applied into their credit card payments. In your app side, there’s no adjustment needed. To enabled this feature in mobile SDK you just need to contact our support team. Please have a look to the following BNI Point flow to know more about this feature.
Mandiri Fiestapoin
Mandiri Fiestapoin is special feature for Mandiri Bank customers. This feature allows users to redeem their Mandiri fiestapoin to be applied into their credit card payments. In your app side, there’s no adjustment needed. To enabled this feature in mobile SDK you just need to contact our support team.
Risk Based Authentication (RBA)
Set up RBA
CreditCard creditCard = new CreditCard();
// ....
// make set authentication to RBA
creditCard.setAuthentication(Authentication.AUTH_RBA);
// Set into transaction Request
TransactionRequest transactionRequest = MidtransSDK.getInstance().getTransactionRequest();
transactionRequest.setCreditCard(creditCard);
// You can set Authentication.AUTH_3DS / Authentication.AUTH_RBA / Authentication.AUTH_NONE
CC_CONFIG.authenticationType = MTAuthenticationTypeRBA;
RBA is a program from VISA for merchants to be able to route each of their transactions to use 3DS MID or non-3DS based on their risk level.
Under RBA program, VISA wish to help merchants to protect their transactions without sacrificing their conversion rate due to known issues in current 3DS (delayed/unsent OTP, connection, etc).
Example: Use 3D secure if customer is using US card and did more than 3 transactions in the last 1 hour. Use non 3D Secure if customer is using Indonesia card and amount is less than 100,000.
This feature can be activated by contacting our support team. Then you need to configure the SDK to use this feature.
Pre Authorization
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());
CC_CONFIG.preauthEnabled = YES;
Pre Authorization is a feature to set the credit card transaction type into authorize
.
If the transaction type is authorize
then the merchant needs to capture the payment in MAP.
To use this feature you need to add a settings into the credit card options in transaction request.
Direct payment screen
Start Direct Payment Screen
startPaymentUiFlow(CONTEXT, PAYMENT_METHOD)
// or run the SDK by using snap token
startPaymentUiFlow(CONTEXT, PAYMENT_METHOD, SNAP_TOKEN)
// example : credit card payment
MidtransSDK.getInstance().startPaymentUiFlow(MainActivity.this, PaymentMethod.CREDIT_CARD);
// example : credit card payment
MidtransUIPaymentViewController *paymentVC =
[[MidtransUIPaymentViewController alloc] initWithToken:token
andPaymentFeature:MidtransPaymentFeatureCreditCard];
Other PAYMENT_METHOD Possible Value
//bank transfer
PaymentMethod.BANK_TRANSFER
//bank transfer BCA
PaymentMethod.BANK_TRANSFER_BCA
//bank transfer Mandiri
PaymentMethod.BANK_TRANSFER_MANDIRI
//bank transfer Permata
PaymentMethod.BANK_TRANSFER_PERMATA
//bank transfer BNI
PaymentMethod.BANK_TRANSFER_BNI
//bank transfer other
PaymentMethod.BANK_TRANSFER_OTHER
//GO-PAY
PaymentMethod.GO_PAY
//BCA KlikPay
PaymentMethod.BCA_KLIKPAY
//KlikBCA
PaymentMethod.KLIKBCA
//Mandiri Clickpay
PaymentMethod.MANDIRI_CLICKPAY
//Mandiri e-cash / LINE Pay
PaymentMethod.MANDIRI_ECASH
//e-Pay BRI
PaymentMethod.EPAY_BRI
//CIMB Clicks
PaymentMethod.CIMB_CLICKS
//Indomaret
PaymentMethod.INDOMARET
//KIOSON
PaymentMethod.KIOSON
//GIFT CARD INDONESIA
PaymentMethod.GIFT_CARD_INDONESIA
//Indosat dompetku
PaymentMethod.INDOSAT_DOMPETKU
//Telkomsel cash
PaymentMethod.TELKOMSEL_CASH
//XL TUNAI
PaymentMethod.XL_TUNAI
//Danamon online
PaymentMethod.DANAMON_ONLINE
//Akulaku
PaymentMethod.AKULAKU
//Alfamart
PaymentMethod.ALFAMART
//ShopeePay
PaymentMethod.SHOPEEPAY
typedef NS_ENUM(NSInteger, MidtransPaymentFeature) {
MidtransPaymentFeatureNone,
MidtransPaymentFeatureCreditCard,
MidtransPaymentFeatureBankTransfer,///va
MidtransPaymentFeatureBankTransferBCAVA,
MidtransPaymentFeatureBankTransferMandiriVA,
MidtransPaymentFeatureBankTransferBNIVA,
MidtransPaymentFeatureBankTransferBRIVA,
MidtransPaymentFeatureBankTransferPermataVA,
MidtransPaymentFeatureBankTransferOtherVA,
MidtransPaymentFeatureKlikBCA,
MidtransPaymentFeatureIndomaret,
MidtransPaymentFeatureAlfamart,
MidtransPaymentFeatureCIMBClicks,
MidtransPaymentFeatureBCAKlikPay,
MidtransPaymentFeatureBRIEpay,
MidtransPaymentFeatureDanamonOnline,
MidtransPaymentFeatureAkulaku,
MidtransPaymentFeatureGOPAY,
MidtransPaymentFeatureShopeePay
};
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.
- For other payment methods you just need to change the parameter of payment method.
- For GO-PAY integration in iOS please see section
GO-PAY CONFIGURATION IOS
// -----------------------
// GO-PAY CONFIGURATION IOS
// -----------------------
<key>LSApplicationQueriesSchemes</key>
<array>
<string>gojek</string>
</array>
We provide a method API to make direct payment for all payment methods on Android and iOS SDK.
Gopay IOS Configuration
Gopay transaction is happened through the Gojek app. For IOS, In order to detect and open the Gojek app, it’s required to add the LSApplicationQueriesSchemes
key to your app’s Info.plist.
// Gopay ios config to detect and open gojek app
<key>LSApplicationQueriesSchemes</key>
<array>
<string>gojek</string>
</array>
Using Callback Deeplink
You can enable callback deeplink, which enable users to go back to the host app after completing gopay payment in Gojek app. You need to implement the deeplink callback by adding your app url schemes. There’re two ways to do this, You can either:
- Go to
Project Settings
->Info
, and add inside TheURL Types
section a new URL scheme. For example you can add something likemyApp
or any name you preferred. - Alternatively you can go to your
info.plist
file and paste this code, you can changemyApp
value to any name you preferred for your app.
// Add url scheme to your app
// You can replace myApp to your preferred app name.
// CAUTION: Don't ever use gojek as the name in your url scheme because it will interfere with the functionality
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myApp</string>
</array>
</dict>
</array>
CAUTION: Don’t ever use gojek
as the name in your url scheme because it will interfere with the functionality.
Afterwards, you need to configure it in the sdk based on your url scheme name.
//configure your url scheme to the sdk config
MidtransConfig.shared.callbackSchemeURL = @"myApp://";
Without callback deeplink
Alternatively if you want to check your transaction status manually, you can do it by calling this method:
// iOS without callback deeplink implementation
NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:MIDTRANS_CORE_CURRENT_TOKEN];
[[MidtransMerchantClient shared] performCheckStatusTransactionWithToken:token completion:^(MidtransTransactionResult * _Nullable result, NSError * _Nullable error) {
if (!error) {
if (result.statusCode == 200) {
//handle success
}
} else {
//handle error
}
}];
Gopay Android Configuration
If you use GO-PAY payment method, There are two ways to get the result of the transaction:
- First, the easy one is with callback deeplink (go back to host-app)
- Alternatively you can also do it without callback deeplink.
If you want to use callback deeplink to get the result from GO-JEK app, please set your deeplink on the TransactionRequest object that you’ve created, please refer to this link for deeplink implementation. If your app don’t use deeplink, you can skip this step and check your transaction manually.
For example if you set your deeplink like this demo:://midtrans
then GO-JEK app will return callback like this for success demo://midtrans?order_id=xxxx&result=success
and this for failure demo://midtrans?order_id=xxxx&result=failure
.
Note:
- Please make sure the payment method is activated via Setting -> Snap Preferences in MAP.
- Using deeplink only work with latest GO-JEK application.
- For more GO-PAY integration please refere to this link for Android.
Using callback deeplink
// Setup your Transaction Request here then set your GO-PAY deeplink.
// Assume you already make TransactionRequest object.
transactionRequest.setGopay(new Gopay("demo://midtrans"));
Without callback deeplink
// You don't need special setting for this implementation.
// For checking transaction status, you can call getTransactionStatus method for checking.
String snapToken = getMidtransSDK().readAuthenticationToken();
MidtransSDK.getInstance().getTransactionStatus(snapToken, new GetTransactionStatusCallback() {
@Override
public void onSuccess(TransactionStatusResponse response) {
// do action for response
}
@Override
public void onFailure(TransactionStatusResponse response, String reason) {
// do nothing
}
@Override
public void onError(Throwable error) {
// do action if error
}
});
ShopeePay Callback Deeplink
ShopeePay transaction is happened through the Shopee App. You must enable deeplink, which enable users to go back to the host app after completing ShopeePay payment in Shopee app.
1) For ios, to enable deeplink you need to setup the url scheme in your plist file. However if you already implement it for GoPay, then you don’t need to setup the url scheme again, you are already good to go. You just need to directly setup the ShopeePay callback url value on the SDK Config based on your url scheme name.
// Add url scheme to your app
// You can replace myApp to your preferred app name.
// If you already set this for GoPay in your app, then you don't need to do this again
// CAUTION: Don't ever use gojek as the name in your url scheme because it will interfere with the functionality
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myApp</string>
</array>
</dict>
</array>
//configure your url scheme to the sdk config
MidtransConfig.shared.shopeePayCallbackURL = @"myApp://";
2) For Android, please set your deeplink on the TransactionRequest object that you’ve created, please refer to this link for deeplink implementation.
For example if you set your deeplink like this demo:://midtrans
then Shopee app will return callback like this demo://midtrans
.
To get the transaction status, you can get from the SDK callback (Refer to Gopay Android Configuration)
//Add intent filters for incoming links
//If you already do this for GoPay, you don't need to set this again.
<activity android:name=".EntryActivity"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="midtrans"
android:scheme="demo" />
</intent-filter>
</activity>
// Setup your Transaction Request here then set your ShopeePay deeplink.
// Assume you already make TransactionRequest object.
transactionRequest.setShopeepay(new Shopeepay("demo://midtrans"));
Card Registration
Card Register Implementation
MidtransSDK.getInstance().UiCardRegistration(CONTEXT, new CardRegistrationCallback() {
@Override
public void onSuccess(CardRegistrationResponse response) {
String savedTokenId = response.getSavedTokenId();
String maskedCard = response.getMaskedCard();
}
@Override
public void onFailure(CardRegistrationResponse response, String reason) {
// Handle failure here
}
@Override
public void onError(Throwable error) {
// Handle error here
}
});
NSString *clientkey = @"your client key";
NSString *merchantServer = @"your merchant server url";
[[MidtransNetworkLogger shared] startLogging];
[CONFIG setClientKey:clientkey
environment:MidtransServerEnvironmentSandbox
merchantServerURL:merchantServer];
NSArray *data = [self.expiryDate.text componentsSeparatedByString:@"/"];
NSString *expMonth = [data[0] stringByReplacingOccurrencesOfString:@" " withString:@""];
NSString *expYear = [NSString stringWithFormat:@"%ld",[data[1] integerValue]+2000];
MidtransCreditCard *creditCard = [[MidtransCreditCard alloc] initWithNumber: [self.cardNumberTextFIeld.text stringByReplacingOccurrencesOfString:@" " withString:@""] expiryMonth:expMonth expiryYear:expYear cvv:self.cvv.text];
[[MidtransClient shared] registerCreditCard:creditCard completion:^(MidtransMaskedCreditCard * _Nullable maskedCreditCard, NSError * _Nullable error) {
if (!error) {
[self saveCreditCardObject:maskedCreditCard];
}
else {
}
}];
Card Registration is a feature to allow customers to save credit card token without doing transactions first. This feature is provided for merchants that will make API-to-API payments. To implement it, you just need to follow the sample code.
Notes:
- Card expiry consists of
expiryMonth
andexpiryYear
. Both areString
and should follow this format : 2 digit forexpiryMonth
(for example : “02”), and 4 digit forexpiryYear
(for example : “2020”). - CVV is
String
too, with number of digit between 3 or 4, based on card. Mastercard, Visa, or JCB usually has 3 digit CVV, while American Express has 4. - Number of digit for expiryMonth (example : it must be 2 digits) Reason : there is an error while merchant try to input 1 digit for this parameter, but there is no clue what’s gone wrong regarding the code.
- Number of digit for expiryYear (example : it must be 4 digits)
- Number of digit for cvv (example : it must be 3 digits)
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 Configuration
// 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);
MidtransTransactionExpire *expireTime = [[MidtransTransactionExpire alloc] initWithExpireTime:nil expireDuration:1 withUnitTime:MindtransTimeUnitTypeHour];
// and then
[[MidtransMerchantClient shared] requestTransactionTokenWithTransactionDetails:trx
itemDetails:@[itm]
customerDetails:cst
customField:arrayOfCustomField
binFilter:binFilter
blacklistBinFilter:blacklistBin
transactionExpireTime:expireTime
completion:^(MidtransTransactionTokenResponse * _Nullable token, NSError * _Nullable error)
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
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);
NSMutableArray *arrayOfCustomField = [NSMutableArray new];
[arrayOfCustomField addObject:@{MIDTRANS_CUSTOMFIELD_1:@"custom134"}];
[arrayOfCustomField addObject:@{MIDTRANS_CUSTOMFIELD_2:@"custom3332"}];
[arrayOfCustomField addObject:@{MIDTRANS_CUSTOMFIELD_3:@"custom3333"}];
// and then
[[MidtransMerchantClient shared] requestTransactionTokenWithTransactionDetails:self.transactionDetails
itemDetails:self.itemDetails
customerDetails:self.customerDetails
customField:arrayOfCustomField
transactionExpireTime:nil
completion:^(MidtransTransactionTokenResponse * _Nullable token, NSError * _Nullable error)
{
...
}];
These 3 fields will be brought at payment so it will be available at MAP and a HTTP notification will be sent to the merchant.
Custom VA Number
Set up Custom VA Number
// ....
// 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));
// ...
// ....
// Custom VA Number BNI Bank
TransactionRequest transactionRequest = MidtransSDK.getInstance().getTransactionRequest();
// custom va number
String BNI_VA_NUMBER = "1234512345";
// Set into transaction Request
transactionRequest.setBniVa(new BankTransferRequestModel(BNI_VA_NUMBER));
// ...
CONFIG.customBCAVANumber = @"your va string";
CONFIG.customPermataVANumber = = @"your va string";
Mobile SDK provides a feature that allows customized VA Number for the following payment methods - Permata VA (Bank Transfer) - BCA VA (Bank Transfer) - BNI VA (Bank Transfer)
Note - The Custom VA number must consist of numbers. - Custom VA Number for Permata Bank Transfer must be 10 digits
Other Bank ATM / VA Switcher
For bank transfers beside BCA, Mandiri, BNI, or Permata, Midtrans previously utilized Permata as VA processor. Recently, Midtrans adds support for BNI VA, giving the merchant flexibility to choose which one will be used for other bank transfer. The idea is when one of the processors (either BNI or Permata) is down, merchant can switches to other processor, preventing lose of the sales. In order to use this functionality, merchant should enable both BNI VA and Permata VA. The switch itself is located in Snap Preferences in MAP (Merchant Administrator Portal). In merchant app, there’s no adjustment needed. The changes will be valid for the next checkout.
Sub Company Code
Set up sub company code for BCA VA
// ....
// Transaction request
TransactionRequest transactionRequest = MidtransSDK.getInstance().getTransactionRequest();
// sub company code must be exactly 5 digits of number
String SUB_COMPANY_CODE_BCA = "12321";
// Create BcaBankTransferRequestModel object and then set the SUB_COMPANY_CODE_BCA
BcaBankTransferRequestModel bcaRequestModel = new BcaBankTransferRequestModel();
bcaRequestModel.setSubCompanyCode(SUB_COMPANY_CODE_BCA);
// Set into transaction Request
transactionRequest.setBcaVa(bcaRequestModel);
// sub company code must be exactly 5 digits of number ex:55555
CONFIG.customBCASubcompanyCode = @“55555”;
This feature allows you to pass sub company code in VA payment. The sub company code must be exactly 5 digits of number. This feature is only available on BCA VA payment method.
Custom Recipient
Set up Custom Recipient for Permata
// ....
// Custom Recipient Name for Permata Bank
TransactionRequest transactionRequest = MidtransSDK.getInstance().getTransactionRequest();
// custom recipient for Permata Bank Transfer must be 20 character at most and in uppercase
String PERMATA_RECIPIENT = "SUDARSONO";
// Create request model (you can optionally insert custom VA as method argument here)
PermataBankTransferRequestModel permataRequest = new PermataBankTransferRequestModel();
permataRequest.setRecipientName(PERMATA_RECIPIENT);
// Set into transaction Request
transactionRequest.setPermataVa(permataRequest);
Mobile SDK provides a feature that allows merchant to customize recipient name for Permata VA (Bank Transfer). The recipient name will be displayed in the ATM screen.
Note - The custom recipient name must consist of alphanumeric characters and space. No symbol allowed. - Custom recipient name for Permata Bank Transfer must be 20 characters at most, and in uppercase.
Custom Themes
Set up Custom Fonts & Theme Color
/**
* Android custom font
*/
MidtransSDK midtransSDK = MidtransSDK.getInstance();
midtransSDK.setDefaultText("open_sans_regular.ttf");
midtransSDK.setSemiBoldText("open_sans_semibold.ttf");
midtransSDK.setBoldText("open_sans_bold.ttf")
/**
* Android custom theme color
*/
// Create Custom Color Theme
String examplePrimary = "#ffffff";
String examplePrimaryDark = "#ffffff";
String exampleSecondary = "#ffffff";
CustomColorTheme colorTheme = new CustomColorTheme(examplePrimary, examplePrimaryDark, exampleSecondary);
// Set Theme color into SDK Builder
SdkUIFlowBuilder.init(this, BuildConfig.CLIENT_KEY, BuildConfig.BASE_URL, this)
.setColorTheme(colorTheme)
.build();
// or
// Set Theme color into Initialized SDK
MidtransSDK midtransSDK = MidtransSDK.getInstance();
midtransSDK.setColorTheme(colorTheme)
// Set Fonts & Theme color into Initialized SDK
MidtransUIFontSource fontSource =
[[MidtransUIFontSource alloc] initWithFontNameBold:font_name
fontNameRegular:font_name
fontNameLight:font_name];
[MidtransUIThemeManager applyCustomThemeColor:themeColor
themeFont:fontSource];
Mobile SDK provide Fonts
and Theme color
customization.
- Custom Fonts : to set your fonts to SDK you have to add the font to your project.
- Custom Theme Color : By default, SDK will use color settings provided in Snap Preferences in MAP. If you want to use your own custom theme color you need to define it in SDK.
Android Custom Themes
Android Custom Fonts
To use a custom font on Android SDK, you need to put your font files to assets directory of project and then just follow the sample code.
Notes:
- (Android)
open_sans_regular.ttf
,open_sans_semibold.ttf
,open_sans_bold.ttf
are path of the custom font on the assets directory.
Android Custom Theme color
To set custom theme in this SDK you just need to provide 3 colors:
- Primary: For top panels showing amount
- Primary Dark: For bordered button, link button
- Secondary: For text field.
iOS Custom Themes
We’ve created MidtransUIThemeManager
to configure the theme color and font of the Midtrans payment UI.
Class MidtransUIThemeManager
needs UIColor
object so you need to convert your HEX or RGB to UIColor
, here is a 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.
Uikit Custom Settings
We provide Settings to handle more customizable UI in our SDK.
Skip Payment Status
Skip Payment Status
// Init custom settings
UIKitCustomSetting uisetting = new UIKitCustomSetting();
uisetting.setShowPaymentStatus(false); // hide sdk payment status
MidtransSDK.getInstance().setUIKitCustomSetting(uiKitCustomSetting);
UICONFIG.hideStatusPage = YES;
You can skip payment status provided by Midtrans SDK if you want to show your own status page.
Set Default save card options to true
Set default save card options to true
// Init custom settings
UIKitCustomSetting uisetting = new UIKitCustomSetting();
uiKitCustomSetting.setSaveCardChecked(true);
MidtransSDK.getInstance().setUIKitCustomSetting(uiKitCustomSetting);
CC_CONFIG.setDefaultCreditSaveCardEnabled = YES;
In credit card payment page, there is a checkbox to save card and it is not checked by default. You can make this checkbox checked by default by using this settings.
Skip customer detail
Skip customer detail
UIKitCustomSetting setting = MidtransSDK.getInstance().getUIKitCustomSetting();
uiKitCustomSetting.setSkipCustomerDetailsPages(true);
MidtransSDK.getInstance().setUIKitCustomSetting(setting);
On the first SDK usage, user are required to fill in customer details to make a payment. This setting is only for Android SDK due to the iOS SDK not having built-in customer details pages. You can skip this screen if you want by using UIKitCustomSetting.
Add customer contact in credit card form
Add customer contact in credit card form
UIKitCustomSetting setting = MidtransSDK.getInstance().getUIKitCustomSetting();
uiKitCustomSetting.setShowEmailInCcForm(true);
MidtransSDK.getInstance().setUIKitCustomSetting(setting);
If you want to show additional fields for customer contact (phone number and / or email), you can use this option. SDK will automatically display additional fields. Please note that both fields are optional.
To use this feature, please make sure you have installed our latest SDK.
Enable Auto Read OTP (Android Only)
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);
There is an option to enable auto read OTP for credit card payments. You can enable this option by using the following settings.
Bin Promo (Bin Filter)
Whitelist bin object will be like this:
"whitelist_bins": [
"mandiri",
"41111111"
]
Blacklist bin object will be like this:
"blacklist_bins": [
"mandiri",
"41111111"
]
So complete bin promo request will be like this:
{
"transaction_details": {
"order_id": "ORDER-ID",
"gross_amount": 10000
},
"credit_card": {
"secure": true,
"whitelist_bins": [
"bni",
"459920"
],
"blacklist_bins": [
"bri",
"410505"
]
},
"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"
}
}
}
Credit card bins can be filtered by using whitelist_bins
or blacklist_bins
or both features. To use these features, merchant server must intercept mobile SDK’s request and add list of whitelist bin into request.
Note:
- This object needs to be added into
credit_card
object. - If set of whitelisted bins intersects with set of blacklisted bins, then:
- Everything in whitelisted bins that is not mentioned in blacklisted bins will be accepted.
- Everything else will be denied
Parameter | Description |
---|---|
whitelist_bins Array (optional) |
Allowed credit card BIN numbers. The bin value can be either a prefix (up to 8 digits) of card number or the name of a bank, in which case all the cards issued by that bank will be allowed. The supported bank names are bni bca mandiri cimb bri and maybank . Default: allow all cards |
blacklist_bins Array (optional) |
A list of credit card BIN numbers that cannot be used for the transaction. The bin value can be either a prefix (up to 8 digits) of card number or the name of a bank, in which case all the cards issued by that bank will be denied. The supported bank names are bni bca mandiri cimb bri and maybank . Default: allow all cards |
Testing Credentials
Here is a list of dummy transaction credentials that can be used for transactions 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 0286 6251 2583 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 0286 6251 2583 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 |
---|---|
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 |
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 |
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 the production version in Android, please use the production version of the library and also production client key
which you can get from MAP.
Latest Corekit Production version
implementation 'com.midtrans:corekit:1.21.2'
Latest Uikit Production version
implementation 'com.midtrans:uikit:1.21.2'
iOS
To use the production version in iOS, please use the production environment when initializing SDK and also production client key
which 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 the production version of Snap, please use the production endpoint of Snap and also production server key
which you can get from MAP.
Production Endpoint: https://app.midtrans.com/snap/v1/
Frequently Asked Questions
What is a merchant server?
Midtrans 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).
Why did I get response message “Token not found” when trying to do checkout?
Please make sure you have installed correct SDK and supplied corresponding credentials. In sandbox environment, please make sure that you use sandbox keys (client key and server key) and sandbox version of SDK (the name of SDK using postfix “-SANDBOX” eg: com.midtrans:uikit:1.16.0-SANDBOX).
Why did I get a blank screen when trying to do checkout?
First, please make sure you’ve already used our latest version of SDK (at least v1.15.3). If you still face this problem, please either do one of these two solutions : (1) supply user detail to SDK, or (2) use UIKitCustomSetting. Please refer to this guide on how to do one of them.
I got error when trying to do checkout.
First, please make sure you’ve already used our latest version of SDK. Then, please examine the error log captured in Logcat or other error reporting.
If the error looks like this :
E/AndroidRuntime: FATAL EXCEPTION: main java.lang.NoSuchMethodError: No virtual method load(Ljava/lang/Integer;)Lcom/bumptech/glide/DrawableTypeRequest; in class Lcom/bumptech/glide/RequestManager; or its super classes (declaration of ‘com.bumptech.glide.RequestManager’ appears in /data/app/id.packageaplikasi.app-1/base.apk:classes3.dex) |
---|
Then rest easy as this is a known problem. Our mobile SDK uses Glide v3.7 as image loader library, so if your app uses Glide too, make sure you use the same version (or at least v3.x) to avoid this error. We still work on it to make sure in the future, no such version clashing exist anymore.
Modify base theme to avoid error
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item> </style>
If the error looks like this :
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.yourcompany.appname/com.midtrans.sdk.uikit.activities.UserDetailsActivity}: java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead. |
---|
You should have no worries. Since our mobile SDK uses Toolbar as ActionBar, you need to disable ActionBar in your app and use Toolbar instead. It requires you to modify your base theme.
For more information regarding this particular error, please refer to this Stack Overflow post.
I would like to test bank point. Is there any testing credential that I can use?
Sure. If you want to test bank point in sandbox environment, you can use this card number.
- BNI Point : 4105 0586 8948 1467
- Mandiri Fiestapoin : 4617 0069 5974 6656
The expiry and CCV are the same like any other testing cards. Please refer to this section to see other testing credential.
Why is the Gojek App can’t be opened from my app when using iOS SDK?
There is a case that Gojek app is not detected, while using our iOS SDK.
You will need to add LSApplicationQueriesSchemes key to your app’s Info.plist
Add LSApplicationQueriesSchemes key with this value:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>gojek</string>
</array>
How to get pdf_url ?
pdf_url is an response property that provide url to download instruction of VA payment. Here’s how to get pdf_url : String pdfUrl = transactionResponse.getPdfUrl()
Handle Async Payment
There are some async payment supported by Midtrans:
- Internet Banking and Direct Debit
- KlikBCA
- BCA KlikPay
- Epay BRI
- CIMB Clicks
- LINE Pay e-cash / mandiri e-cash
- Bank Transfer (Virtual Account)
- BCA VA
- Mandiri Bill
- Permata VA
- Convenience Store
- Indomaret
- Installment Method
- Akulaku
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:
- HTTP Notification sent from Midtrans backend
- Get Latest Transaction Status using Midtrans API
Handling HTTP Notification
In order to increase the security aspect, there are several ways to ensure that the notification received is 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.
Signature Key
We added 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 not be 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
- Always use an HTTPS endpoint. It is secure and there cannot be MITM attacks because we validate the certificates match the hosts. Also do not use self signed certificates.
- Always implement notification in an idempotent way, in extremely rare cases, we may send multiple notifications for the same transaction event twice. It should not cause double entries on the merchant end. The simple way of achieving this is to use orderid as the key to track the entries.
- Always check the signature hash of the notification, This will confirm that the notification was actually sent by Midtrans, because we encode the shared secret (server key). Nobody else can build this signature hash.
- Always check all the following three fields to confirm successful transactions
- status code: Should be 200 for successful transactions
- fraud status: ACCEPT
- transaction status : settlement/capture
- We strive to send the notification immediately after the transaction has occurred, but in extremely rare cases, it may be delayed because of transaction spikes. If you have not received a notification, please use the Status API to check the current status of the transaction.
- It is safe to call Status API to get the latest status of the transaction/order on each notification.
- We set the HTTP timeout to 30 seconds. Please strive to keep the response time of the HTTP notifications under 5 seconds.
- In extremely rare cases we may send the HTTP notifications out of order, ie. a
settlement
status for a notification before the notification forPending
status. It’s important that such later notifications are ignored. Here’s the state transition diagram that you could use. But again, use our /status API to confirm the actual status. - We send the notification body as JSON, please parse the JSON with a JSON parser. Always expect new fields will be added to the notification body, so parse it in a non strict format, so if the parser sees new fields, it should not throw exception. It should gracefully ignore the new fields. This allows us to extend our notification system for newer use cases without breaking old clients.
- Always use the right HTTP Status code for responding to the notification, we handle retry for error cases differently based on the status code
- for 2xx: No retries, it is considered success
- for 500: We will retry 1 times in the 1 minute interval
- for 503: Retry 4 times
- for 400/404: retry 2 times in 1 minute interval
- for all other failures: Retry 5 times at 1 minute interval
- Redirection
- for 307/308: The request will be repeated with the new URL using POST method and the same notification body. A maximum of 5 redirection is allowed. -for 301/301/303: The job will be marked as failed without further retries. The merchant will be notified via email. We suggest either to use 307/308 or update the notification endpoint settings in merchant portal.
The following are the standard types of notifications. Note different types of notifications can be added in addition to the ones 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.
GoPay Tokenization SDK
Overview
Gopay tokenization SDK allows your Android and iOS app users to link their Gopay account and perform payments within your app. Users can get their balance and choose which Gopay payment method they want to use. The SDK opens a secure webview for authorization. Other than that, you control the user experience.
Feature
Gopay tokenization SDK allows you to do the following:
- Account linking - This feature links a user’s gopay account to your merchant ID.
- Account status inquiry - This feature enquires about the status of a linked account. You’ll get the linking status, and if the account is linked, this feature will also provide the available Gopay payment options along with the balance and the token required to create transactions.
- Create transactions - This feature creates transactions using the user’s token.
- Disable account - This feature unlinks the account and disables the use of the user token.
- API response processor - This feature simplifies the processing of use-cases that need further processing via Web in account linking and transaction API.
Usage
Installation
Gopay Tokenization SDK is available via Gradle on Android and CocoaPods on iOS.
Android
Add Midtrans Maven on build.gradle on the root project
allprojects {
repositories {
...
maven { url "http://dl.bintray.com/pt-midtrans/maven" }
}
}
Add the following line to the dependency section inside your app’s module’s build.gradle
implementation "com.midtrans:gopay-checkout:0.1.5"
IOS
Please follow the following steps to install the library to your app.
Step 1: Prepare the Podfile
Add the following to your Podfile
target 'MyApp' do
pod 'GopayCheckoutKit'
end
The above code example will get you the latest version of the library. If you need to use a specific version of the library, use the following script, and change the [ ] with the version number you wish to use.
target 'MyApp' do
pod 'GopayCheckoutKit','~> [version number]'
end
Step 2: Execute the Podfile
On your terminal, run
$ pod install
Step 3: Add the code to the AppDelegate
For Swift, you need to import GopayCheckoutKit in your AppDelegate.Swift File and every class where you plan to use the SDK method.
For Objective-C, you need to import GopayCheckoutKit.h in your AppDelegate.h and every class where you plan to use the SDK method.
Step 4: Setup app URL scheme
This step is needed to let the SDK go back to close the webview automatically and navigate to the previous screen. For example, your app URL scheme should be something like myapp://, all lowercase.
To set up your app URL scheme, you can choose to either: Go to Project Settings -> Info, and add inside the URL Types section, a new URL scheme. Add something of the sort of myapp or any name you prefer, all lowercase.
Alternatively, you can also go to your info.plist file and paste the following code. You can rename the myapp value with your preferred name.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
Initialization
To start using the SDK, you need to initialize the installed libraries. You can provide the following mandatory parameters:
Paramtert Name | Explanation |
---|---|
merchant_id | This is your merchant ID. You can find this in your Midtrans dashboard |
callback_url | This is the callback URL that will redirect back after webview is invoked |
mercahnt_server_url | This is the address of the merchant server that you register to Midtrans |
Android
You need to pass the Android context to initialize the client. Use the following script to initialize on Android.
GoPayCheckoutClient goPayCheckoutClient = new GoPayCheckoutClient(
CONTEXT,
MERCHANT_ID,
CALLBACK_URL,
MERCHANT_SERVER_URL,
false // to enable logging
);
IOS
In your AppDelegate file, you need to set up the SDK within the application:didFinishLaunchingWithOptions: and application:openURL:method.
Ever since iOS 13, Apple introduced SceneDelegate, so you’ll also need to add the handleCallbackUrl method on the SceneDelegate file within the openURLContexts: method.
Use this script in the AppDelegate
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
//sdk initialization
[GPYClient initWithMerchantServerURL:MERCHANT_SERVER_URL merchantId:MERCHANT_ID callbackUrl:@"myapp://home" isLoggingEnabled:NO];
//to handle callback
(BOOL) application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
//add handleCallbackUrl method
[GPYClient handleCallbackUrl:url];
return YES;
}
Use this script in the SceneDelegate
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts{
//also add handleCallbackUrl method on SceneDelegate
NSURL *url = URLContexts.allObjects.firstObject.URL;
[GPYClient handleCallbackUrl:url];
}
Important Notes : For the callbackUrl parameter, please use your app URL scheme with this format myapp://home, by adding home to your app URL scheme, as shown in the code below
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
//sdk initialization
[GPYClient initWithMerchantServerURL:MERCHANT_SERVER_URL merchantId:MERCHANT_ID callbackUrl:@"myapp://home" isLoggingEnabled:YES];
...
}
For the isLoggingEnabled parameter, for security purposes, we encourage merchants to disable it (by giving false) on production apps.
Account Linking
In order to be able to generate the token for transaction purposes, users need to link their wallet.
Account linking is the process for users to link their Gopay account to your merchant account. The result is a token used for:
- account status inquiry
- create a transaction
- disable an account
The overview of account linking is seen in this flow
To do account linking, you need to provide the GoPayPartnerDetails object that consisted of the following parameters:
Field | Explanation |
---|---|
PHONE_NUMBER | Phone number string without country code and without leading 0 with a minimum length of 9 characters maximum of 12 characters. Please refer to E.164 standard for this |
COUNTRY_CODE | Country code string without the + sign with a minimum length of 1 character and a maximum of 3 characters. Please refer to the E.164 standard. For Indonesian merchants, please use 62 as the value |
Android
The following script can be used as an example for account linking on Android :
// use the goPayCheckoutClient object from initialization
goPayCheckoutClient.linkAccount(
ACTIVITY,
new GoPayPartnerDetails(
PHONE,
COUNTRY_CODE
),
new GoPayCheckoutCallback<AccountResponse>() {
@Override
public void onResponse(AccountResponse response) {
// Handle response of account linking
// For actual status merchant need to use get account status API
}
@Override
public void onFailure(GoPayCheckoutError error, AccountResponse errorResponse) {
// Handle error
}
}
The AccountResponse object has the following properties that you will require in other APIs
Name | Type | Explanation |
---|---|---|
accountId | String | Account ID to be used enquire account status, create a transaction and disable the account |
accountStatus | String | Current account linking status. Possible values are ENABLED, PENDING, and DISABLED |
The errorResponse object maps the error response from the Partner API. You can parse the message to identify the problem. Please refer to this section of partner API Docs for detailed information.
IOS
The following script can be used as an example for account linking on iOS
GPYPartnerDetails *details = [[GPYPartnerDetails alloc]initWithPhoneNumber:phone countryCode:@"62"];
// use the initialized GPYClient object
[GPYClient linkAccountWithPaymentType:@"gopay" gopayPartnerDetails:details viewController:self completion:^(GPYLinkAccountResult * _Nullable result, NSError * _Nullable error) {
if (result) {
// do something
} else{
// error
}
}];
The GPYLinkAccountResult object has the following properties that you will require in other APIs
Name | Type | Explanation |
---|---|---|
accountID | String | Account ID to be used enquire account status, create a transaction and disable the account |
accountStatus | String | Current account linking status. Possible values are ENABLED, PENDING, and DISABLED |
The error object maps the error response from the Partner API. You can parse the message to identify the problem. Please refer to this section of partner API Docs for detailed information.
Account Status Enquiry
The account status inquiry is used before creating transactions. The API is required for the following purposes:
- Checking the account linking status
- Getting available payment options
- Getting the balance of each available payment option
Currently, we support Gopay Wallet and Gopay Paylater for account status, but this will be dynamically added or reduced. Please do not hardcode the types and rely on the resulting payment options.
The overview of the account status inquiry is seen in this flow.
The parameter that you need for this API is the account_id, which you get from the response from the account linking API.
The API will result in account information where you will get the linking status, list of available payment options. The payment options have the balance information and the payment option token that you need to create transactions.
Android
The following script can be used as an example for account status enquiry on Android
goPayCheckoutClient.enquireAccount(
ACCOUNT_ID,
new GoPayCheckoutCallback<AccountResponse>() {
@Override
public void onResponse(AccountResponse response) {
// Handle response of account enquiry
}
@Override
public void onFailure(GoPayCheckoutError error, AccountResponse errorResponse) {
// Handle error
}
}
);
The AccountResponse object has the following properties that you will require in other APIs
Name | Type | Explanation |
---|---|---|
accountId | String | Account ID to be used enquire account status, create a transaction and disable an account |
accountStatus | String | Current account linking status. Possible values are ENABLED, PENDING and DISABLED |
Metadata | AccountMetadata | List of available PaymentOption objects |
The PaymentOption object has the following properties that you will require in other APIs
Name | Type | Explanation |
---|---|---|
name | String | Name of payment option |
active | Boolean | Payment option status. True indicates active |
token | String | Payment token to create transactions |
balance | Amount | An object consisting of amount and currency |
The errorResponse object maps the error response from the Partner API. You can parse the message to identify the problem. Please refer to this section of partner API Docs for detailed information.
IOS
The following script can be used as an example for account status inquiry on Android
[GPYClient enquireAccountWithAccountID:ACCOUNT_ID completion:^(GPYAccountInfo * _Nullable result, NSError * _Nullable error) {
if (result) {
// Handle the account info of account enquiry
} else{
// Handle error
}
}];
The GPYAccountInfo object has the following properties that is required in other APIs
Name | Type | Explanation |
---|---|---|
accountID | String | Account ID to be used to enquire account status, create a transaction and disable the account |
accountStatus | String | Current account linking status. Possible values are ENABLED, PENDING and DISABLED |
metadata | GPYAccountMetadata | List of available GPYPaymentOption objects |
The GPYPaymentOption object has the following properties that you will require in other API
Name | Type | Explanation |
---|---|---|
name | String | Name of payment option |
active | Boolean | Payment option status. True indicates active |
token | String | Payment token to create transactions |
balance | Amount | An object consisting of amount and currency |
The error object maps the error response from the Partner API. You can parse the message to identify the problem. Please refer to this section of partner API Docs for detailed information.
Create Transaction
The overview for creating transactions is shown in this flow.
Created transactions are idempotent by nature. If you send the same transaction object, it will only check the same transaction on the server and return the same object without creating a new one.
The create transaction API is used to perform transactions from an already linked account. You need the following parameters to create transactions:
Field | Explanation |
---|---|
GoPayDetails | An object that contains account_id and payment_option_token from the account status inquiry process |
TransactionDetails | An object that contains the gross_amount and currency |
Items | This is a list of ItemDetail objects that specifies the items involved in the transaction. The information is item_id, name, price, quantity, and category. This is an optional parameter and can be set to null if not used |
Android
The following script can be used as an example for creating transactions on Android
List<ItemDetail> items = new ArrayList<>();
items.add(
new ItemDetail(
UUID.randomUUID().toString(),
"Beli barang bagus",
12000L,
1,
null
)
);
goPayCheckoutClient
.createTransaction(
Activity.this,
new GoPayDetails(
ACCOUNT_ID,
PAYMENT_OPTION_TOKEN
),
new TransactionDetails(
ORDER_ID,
GROSS_AMOUNT,
"IDR" //CURRENCY
),
PHONE_NUMBER,
items,
new GoPayCheckoutCallback<TransactionResponse>() {
@Override
public void onResponse(TransactionResponse response) {
// Handle transaction finished
// Result is available in the HTTP Notification not from SDK
}
@Override
public void onFailure(GoPayCheckoutError error, TransactionResponse errorResponse) {
// Handle error
}
}
);
The TransactionResponse object has the following properties
Name | Type | Explanation |
---|---|---|
transactionId | String | The transaction ID recorded in the system. |
transactionStatus | String | The transaction status. This will always return pending as the status is sent via HTTP Notification. |
orderID | String | The order ID set in the TransactionDetails passed into the create transaction API. |
grossAmount | String | The transaction amount. |
currency | String | The currency of the transaction. |
paymentType | String | The payment option type used in the transaction. |
transactionTime | String | The time of transaction. |
fraudStatus | String | This is the fraud checking Status. |
The errorResponse object maps the error response from the Partner API. You can parse the message to identify the problem. Please refer to this section of partner API Docs for detailed information.
IOS
The following script can be used as an example for creating transactions on iOS
GPYGopayDetails *gopayDetails = [[GPYGopayDetails alloc]initWithAccountID:ACCOUNT_ID paymentOptionToken:PAYMENT_OPTION_TOKEN];
GPYTransactionDetails *transDetails = [[GPYTransactionDetails alloc]initWithGrossAmount:@100 orderID:ORDER_ID currency:@"IDR"];
GPYItemDetails *itemDetails = [[GPYItemDetails alloc]initWithIthItemID:@"itemId1" name:@"one piece t-shirt" price:@100 quantity:@1 category:@"clothing"];
[GPYClient createTransactionWithPaymentType:@"gopay" viewController:self gopayDetails:gopayDetails transactionDetails:transDetails itemDetails:@[itemDetails] completion:^(GPYTransactionResult * _Nullable result, NSError * _Nullable error) {
if (result) {
// Handle transaction finished
// Result is available in the HTTP Notification not from SDK
} else {
// Handle error
}
}];
The GPYTransaction object has the following properties
Name | Type | Explanation |
---|---|---|
transactionID | String | The transaction ID recorded in the system. |
transactionStatus | String | The transaction status. This will always return pending as the status will be sent via HTTP Notification. |
orderID | String | The order ID set in the TransactionDetails passed into the create transaction API. |
grossAmount | String | The transaction amount. |
currency | String | The currency of the transaction. |
paymentType | String | The payment option type used in the transaction. |
transactionTime | String | The time of transaction. |
fraudStatus | String | The fraud checking Status. |
The error object maps the error response from the Partner API. You can parse the message to identify the problem.Please refer to this section of partner API Docs for detailed information.
Disable Account
The API will stop the linking of user accounts from your merchant ID, and for making the payment option tokens unable to be used again. If the user needs to create transactions, the user account needs to be linked again.
The overview for disabling an account is shown in this flow.
The parameter that you need for this API is the account_id, which you get from the result of the account linking API.
Android
The following script can be used as an example for disabling account on Android.
goPayCheckoutClient.disableAccount(
ACCOUNT_ID,
new GoPayCheckoutCallback<AccountResponse>() {
@Override
public void onResponse(AccountResponse response) {
// Handle response of disable the account
}
@Override
public void onFailure(GoPayCheckoutError error, AccountResponse errorResponse) {
// Handle error
}
}
);
The AccountResponse object has the following properties.
Name | Type | Explanation |
---|---|---|
accountId | String | Account ID similar to what you use to disable an account |
accountStatus | String | Current account linking status. The result will always return DISABLED |
The errorResponse object maps the error response from the Partner API. You can parse the message to identify the problem.Please refer to this section of partner API Docs for detailed information.
IOS
The following script can be used as an example for disabling account on iOS
[GPYClient disableAccountWithAccountID:ACCOUNT_ID completion:^(GPYDisableAccountResult * _Nullable result, NSError * _Nullable error) {
if (result) {
// Handle response of disable account
} else {
// Handle error
}
}];
The GPYDisableAccountResponse object has the following properties
Name | Type | Explanation |
---|---|---|
accountID | String | Account ID similar to what you use to disable account |
accountStatus | String | Current account linking status. The result will always return DISABLED |
The error object maps the error response from the Partner API. You can parse the message to identify the problem. Please refer to this section of partner API Docs for detailed information.
Checkout API Response Processor
For account linking and making payment API, some use-cases need further processing via Web. The checkout API response processor can be used to simplify it.
Since the response is processed beforehand, the app should already know the pending response. However, the processor does not know the actual status. So after completion, callback is called, the app should check the latest status API.
Account Linking
Android
The following script can be used as an example for account linking response processor on Android
GoPayCheckoutProcessor
.processAccountLinking(
ACTIVITY,
RESPONSE,
CALLBACK_URL,
new GoPayCheckoutProcessorCallback() {
@Override
public void onCompleted() {
// Handle completed
}
}
);
IOS
The following script can be used as an example for account linking response processor on iOS
[GPYCheckoutProcessor processAccountLinkingWithResponse:linkingResponse viewController:viewController completion:^(GPYLinkAccountResult * _Nullable result, NSError * _Nullable error) {
if (result) {
// Handle completed
} else{
// Handle error
}
}];
Making Payment
Android
The following script can be used as an example for making payment response processor on Android
GoPayCheckoutProcessor
.processTransaction(
ACTIVITY,
RESPONSE,
CALLBACK_URL,
new GoPayCheckoutProcessorCallback() {
@Override
public void onCompleted() {
// Handle completed
}
}
);
IOS
The following script can be used as an example for create transaction response processor on iOS
[GPYCheckoutProcessor processCreateTransactionWithResponse:transactionResponse viewController:viewController completion:^(GPYTransactionResult * _Nullable result, NSError * _Nullable error) {
if (result) {
// Handle completed
} else {
// Handle error
}
}];
Merchant Server API Specification
There is a merchant server component in the transaction flow. The goal is to provide an extra layer of security since your Midtrans Server Key should be passed in the header of each request. The Server key is important, so you need to ensure that it is not embedded in your application since there’s a possibility of reverse engineering through decompilation. All requests coming from the SDK will not have the authorization header since the merchant server will provide this.
The server key that is base64 encoded should be in the Authorization request header. The rest of the headers and request body should just be forwarded. Once the response from the Partner API is received, the received request body, status code and request headers should be returned to the SDK.
The following sections define the specification of each required endpoints.
Account Linking
Endpoint address is /v2/pay/account
Request method is POST
Expected mandatory additional headers being sent to partner API are listed in the table below:
Field Name | Type | Value | Explanation |
---|---|---|---|
Content-Type | String | application/json | Standard requirement to define the incoming request content type. |
Accept | String | application/json | Standard requirement to expect response content type. |
Authorization | String | Base64 Encoded result of Server key | A string resulted from Base64 encoding of the Midtrans Merchant Server Key. |
Partner API forwarding endpoint is /v2/pay/account
Request Method is POST.
Request Header should follow the above requirements.
Request body should forward all request body sent from the SDK.
For every response from Partner API, please return to SDK and use the same request headers and request body. HTTP status code should follow the payload content in the status_code field.
Account Status Enquiry
Endpoint address is /v2/pay/account/<account id>
Request method is GET
The expected mandatory additional headers being sent to the partner API are listed in the table below:
Field Name | Type | Value | Explanation |
---|---|---|---|
Accept | String | application/json | Standard requirement to expect response content type |
Authorization | String | Base64 Encoded result of Server key | A string resulted from Base64 encoding of the Midtrans Merchant Server Key |
Partner API forwarding endpoint is /v2/pay/account/<account id>
Request Method is GET.
Request Header should follow the above requirements.
Request body should forward all request body sent from the SDK.
For every response from Partner API, please return to SDK and use the same request headers and request body. HTTP status code should follow the payload content in the status_code field.
Create Transaction
Endpoint address is /v2/charge
Request method is POST
Expected mandatory additional headers being sent to partner API are listed in the table below:
Field Name | Type | Value | Explanation |
---|---|---|---|
Content-Type | String | application/json | Standard requirement to define the incoming request content type. |
Accept | String | application/json | Standard requirement to expect response content type. |
Authorization | String | Base64 Encoded result of Server key | A string resulted from Base64 encoding of the Midtrans Merchant Server Key. |
Partner API forwarding endpoint is /v2/charge.
Request Method is POST.
Request Header should follow the above requirements.
Request body should forward all request body sent from the SDK
For every response from Partner API, please return to SDK and use the same request headers and request body. HTTP status code should follow the payload content in the status_code field.
Disable Account
Endpoint address is /v2/pay/account/<account id>/unbind
Request method is POST
Expected mandatory additional headers being sent to partner API are listed in the table below:
Field Name | Type | Value | Explanation |
---|---|---|---|
Content-Type | String | application/json | Standard requirement to define the incoming request content type |
Accept | String | application/json | Standard requirement to expect response content type |
Authorization | String | Base64 Encoded result of Server key | A string resulted from Base64 encoding of the Midtrans Merchant Server Key |
Partner API forwarding endpoint is /v2/pay/account/<account id>/unbind
Request Method is POST
Request Header should follow the above requirements
Request body should forward all request body sent from the SDK
For every response from Partner API, please return to SDK and use the same request headers and request body. HTTP status code should follow the payload content in the status_code field.
Example Reference
Example reference of the SDK implementation can be accessed here. Example reference of the merchant server implementation can be accessed here.
Status Code Reference
Flow | Status Code | State(Success/Failed) | Returns | Explanation |
---|---|---|---|---|
Account Linking | 200 | Success | Account exist & linked | Account existed and linking is already successful |
201 | Success | PENDING | Account linking not completed, waiting for action from user | |
202 | Failed | Internal server error | Please refer to the error message specified | |
310 | Failed | Malformed data | validation error on one of the fields | |
400 | Failed | Bad request | Something wrong in the request sent | |
401 | Failed | Unauthorized | Please recheck authorization credentials | |
9xx | Failed | server problem | Intermittent gopay error | |
Account Enquiry | 200 | Success | Success | Account info returned |
201 | Success | Pending | Account linking process hasn’t been completed | |
400 | Failed | Bad request | Something wrong in the request sent | |
404 | Failed | Not found | Account you want to check does not exist | |
Create Transaction | 200 | Success | Create transaction success | Transaction created successfully, no action needed |
201 | Success | Pending | Transaction pending, action needed | |
202 | Failed | Denied | Transaction denied | |
400 | Failed | Bad request | Something wrong in the request sent | |
401 | Failed | Unauthorized | Please recheck authorization credentials | |
502 | Failed | Timeout | Timeout from gopay during creation | |
Unlink Account | 204 | Success | Account disabled | Account unlinked successfully |
202 | Failed | Authentication error | Recheck account authentication | |
400 | Failed | Bad request | Something wrong in the request sent | |
401 | Failed | Unauthorized | Please recheck authorization credentials | |
404 | Failed | Not found | Account does not exist |
Support / Contact
For further questions or support, you can contact our amazing support team. We are always happy to help you integrate faster. Additional Documentation can also be accessed here.
Frequently Asked Questions
- Do I need the Midtrans UIKit SDK to use the tokenization SDK?
No, the Gopay tokenization SDK is a standalone SDK. It doesn’t have any dependency to the other Midtrans SDK.
- Will there be any instances when my user needs to be redirected to the Gojek app in the middle of any of the payment flows?
No, the SDK is designed to keep the user within your app. The authentication happens via a secure webview within your app.
- Is it safe to store the payment option token on the backend or frontend or both?
The token is safe to store. It can only be used to create transactions with your merchant ID, and it requires user’s authorization before it can be used.
- What happens if the token is invalidated (by Midtrans/Gopay/user)?
If the token is invalidated, the token can no longer be used to create transactions. If the user wants to do another transaction then the user needs to re-do the account linking flow.
- Is there any information on the response object that is unsafe for storage or personally identifiable information?
No, all information provided is safe to store.
- Is Paylater supported?
Paylater is one of the options available in the payment options list if your user is eligible to use it.
- How do I differentiate between sandbox and production environments?
You can do that by switching the merchant server URL between sandbox and production in your own server environment.
- How can I ensure that users can’t do credit based payments?
You will get the available payment option when you enquire about the account status. Do not show the PayLater options from the list as a payment option.
- When will the PIN request webview pop up?
The PIN request webview will pop up during the following conditions. Account linking process after user enters the OTP and during transaction creation to authorize the payment
- Do I need to give my users the options to “unlink/disable their accounts”?
You need to give users the control over the use of their payment tokens. Be explicit on what happens after a user unlinked/disabled the account.
- Do I have to notify my users when a transaction takes place using a token?
Users will know that they entered the authorization PIN and afterward will expect a status on the payment. We will notify your merchant server via HTTP notification and you can notify the users on the payment status change after the success notification was received.