Skip to content

Repository files navigation

Midtrans Client - Java

DownloadBuild StatusDemo apps

Midtrans ❤️ Java, This is the Official Java API client/library for Midtrans Payment API. Visit https://midtrans.com. More information about the product and see documentation at http://docs.midtrans.com for more technical details. This library used java version 1.8

1. Installation

1.a Using Maven or Gradle

If you're using Maven as the build tools for your project, please add the following dependency to your project's build definition (pom.xml): Maven:

<dependency>
<groupId>com.midtrans</groupId>
<artifactId>java-library</artifactId>
<version>3.2.2</version>
</dependency>

Gradle: If you're using Gradle as the build tools for your project, please add jcenter repository to your build script then add the following dependency to your project's build definition (build.gradle):

dependencies {
implementation 'com.midtrans:java-library:3.2.2'
}

IMPORTANT NOTE: Since April 13, 2021 We already migrate the repository from jcenter/bintray repository to Maven central.

1.b Using JAR File

If you are not using project build management like Maven, Gradle or Ant you can use manual jar library download JAR Library on here

2. Usage

2.1 Choose Product/Method

We have 3 different products that you can use:

  • Snap - Customizable payment popup will appear on your web/app (no redirection). doc ref
  • Snap Redirect - Customer need to be redirected to payment url hosted by midtrans. doc ref
  • Core API (VT-Direct) - Basic backend implementation, you can customize the frontend embedded on your web/app as you like (no redirection). doc ref
  • Iris Disbursement - Iris is Midtrans’ cash management solution that allows you to disburse payments to any bank accounts in Indonesia securely and easily. doc ref

Choose one that you think best for your unique needs.

2.2 Client Initialization and Configuration

Get your client key and server key from Midtrans Dashboard

Create API client object, Select one from any of methods below that you most prefer. You can also check the project's functional tests for more examples.

Set a config with globally, except iris api

importcom.midtrans.Midtrans;
importcom.midtrans.httpclient.CoreApi;
importcom.midtrans.httpclient.SnapApi;
importcom.midtrans.httpclient.error.MidtransError;
importorg.json.JSONObject;
Midtrans.serverKey = "YOUR_SERVER_KEY";
Midtrans.clientKey = "YOUR_CLIENT_KEY";
Midtrans.isProduction = false;
// CoreApi Request with global configJSONObjectresult = CoreApi.chargeTransaction(param);
// SnapApi request with global configJSONObjectresult = SnapApi.createTransaction(param);

Per-request Configuration

It is also possible if on each of individual requests you want to set a unique/different configuration; like idempotency key, proxy, override/append notification url, or multiple account API keys via Config options and set as param on static method e.g: CoreApi.chargeTransaction(param, configOptions) method available on CoreApi.class, SnapApi.class, TransactionApi.class or IrisApi.class. Please follow the steps given below.

Note: This method is expected to be thread-safe, you should prefer this if you are implementing multi-threading/concurrency in your code.

importcom.midtrans.Config;
importcom.midtrans.Midtrans;
importcom.midtrans.httpclient.CoreApi;
importcom.midtrans.httpclient.error.MidtransError;
importorg.json.JSONObject;
ConfigcoreApiConfigOptions = Config.builder()
.setServerKey("YOUR_SERVER_KEY")
.setClientKey("YOUR_CLIENT_KEY")
.setIrisIdempotencyKey("UNIQUE_ID")
.setPaymentIdempotencyKey("UNIQUE_ID")
.setProxyConfig(PROXY_CONFIG)
.setPaymentOverrideNotification("WEBHOOK_ENDPOINT")
.setIsProduction(false)
.build();
// CoreApi request with config optionsJSONObjectresult = CoreApi.chargeTransaction(param, coreApiConfigOptions);
ConfigsnapConfigOptions = Config.builder()
.setServerKey("YOUR_SERVER_KEY")
.setClientKey("YOUR_CLIENT_KEY")
.setIrisIdempotencyKey("UNIQUE_ID")
.setPaymentIdempotencyKey("UNIQUE_ID")
.setProxyConfig(PROXY_CONFIG)
.setPaymentOverrideNotification("WEBHOOK_ENDPOINT")
.setIsProduction(false)
.build();
// SnapApi request with config optionsJSONObjectresult = SnapApi.createTransaction(param, snapConfigOptions);

In case you are using a single account API key, but you need to set the config options value dynamically from the config object. Please follow the steps given below.

importcom.midtrans.Midtrans;
importcom.midtrans.httpclient.CoreApi;
importcom.midtrans.httpclient.SnapApi;
importcom.midtrans.httpclient.error.MidtransError;
importorg.json.JSONObject;
//1. Set credentials key globallyMidtrans.serverKey = "YOUR_SERVER_KEY";
Midtrans.clientKey = "YOUR_CLIENT_KEY";
Midtrans.isProduction = false;
//2. Set config options for core-api charge requestConfigconfigOptions = Config.builder()
.setPaymentIdempotencyKey("UNIQUE_ID")
.setPaymentOverrideNotification("DYNAMIC_WEBHOOK_ENDPOINT")
.build();
//3. CoreApi request with config optionsJSONObjectresult = CoreApi.chargeTransaction(param, configOptions);
//4. Set config options for Snap charge requestConfigsnapConfigOptions = Config.builder()
.setPaymentOverrideNotification("DYNAMIC_WEBHOOK_ENDPOINT")
.build();
//5. SnapApi request with config optionsJSONObjectresult = SnapApi.createTransaction(param, snapConfigOptions);

Alternative way to initialize

importcom.midtrans.Config;
importcom.midtrans.ConfigFactory;
importcom.midtrans.service.MidtransCoreApi;
ConfigcoreApiConfigOptions = Config.builder()
.setServerKey("YOUR_SERVER_KEY")
.setClientKey("YOUR_CLIENT_KEY")
.setIsProduction(false)
.build();
MidtransCoreApicoreApi = newConfigFactory(coreApiConfigOptions).getCoreApi();
//You can set Config.class with
`YOUR_SERVER_KEY`
`YOUR_CLIENT_KEY`
`isProduction`
importcom.midtrans.Config;
importcom.midtrans.ConfigFactory;
importcom.midtrans.service.MidtransSnapApi;
ConfigsnapConfigOptions = Config.builder()
.setServerKey("YOUR_SERVER_KEY")
.setClientKey("YOUR_CLIENT_KEY")
.setIsProduction(false)
.build();
MidtransSnapApisnapApi = newConfigFactory(snapConfigOptions).getSnapApi();
//You can set Config.class with
`YOUR_SERVER_KEY`
`YOUR_CLIENT_KEY`
`isProduction`
importcom.midtrans.Config;
importcom.midtrans.ConfigFactory;
importcom.midtrans.service.MidtransIrisApi;
ConfigirisConfigOptions = Config.builder()
.setServerKey("IRIS-CREDENTIAL")
.setIsProduction(false)
.build();
MidtransIrisApiirisApi = newConfigFactory(irisConfigOptions).getIrisApi();
//You can set Config.class with
`IRIS-CREDNTIALS`
`null`
`isProduction`

You can also re-set config using apiConfig() method on MidtransCoreApi.Class, MidtransSnapApi.Class or MidtransIrisApi.class like coreApi.apiConfig().set( ... )

Please note that if you are using multi-thread concurrency, this method is not thread-safe. For that, you should use the method of creating & setting individual Config option instances per request. Refer to this section

example:

// Create Snap API instance, empty configcoreApi.apiConfig().setProduction(false);
coreApi.apiConfig().setClientKey("YOUR_CLIENT_KEY");
coreApi.apiConfig().setServerKey("YOUR_SERVER_KEY");
// You don't have to re-set using all the options, // i.e. set serverKey onlycoreApi.apiConfig().setServerKey("YOUR_SERVER_KEY");
// For Iris Disbursement can set creator & approver credentials with apiConfig()irisApi.apiConfig().setServerKey("IRIS-CREDENTIALS");

In production environment, LOG is by default turned off, you can enable by setEnabledLog, e.g:

coreApi.apiConfig().setEnabledLog(true);
//or usingconfig.setEnabledLog(true);

Using internal proxy, you can set ProxyConfig object with ProxyConfigBuilder to set hostname, port, username, and password. and also connectionTimeout, readTimeout, and writeTimeout. But if you not define network configuration like ProxyConfig, connectionTimeout, readTimeout and writeTimeout, default value is 10 second and the connection no proxy configuration.

example:

importcom.midtrans.proxy.ProxyConfig;
importcom.midtrans.service.MidtransCoreApi;
ProxyConfigproxyConfig = ProxyConfig.builder()
.setHost(PROXY_HOTS)
.setPort(PROXY_PORT)
.setUsername(PROXY_USERNAME)
.setPassword(PROXY_PASSWORD)
.build();
//Initialize MidtransCoreApi config with proxy and network configurationprivateMidtransCoreApicoreApi = newConfigFactory(newConfig("YOU_SERVER_KEY","YOUR_CLIENT_KEY", false, 10, 10, 10, proxyConfig)).getCoreApi();
// Alternative, initialize proxy in Global ConfigMidtrans.setProxyConfig(proxyConfig);

add new 4 params to use http proxy and network config,

  • connectionTimeout - default value 10s
  • readTimeout - default values 10s
  • writeTimeout - default value 10s
  • proxyConfig
  • maxConnectionPool - default value 16
  • keepAliveDuration - default value 300s

and also you can set value for connectionTimeout or etc with configuration class, default value for TimeUnit is SECONDS, you can change the TimeUnit with config class.

example:

// set as globallyMidtrans.setConnectTimeout(10000);
Midtrans.setReadTimeout(10000);
Midtrans.setWriteTimeout(10000);
Midtrans.setMaxConnectionPool(16);
Midtrans.setKeepAliveDuration(300000);
Midtrans.setHttpClientTimeUnit(TimeUnit.MILLISECONDS);
// set connection timeout with Config classconfig.setConnectionTimeout(10000, TimeUnit.MILLISECONDS);
config.setReadTimeout(10000, TimeUnit.MILLISECONDS);
config.setWriteTimeout(10000, TimeUnit.MILLISECONDS);
config.setKeepAliveDuration(300000, TimeUnit.MILLISECONDS);
config.setMaxConnectionPool(16);
// Set connection timeout from initiate api objectcoreApi.apiConfig().setConnectionTimeout(10000, TimeUnit.MILLISECONDS);
coreApi.apiConfig().setReadTimeout(10000, TimeUnit.MILLISECONDS);
coreApi.apiConfig().setWriteTimeout(10000, TimeUnit.MILLISECONDS);
coreApi.apiConfig().setKeepAliveDuration(300000, TimeUnit.MILLISECONDS);
coreApi.apiConfig().setMaxConnectionPool(16);

Override Notification Url

Merchant can opt to change or add custom notification urls on every transaction. It can be achieved by adding additional HTTP headers into charge request.

There are two headers we provide:

  1. X-Append-Notification: to add new notification url(s) alongside the settings on dashboard
  2. X-Override-Notification: to use new notification url(s) disregarding the settings on dashboard Both header can only receive up to maximum of 3 urls.

More details

//X-Append-NotificationConfigconfigOptions = Config.builder()
.setPaymentAppendNotification("https://example.com/test1,https://example.com/test")
.build();
CoreApi.chargeTransaction(param, configOptions);
//X-Override-NotificationConfigconfigOptions = Config.builder()
.setPaymentOverrideNotification("https://example.com/test1,https://example.com/test")
.build();;
CoreApi.chargeTransaction(param, configOptions);

When both X-Append-Notification and X-Override-Notification are used together then only override will be used.

Handling Error / Exception

When using function that result in Midtrans API call e.g: CoreApi.chargeTransaction(...) or SnapApi.createTransaction(...) there's a chance it may throw error (MidtransError object), the error object will contains below properties that can be used as information to your error handling logic:

try {
JSONObjectresult = CoreApi.chargeTransaction(param);
} catch (MidtransErrore) {
e.printStackTrace();
e.getStatusCode(); // basic error message stringe.getMessage(); // HTTP status code e.g: 400, 401, etc.e.getResponseBody(); // API response bodye.getResponse(); // raw OkHttp response object
}

CoreAPI Simple Sample Usage

importcom.midtrans.httpclient.CoreApi;
importcom.midtrans.httpclient.error.MidtransError;
importcom.midtrans.Midtrans;
importjava.util.HashMap;
importjava.util.Map;
importjava.util.UUID;
importorg.json.JSONObject;
publicclassMidtransExample {
publicstaticvoidmain(String[] args) throwsMidtransError {
Midtrans.serverKey = "YOUR_SERVER_KEY";
Midtrans.isProduction = false;
UUIDidRand = UUID.randomUUID();
Map<String, Object> chargeParams = newHashMap<>();
Map<String, String> transactionDetails = newHashMap<>();
transactionDetails.put("order_id", idRand.toString());
transactionDetails.put("gross_amount", "265000");
chargeParams.put("transaction_details", transactionDetails);
chargeParams.put("payment_type", "gopay");
JSONObjectresult = CoreApi.chargeTransaction(chargeParams);
System.out.println(result);
}
}

2.2.A Snap

You can see Snap example here.

Available methods for MidtransSnapApi class

//1. To get snap transaction with return json raw objectJSONObjectcreateTransaction(Map<String, Object> params);
//2. To get snap token with return String tokenStringcreateTransactionToken(Map<String, Object> params);
//3. To get snap redirect url with return String redirect urlStringcreateTransactionRedirectUrl(Map<String, Object> params);

params is Map Object or String of JSON of SNAP Parameter

Get Snap Token

// Create new Object SnapAPIMidtransSnapApisnapApi = newConfigFactory(newConfig("YOU_SERVER_KEY","YOUR_CLIENT_KEY", false)).getSnapApi();
// Create params JSON Raw Object requestpublicMap<String, Object> requestBody() {
UUIDidRand = UUID.randomUUID();
Map<String, Object> params = newHashMap<>();
Map<String, String> transactionDetails = newHashMap<>();
transactionDetails.put("order_id", idRand);
transactionDetails.put("gross_amount", "265000");
Map<String, String> creditCard = newHashMap<>();
creditCard.put("secure", "true");
params.put("transaction_details", transactionDetails);
params.put("credit_card", creditCard);
returnparams;
}
// Create Token and then you can send token variable to FrontEnd,// to initialize Snap JS when customer click pay buttonStringtransactionToken = snapApi.createTransactionToken(requestBody())
//you can use Model object in springboot controller to send token to FrontEndmodel.addAttribute("transactionToken", transactionToken);

Initialize Snap JS when customer click pay button

On frontend / html: Replace PUT_TRANSACTION_TOKEN_HERE with transactionToken acquired above, you can use java template engine like Thymeleaf to parse transactionToken to frontEnd like this[[${transactionToken}]]

<html><body><buttonid="pay-button">Pay!</button><pre><divid="result-json">JSON result will appear here after payment:<br></div></pre><!-- TODO: Remove ".sandbox" from script src URL for production environment. Also input your client key in "data-client-key" --><scriptsrc="https://app.sandbox.midtrans.com/snap/snap.js" data-client-key="<Set your ClientKey here>"></script><scripttype="text/javascript">document.getElementById('pay-button').onclick=function(){// SnapToken acquired from previous stepsnap.pay('PUT_TRANSACTION_TOKEN_HERE',{// OptionalonSuccess: function(result){/* You may add your own js here, this is just example */document.getElementById('result-json').innerHTML+=JSON.stringify(result,null,2);},// OptionalonPending: function(result){/* You may add your own js here, this is just example */document.getElementById('result-json').innerHTML+=JSON.stringify(result,null,2);},// OptionalonError: function(result){/* You may add your own js here, this is just example */document.getElementById('result-json').innerHTML+=JSON.stringify(result,null,2);}});};</script></body></html>

Implement Notification Handler

Refer to this section

2.2.B Snap Redirect

Also available as examples here.

Get Redirection URL of a Payment Page

// Create new Object SnapAPIMidtransSnapApisnapApi = newConfigFactory(newConfig("YOU_SERVER_KEY","YOUR_CLIENT_KEY", false)).getSnapApi();
// Create params JSON Raw Object requestpublicMap<String, Object> requestBody() {
UUIDidRand = UUID.randomUUID();
Map<String, Object> params = newHashMap<>();
Map<String, String> transactionDetails = newHashMap<>();
transactionDetails.put("order_id", idRand);
transactionDetails.put("gross_amount", "265000");
Map<String, String> creditCard = newHashMap<>();
creditCard.put("secure", "true");
params.put("transaction_details", transactionDetails);
params.put("credit_card", creditCard);
returnparams;
}
// Create Token and then you can send token variable to FrontEnd,// to initialize Snap JS when customer click pay buttonStringredirectURL = snapApi.createTransactionRedirectUrl(requestBody())
//you can return to redirectURL on springboot controllerreturn"redirect:" +redirectURL;

Implement Notification Handler

Refer to this section

2.2.C Core API (VT-Direct)

You can see Core API examples here.

Available methods for MidtransCoreApi class

/** * Do re-set config Class like clientKey, serverKey, isProduction * @return {Config class} */ConfigapiConfig();
/** * Do `/charge` API request to Core API * @param {Map Object} parameter - object of Core API JSON body as parameter, will be converted to JSON (more params detail refer to: https://api-docs.midtrans.com) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response */JSONObjectchargeTransaction(Map<String, Object> params);
/** * Do `/<orderId>/status` API request to Core API * @param {String} orderId - orderId of the transaction (more detail refer to: https://api-docs.midtrans.com) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response */JSONObjectcheckTransaction(StringorderId);
/** * Do `/<orderId>/approve` API request to Core API * @param {String} orderId - orderId of the transaction (more detail refer to: https://api-docs.midtrans.com) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response */JSONObjectapproveTransaction(StringorderId);
/** * Do `/<orderId>/cancel` API request to Core API * @param {String} orderId - orderId of the transaction (more detail refer to: https://api-docs.midtrans.com) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response */JSONObjectcancelTransaction(StringorderId);
/** * Do `/<orderId>/expire` API request to Core API * @param {String} orderId - orderId of the transaction (more detail refer to: https://api-docs.midtrans.com) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response */JSONObjectexpireTransaction(StringorderId);
/** * Do `/<orderId>/refund` API request to Core API * @param {String} orderId - orderId of the transaction (more detail refer to: https://api-docs.midtrans.com) * @param {Map Object} parameter - object of Core API JSON body as parameter, will be converted to JSON (more params detail refer to: https://api-docs.midtrans.com) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response */JSONObjectrefundTransaction(StringorderId, Map<String, String> params);
/** * Do `/token` API request to Core API * @param {Map Object} parameter - object of Core API JSON body as parameter, will be converted to JSON (more params detail refer to: https://api-docs.midtrans.com) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response */JSONObjectcardToken(Map<String, String> params);
/** * Do `/card/register` API request to Core API * @param {Map Object} parameter - object of Core API JSON body as parameter, will be converted to JSON (more params detail refer to: https://api-docs.midtrans.com) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response */JSONObjectregisterCard(Map<String, String> params);
/** * Do `/point_inquiry/<tokenId>` API request to Core API * @param {String} tokenId - tokenId of credit card (more detail refer to: https://api-docs.midtrans.com) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response */JSONObjectcardPointInquiry(StringtokenId);
/** * Do `/<orderId>/deny` API request to Core API * @param {String} orderId - orderId of the transaction (more detail refer to: https://api-docs.midtrans.com/#deny-transaction) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response */JSONObjectdenyTransaction(StringorderId);
/** * Do `v1/bins/{bin}` API request to Core API * @param binNumber {String} of the transaction (more detail refer to: https://api-docs.midtrans.com/#bin-api) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response * @throws MidtransError when an exception was occurred during executing the request. */JSONObjectgetBIN(StringbinNumber) throwsMidtransError;

params is Map Object or String of JSON of Core API Parameter

Credit Card Get Token

Get token should be handled on Frontend please refer to API docs

Credit Card Charge

MidtransCoreApicoreApi = newConfigFactory(newConfig("YOU_SERVER_KEY","YOUR_CLIENT_KEY", false)).getCoreApi();
// Create Function JSON Raw ObjectpublicMap<String, Object> requestBody() {
UUIDidRand = UUID.randomUUID();
Map<String, Object> params = newHashMap<>();
Map<String, String> transactionDetails = newHashMap<>();
transactionDetails.put("order_id", idRand);
transactionDetails.put("gross_amount", "265000");
Map<String, String> creditCard = newHashMap<>();
creditCard.put("token_id", YOUR_TOKEN_ID);
creditCard.put("authentication", "true");
params.put("transaction_details", transactionDetails);
params.put("credit_card", creditCard);
returnparams;
}
// charge transactionJSONObjectresult = coreApi.chargeTransaction(requestBody());
System.out.println(result);

Credit Card 3DS Authentication

The credit card charge result may contains redirect_url for 3DS authentication. 3DS Authentication should be handled on Frontend please refer to API docs

For full example on Credit Card 3DS transaction refer to:

2.3 Handle HTTP Notification

IMPORTANT NOTE: To update transaction status on your backend/database, DO NOT solely rely on frontend callbacks! For security reason to make sure the status is authentically coming from Midtrans, only update transaction status based on HTTP Notification or API Get Status.

Create separated web endpoint (notification url) to receive HTTP POST notification callback/webhook. HTTP notification will be sent whenever transaction status is changed. Example also available here

@PostMapping(value = "/notification", produces = MediaType.APPLICATION_JSON_VALUE)
privateResponseEntity<String> handleNotification(@RequestBodyMap<String, Object> response) throwsMidtransError {
StringnotifResponse = null;
if (!(response.isEmpty())) {
//Get Order ID from notification bodyStringorderId = (String) response.get("order_id");
// Get status transaction to api with order idJSONObjecttransactionResult = coreApi.checkTransaction(orderId);
StringtransactionStatus = (String) transactionResult.get("transaction_status");
StringfraudStatus = (String) transactionResult.get("fraud_status");
notifResponse = "Transaction notification received. Order ID: " + orderId + ". Transaction status: " + transactionStatus + ". Fraud status: " + fraudStatus;
System.out.println(notifResponse);
if (transactionStatus.equals("capture")) {
if (fraudStatus.equals("challenge")) {
// TODO set transaction status on your database to 'challenge' e.g: 'Payment status challenged. Please take action on your Merchant Administration Portal
} elseif (fraudStatus.equals("accept")) {
// TODO set transaction status on your database to 'success'
}
} elseif (transactionStatus.equals("cancel") || transactionStatus.equals("deny") || transactionStatus.equals("expire")) {
// TODO set transaction status on your database to 'failure'
} elseif (transactionStatus.equals("pending")) {
// TODO set transaction status on your database to 'pending' / waiting payment
}
}
returnnewResponseEntity<>(notifResponse, HttpStatus.OK);
}

2.4 Transaction Action

Also available as examples here

Get Status

// get status of transaction that already recorded on midtrans (already `charge`-ed) JSONObjectresult = checkTransaction("YOUR_ORDER_ID OR TRANSACTION_ID");
//do something with `result` JSON Raw Object

Get Status B2B

// get transaction status of VA b2b transactionJSONObjectresult = getTransactionStatusB2B("YOUR_ORDER_ID OR TRANSACTION_ID");
//do something with `result` JSON Raw Object

Approve Transaction

// approve a credit card transaction with `challenge` fraud statusJSONObjectresult = approveTransaction("YOUR_ORDER_ID OR TRANSACTION_ID");
//do something with `result` JSON Raw Object

Deny Transaction

// deny a credit card transaction with `challenge` fraud statusJSONObjectresult = denyTransaction("YOUR_ORDER_ID OR TRANSACTION_ID");
//do something with `result` JSON Raw Object

Cancel Transaction

JSONObjectresult = cancelTransaction("YOUR_ORDER_ID OR TRANSACTION_ID");
//do something with `result` JSON Raw Object

Expire Transaction

JSONObjectresult = expireTransaction("YOUR_ORDER_ID OR TRANSACTION_ID");
//do something with `result` JSON Raw Object

Refund Transaction

//Make params with Map ObjectprivateMap<String,String> params() {
params.put("amount", "5000");
params.put("reason", "Item out of stock");
returnparams;
}
JSONObjectrefundTransaction("YOUR_ORDER_ID OR TRANSACTION_ID", params());
//do something with `result` JSON Raw Object

2.2.D Iris API (Disbursement)

You can see Iris API examples here.

IrisAPI Simple Sample Usage

importcom.midtrans.Config;
importcom.midtrans.ConfigFactory;
importcom.midtrans.service.MidtransIrisApi;
importcom.midtrans.httpclient.error.MidtransError;
importjava.util.HashMap;
importjava.util.Map;
importjava.util.UUID;
importorg.json.JSONObject;
publicclassMidtransIrisExample {
publicstaticvoidmain(String[] args) throwsMidtransError {
MidtransIrisApiirisApi = newConfigFactory(newConfig("IRIS-CREDENTIALS", null, false)).getIrisApi();
Map<String, String> beneficiary = newHashMap<>();
beneficiary.put("bank", "bca");
beneficiary.put("name", "PT Jon Snow");
beneficiary.put("alias_name", "ptjonsnow");
beneficiary.put("account", "1145532134");
beneficiary.put("email", "jonsnow@mail.com");
// Optional - Use idempotency keyirisApi.apiConfig().setIrisIdempotencyKey("Iris-Idempotency-Key");
// Request create beneficiary to Iris APIJSONObjectresult = irisApi.createBeneficiaries(beneficiary);
System.out.println(result);
}
}

Available methods for MidtransIrisApi class

/** * Do re-set config Class iris-credential, IrisIdempotencyKey * * @return {Config class} */ConfigapiConfig();
/** * Do `/ping` Returns pong message for monitoring purpose * * @return {String} - with value Pong * @throws MidtransError when an exception was occurred during executing the request. */Stringping() throwsMidtransError;
/** * Do get `/balance` API request to Use get current balance information. For Aggregator Partner you need to top up to Iris’ bank account. * * @return {JSONObject} - org.json Promise contains Object from JSON decoded response refer to: https://iris-docs.midtrans.com/#check-balance-aggregator * @throws MidtransError when an exception was occurred during executing the request. */JSONObjectgetBalance() throwsMidtransError;
/** * Do create `/beneficiaries` Use this API to create a new beneficiary information for quick access on the payout page in Iris Portal. * * @param params Map Object parameter, object of Core API JSON body as parameter, will be converted to JSON (more params detail refer to: https://iris-docs.midtrans.com/#create-beneficiaries) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response * @throws MidtransError when an exception was occurred during executing the request. */JSONObjectcreateBeneficiaries(Map<String, String> params) throwsMidtransError;
/** * Do update `/beneficiaries/{alias_name}` Use this API to update an existing beneficiary identified by it's `alias_name`. * * @param aliasName Alias name used by the Beneficiary. Length should be less than or equal to 20 characters only alphanumeric characters are allowed * @param params Map Object parameter, object of Core API JSON body as parameter, will be converted to JSON (more params detail refer to: https://iris-docs.midtrans.com/#update-beneficiaries) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response * @throws MidtransError when an exception was occurred during executing the request. */JSONObjectupdateBeneficiaries(StringaliasName, Map<String, String> params) throwsMidtransError;
/** * Do get `/beneficiaries` Use this API to fetch list of all beneficiaries saved in Iris Portal. * * @return {JSONObject} - org.json Promise contains Object from JSON decoded response refer to: https://iris-docs.midtrans.com/#list-beneficiaries * @throws MidtransError when an exception was occurred during executing the request. */JSONArraygetBeneficiaries() throwsMidtransError;
/** * Do create `/payouts` This API is for Creator to create a payout. It can be used for single payout and also multiple payouts. * * @param params Map Object parameter, object of Core API JSON body as parameter, will be converted to JSON (more params detail refer to: https://iris-docs.midtrans.com/#create-payouts) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response * @throws MidtransError when an exception was occurred during executing the request. */JSONObjectcreatePayouts(Map<String, Object> params) throwsMidtransError;
/** * Do approve `/payouts/approve` Use this API for Apporver to approve multiple payout request. * * @param params Map Object parameter, object of Core API JSON body as parameter, will be converted to JSON (more params detail refer to: https://iris-docs.midtrans.com/#approve-payouts) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response * @throws MidtransError when an exception was occurred during executing the request. */JSONObjectapprovePayouts(Map<String, Object> params) throwsMidtransError;
/** * Do reject `/payouts/reject` Use this API for Apporver to reject multiple payout request. * * @param params Map Object parameter, object of Core API JSON body as parameter, will be converted to JSON (more params detail refer to: https://iris-docs.midtrans.com/#reject-payouts) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response * @throws MidtransError when an exception was occurred during executing the request. */JSONObjectrejectPayouts(Map<String, Object> params) throwsMidtransError;
/** * Do get `/payouts/{reference_no}` Use this API for get details of a single payout * * @param referenceNo String parameter, unique reference no of a payout (more params detail refer to: https://iris-docs.midtrans.com/#get-payout-details) * @return {JSONObject} - org.json Promise contains Object from JSON decoded response * @throws MidtransError when an exception was occurred during executing the request. */JSONObjectgetPayoutDetails(StringreferenceNo) throwsMidtransError;
/** * Do get `/statements` Use this API for list all transactions history for a month. You can specified start date and also end date for range transaction history. * * @param fromDate String date parameter, start date range for payouts (YYYY-MM-DD) more params detail refer to: https://iris-docs.midtrans.com/#transaction-history * @param toDate String date parameter, end date range for payouts (YYYY-MM-DD) more params detail refer to: https://iris-docs.midtrans.com/#get-payout-details * @return {JSONObject} - org.json Promise contains Object from JSON decoded response * @throws MidtransError when an exception was occurred during executing the request. */JSONArraygetTransactionHistory(StringfromDate, StringtoDate) throwsMidtransError;
/** * Do get `/channels` Use this API for get top up information channel only for Aggregator Partner * * @return {JSONObject} - org.json Promise contains Object from JSON decoded response (more params detail refer to: https://iris-docs.midtrans.com/#top-up-channel-information-aggregator) * @throws MidtransError when an exception was occurred during executing the request. */JSONArraygetTopUpChannels() throwsMidtransError;
/** * Do get `/bank_accounts` Use this API for show list of registered bank accounts for facilitator partner * * @return {JSONObject} - org.json Promise contains Object from JSON decoded response (more params detail refer to: https://iris-docs.midtrans.com/#bank-accounts-facilitator) * @throws MidtransError when an exception was occurred during executing the request. */JSONArraygetBankAccounts() throwsMidtransError;
/** * Do get `/bank_accounts/{bank_account_id}/balance` For Facilitator Partner, use this API is to get current balance information of your registered bank account. * * @param bankAccountId String Bank Account Number * @return {JSONObject} - org.json Promise contains Object from JSON decoded response refer to: https://iris-docs.midtrans.com/#check-balance-facilitator * @throws MidtransError when an exception was occurred during executing the request. */JSONObjectgetFacilitatorBalance(StringbankAccountId) throwsMidtransError;
/** * Do get `/beneficiary_banks` Use this API for show list of supported banks in IRIS. https://iris-docs.midtrans.com/#supported-banks * * @return {JSONObject} - org.json Promise contains Object from JSON decoded response (more params detail refer to: https://iris-docs.midtrans.com/#list-banks) * @throws MidtransError when an exception was occurred during executing the request. */JSONObjectgetBeneficiaryBanks() throwsMidtransError;
/** * Do validate `/account_validation` Use this API for check if an account is valid, if valid return account information. * * @param bank String bank code * @param account String Account number * @return {JSONObject} - org.json Promise contains Object from JSON decoded response (more params detail refer to: https://iris-docs.midtrans.com/#validate-bank-account) * @throws MidtransError when an exception was occurred during executing the request. */JSONObjectvalidateBankAccount(Stringbank, Stringaccount) throwsMidtransError;

3. Snap-BI (*NEW FEATURE starting v3.2.0)

Standar Nasional Open API Pembayaran, or in short SNAP, is a national payment open API standard published by Bank Indonesia. To learn more you can read this docs

3.1 General Settings

//These config value are based on the header stated here https://docs.midtrans.com/reference/getting-started-1// Set to Development/Sandbox Environment (default). Set to true for Production Environment (accept real transaction).SnapBiConfig.setProduction(true);
// Set your client id. Merchant’s client ID that will be given by Midtrans, will be used as X-CLIENT-KEY on request’s header in B2B Access Token API.SnapBiConfig.setSnapBiClientId("YOUR CLIENT ID");
// Set your private key here, make sure to add \n on the private key, you can refer to the examplesSnapBiConfig.setSnapBiPrivateKey("YOUR PRIVATE KEY");
// Set your client secret. Merchant’s secret key that will be given by Midtrans, will be used for symmetric signature generation for Transactional API’s header.SnapBiConfig.setSnapBiClientSecret("YOUR CLIENT SECRET");
// Set your partner id. Merchant’s partner ID that will be given by Midtrans, will be used as X-PARTNER-ID on Transactional API’s header.SnapBiConfig.setSnapBiPartnerId("YOUR PARTNER ID");
// Set the channel id here.SnapBiConfig.setSnapBiChannelId("YOUR CHANNEL ID");
// Enable logging to see details of the request/response make sure to disable this on production, the default is disabled.SnapBiConfig.setEnableLogging(true);
// Set your public key here if you want to verify your webhook notification, make sure to add \n on the public key, you can refer to the examplesSnapBiConfig.setSnapBiPublicKey("YOUR PUBLIC KEY");

3.2 Create Payment

3.2.1 Direct Debit (Gopay, Dana, Shopeepay)

Refer to this docs for more detailed information about creating payment using direct debit.

// Create the top-level map of request bodypublicMap<String, Object> createDirectDebitRequestBody() {
// Create the top-level mapMap<String, Object> requestBody = newHashMap<>();
// Add partnerReferenceNo and other fieldsrequestBody.put("partnerReferenceNo", externalId);
requestBody.put("chargeToken", "");
requestBody.put("merchantId", merchantId);
requestBody.put("validUpTo", "2030-07-20T20:34:15.452305Z");
// Create and add urlParam mapMap<String, String> urlParam = newHashMap<>();
urlParam.put("url", "https://midtrans-test.com/api/notification");
urlParam.put("type", "PAY_RETURN");
urlParam.put("isDeeplink", "N");
requestBody.put("urlParam", urlParam);
// Create and add payOptionDetails listList<Map<String, Object>> payOptionDetails = newArrayList<>();
Map<String, Object> payOptionDetail = newHashMap<>();
payOptionDetail.put("payMethod", "GOPAY");
payOptionDetail.put("payOption", "GOPAY_WALLET");
// Create and add transAmount mapMap<String, String> transAmount = newHashMap<>();
transAmount.put("value", "1500");
transAmount.put("currency", "IDR");
payOptionDetail.put("transAmount", transAmount);
payOptionDetails.add(payOptionDetail);
requestBody.put("payOptionDetails", payOptionDetails);
// Create and add additionalInfo mapMap<String, Object> additionalInfo = newHashMap<>();
// Create and add customerDetails mapMap<String, Object> customerDetails = newHashMap<>();
customerDetails.put("firstName", "Merchant");
customerDetails.put("lastName", "Operation");
customerDetails.put("email", "merchant-ops@midtrans.com");
customerDetails.put("phone", "+6281932358123");
// Create and add billingAddress mapMap<String, String> billingAddress = newHashMap<>();
billingAddress.put("firstName", "Merchant");
billingAddress.put("lastName", "Operation");
billingAddress.put("phone", "+6281932358123");
billingAddress.put("address", "Pasaraya Blok M");
billingAddress.put("city", "Jakarta");
billingAddress.put("postalCode", "12160");
billingAddress.put("countryCode", "IDN");
customerDetails.put("billingAddress", billingAddress);
// Create and add shippingAddress mapMap<String, String> shippingAddress = newHashMap<>();
shippingAddress.put("firstName", "Merchant");
shippingAddress.put("lastName", "Operation");
shippingAddress.put("phone", "+6281932358123");
shippingAddress.put("address", "Pasaraya Blok M");
shippingAddress.put("city", "Jakarta");
shippingAddress.put("postalCode", "12160");
shippingAddress.put("countryCode", "IDN");
customerDetails.put("shippingAddress", shippingAddress);
additionalInfo.put("customerDetails", customerDetails);
// Create and add items listList<Map<String, Object>> items = newArrayList<>();
Map<String, Object> item = newHashMap<>();
item.put("id", "8143fc4f-ec05-4c55-92fb-620c212f401e");
// Create and add price mapMap<String, String> price = newHashMap<>();
price.put("value", "1500.00");
price.put("currency", "IDR");
item.put("price", price);
item.put("quantity", 1);
item.put("name", "test item name");
item.put("brand", "test item brand");
item.put("category", "test item category");
item.put("merchantName", "Merchant Operation");
items.add(item);
additionalInfo.put("items", items);
requestBody.put("additionalInfo", additionalInfo);
returnrequestBody;
}
/** * Basic example * to change the payment method, you can change the value of the request body on the `payOptionDetails` * the `currency` value that we support for now is only `IDR` */JSONObjectsnapBiResponse1 = SnapBi.directDebit()
.withBody(createDirectDebitRequestBody)
.createPayment(externalId);

3.2.2 VA (Bank Transfer)

Refer to this docs for more detailed information about VA/Bank Transfer.

//function to create request bodypublicMap<String, Object> createVaRequestBody() {
// Create the top-level mapMap<String, Object> requestBody = newHashMap<>();
// Create and add transAmount mapMap<String, Object> totalAmount = newHashMap<>();
totalAmount.put("value", "1500.00");
totalAmount.put("currency", "IDR");
requestBody.put("totalAmount", totalAmount);
Map<String, Object> flags = newHashMap<>();
flags.put("shouldRandomizeVaNumber", true);
Map<String, Object> billingAddress = newHashMap<>();
billingAddress.put("firstName", "Merchant");
billingAddress.put("lastName", "Operation");
billingAddress.put("phone", "+6281932358123");
billingAddress.put("address", "Pasaraya Blok M");
billingAddress.put("city", "Jakarta");
billingAddress.put("postalCode", "12160");
billingAddress.put("countryCode", "IDN");
Map<String, Object> shippingAddress = newHashMap<>();
shippingAddress.put("firstName", "Merchant");
shippingAddress.put("lastName", "Operation");
shippingAddress.put("phone", "6281932358123");
shippingAddress.put("address", "Pasaraya Blok M");
shippingAddress.put("city", "Jakarta");
shippingAddress.put("postalCode", "12160");
shippingAddress.put("countryCode", "IDN");
Map<String, Object> customerDetails = newHashMap<>();
customerDetails.put("firstName", "Merchant");
customerDetails.put("lastName", "Operation");
customerDetails.put("email", "merchant-ops@midtrans.com");
customerDetails.put("phone", "+6281932358123");
customerDetails.put("billingAddress", billingAddress);
customerDetails.put("shippingAddress", shippingAddress);
List<Map<String, Object>> items = newArrayList<>();
Map<String, Object> item = newHashMap<>();
item.put("id", "8143fc4f-ec05-4c55-92fb-620c212f401e");
// Create and add price mapMap<String, Object> price = newHashMap<>();
price.put("value", "1500.00");
price.put("currency", "IDR");
item.put("price", price);
item.put("quantity", 1);
item.put("name", "test item name");
item.put("brand", "test item brand");
item.put("category", "test item category");
item.put("merchantName", "Merchant Operation");
items.add(item);
Map<String, Object> additionalInfo = newHashMap<>();
additionalInfo.put("merchantId", merchantId);
additionalInfo.put("bank", "bca");
additionalInfo.put("flags", flags);
additionalInfo.put("customerDetails", customerDetails);
additionalInfo.put("shippingAddress", shippingAddress);
additionalInfo.put("billingAddress", billingAddress);
additionalInfo.put("items", items);
requestBody.put("partnerServiceId", " 1234");
requestBody.put("customerNo", "0000000000");
requestBody.put("virtualAccountNo", " 12340000000000");
requestBody.put("virtualAccountName", "Merchant Operation");
requestBody.put("virtualAccountEmail", "merchant-ops@midtrans.com");
requestBody.put("virtualAccountPhone", "6281932358123");
requestBody.put("trxId", externalId);
requestBody.put("additionalInfo", additionalInfo);
returnrequestBody;
}
/** * basic implementation to create payment using va */JSONObjectsnapBiResponse1 = SnapBi.va()
.withBody(createVaRequestBody())
.createPayment(externalId);

3.2.3 Qris

Refer to this docs for more detailed information about Qris.

//function to create the request bodypublicstaticMap<String, Object> createQrisRequestBody() {
// Create the top-level mapMap<String, Object> requestBody = newHashMap<>();
// Add partnerReferenceNo and other fieldsrequestBody.put("partnerReferenceNo", externalId);
requestBody.put("merchantId", merchantId);
requestBody.put("validityPeriod", "2030-07-03T12:08:56-07:00");
// Create and add amount mapMap<String, String> amount = newHashMap<>();
amount.put("value", "1500.00");
amount.put("currency", "IDR");
requestBody.put("amount", amount);
// Create and add additionalInfo mapMap<String, Object> additionalInfo = newHashMap<>();
// Create and add customerDetails mapMap<String, Object> customerDetails = newHashMap<>();
customerDetails.put("firstName", "Merchant");
customerDetails.put("lastName", "Operation");
customerDetails.put("email", "merchant-ops@midtrans.com");
customerDetails.put("phone", "+6281932358123");
additionalInfo.put("customerDetails", customerDetails);
// Create and add items listList<Map<String, Object>> items = newArrayList<>();
Map<String, Object> item = newHashMap<>();
item.put("id", "8143fc4f-ec05-4c55-92fb-620c212f401e");
// Create and add price mapMap<String, String> price = newHashMap<>();
price.put("value", "1500.00");
price.put("currency", "IDR");
item.put("price", price);
item.put("quantity", 1);
item.put("name", "test item name");
item.put("brand", "test item brand");
item.put("category", "test item category");
item.put("merchantName", "Merchant Operation");
items.add(item);
additionalInfo.put("items", items);
additionalInfo.put("acquirer", "gopay");
additionalInfo.put("customerDetails", customerDetails);
additionalInfo.put("countryCode", "ID");
additionalInfo.put("locale", "id_ID");
requestBody.put("additionalInfo", additionalInfo);
returnrequestBody;
}
/** * basic implementation to create payment using Qris */JSONObjectsnapBiResponse1 = SnapBi.qris()
.withBody(createQrisRequestBody())
.createPayment(externalId);

3.4 Get Transaction Status

Refer to this docs for more detailed information about getting the transaction status.

publicstaticMap<String, Object> createDirectDebitStatusByReferenceNoBody
() {
// Create the top-level mapMap<String, Object> requestBody = newHashMap<>();
requestBody.put("originalReferenceNo", "A1202409230511097Hmk31oa4UID");
requestBody.put("serviceCode", "54");
requestBody.put("originalExternalId", "b8cc77cd-64c2-4edb-b083-39a320f67c06");
returnrequestBody;
}
publicstaticMap<String, Object> createDirectDebitStatusByExternalIdBody
() {
// Create the top-level mapMap<String, Object> requestBody = newHashMap<>();
requestBody.put("originalExternalId", "uzi-order-testing66ce90ce90ee5");
requestBody.put("serviceCode", "54");
returnrequestBody;
}
publicstaticMap<String, String > createAdditionalHeader(){
Map<String, String> headers = newHashMap<>();
headers.put("X-Device-id", "device id");
headers.put("debug-id", "debug id");
returnheaders;
}
publicstaticMap<String, Object> createVaStatusBody
() {
// Create the top-level mapMap<String, Object> additionalInfo = newHashMap<>();
additionalInfo.put("merchantId", merchantId);
Map<String, Object> requestBody = newHashMap<>();
requestBody.put("partnerServiceId", " 1234");
requestBody.put("customerNo", "083430");
requestBody.put("virtualAccountNo", " 1234083430");
requestBody.put("inquiryRequestId", "4b1da710-fbf5-425e-9648-06e40b290326");
requestBody.put("additionalInfo", additionalInfo);
returnrequestBody;
}
/** * Example code for Direct Debit getStatus using externalId */JSONObjectsnapBiResponse1 = SnapBi.directDebit()
.withBody(createDirectDebitStatusByReferenceNoBody())
.getStatus(externalId);
/** * Example code for Direct Debit getStatus using referenceNo */JSONObjectsnapBiResponse4 = SnapBi.directDebit()
.withBody(createDirectDebitStatusByReferenceNoBody())
.getStatus(externalId);
/** * Example code for VA (Bank Transfer) getStatus */JSONObjectsnapBiResponse7 = SnapBi.va()
.withBody(createVaStatusBody())
.getStatus(externalId);
/** *  * Example code for Qris getStatus */JSONObjectsnapBiResponse10 = SnapBi.qris()
.withBody(createVaStatusBody())
.getStatus(externalId); 

3.5 Cancel Transaction

Refer to this docs for more detailed information about cancelling the payment.

publicstaticMap<String, Object> createDirectDebitCancelByExternalIdBody
() {
// Create the top-level mapMap<String, Object> requestBody = newHashMap<>();
requestBody.put("originalExternalId", "67be74c3-8cf5-4af3-b62b-0715899fd713");
returnrequestBody;
}
publicstaticMap<String, Object> createDirectCancelByReferenceNoBody
() {
// Create the top-level mapMap<String, Object> requestBody = newHashMap<>();
requestBody.put("originalReferenceNo", "A12024092305243239N7MuWlDCID");
returnrequestBody;
}
publicstaticMap<String, Object> createVaCancelBody
() {
// Create the top-level mapMap<String, Object> additionalInfo = newHashMap<>();
additionalInfo.put("merchantId", merchantId);
Map<String, Object> requestBody = newHashMap<>();
requestBody.put("partnerServiceId", " 1234");
requestBody.put("customerNo", "741633");
requestBody.put("virtualAccountNo", " 1234741633");
requestBody.put("trxId", "02a9c5a3-e088-45de-8688-424b5f65c927");
requestBody.put("additionalInfo", additionalInfo);
returnrequestBody;
}
publicstaticMap<String, Object> createQrisCancelBody
() {
// Create the top-level mapMap<String, Object> requestBody = newHashMap<>();
requestBody.put("originalReferenceNo", "A120240923112046EjKURlq1QqID");
requestBody.put("merchantId", merchantId);
requestBody.put("reason", "cancel reason");
returnrequestBody;
}
/** * Basic implementation to cancel transaction using referenceNo */JSONObjectsnapBiResponse1 = SnapBi.directDebit()
.withBody(createDirectCancelByReferenceNoBody())
.cancel(externalId);
/** * Basic implementation to cancel transaction using externalId */JSONObjectsnapBiResponse4 = SnapBi.directDebit()
.withBody(createDirectDebitCancelByExternalIdBody())
.cancel(externalId);
/** * Basic implementation of VA (Bank Transfer) to cancel transaction */JSONObjectsnapBiResponse7 = SnapBi.va()
.withBody(createVaCancelBody())
.cancel(externalId);
/** * Basic implementation of Qris to cancel transaction */JSONObjectsnapBiResponse10 = SnapBi.qris()
.withBody(createQrisCancelBody())
.cancel(externalId);

3.6 Refund Transaction

Refer to this docs for more detailed information about refunding the payment.

publicstaticMap<String, Object> createDirectDebitRefundByExternalIdBody() {
// Create the top-level mapMap<String, Object> refundAmount = newHashMap<>();
refundAmount.put("value", "100.00");
refundAmount.put("currency", "IDR");
Map<String, Object> requestBody = newHashMap<>();
requestBody.put("originalExternalId", "9d18b81c-485c-4b67-a308-7cc060dc202e");
requestBody.put("partnerRefundNo", "9d18b81c-485c-4b67-a308-7cc060dc202e refund-0001");
requestBody.put("reason", "some-reason");
requestBody.put("refundAmount", refundAmount);
returnrequestBody;
}
publicstaticMap<String, Object> createDirectDebitRefundByReferenceNoBody() {
// Create the top-level mapMap<String, Object> refundAmount = newHashMap<>();
refundAmount.put("value", "100.00");
refundAmount.put("currency", "IDR");
Map<String, Object> requestBody = newHashMap<>();
requestBody.put("originalReferenceNo", "A1202409230511097Hmk31oa4UID");
requestBody.put("reason", "some-reason");
requestBody.put("refundAmount", refundAmount);
returnrequestBody;
}
publicstaticMap<String, Object> createQrisRefundBody() {
Map<String, Object> refundAmount = newHashMap<>();
refundAmount.put("value", "100.00");
refundAmount.put("currency", "IDR");
Map<String, Object> additionalInfo = newHashMap<>();
additionalInfo.put("foo", "bar");
Map<String, Object> requestBody = newHashMap<>();
requestBody.put("merchantId", merchantId);
requestBody.put("originalPartnerReferenceNo", "uzi-order-testing66e01a9b8c6bf");
requestBody.put("originalReferenceNo", "A120240923082857KzdNmUKObJID");
requestBody.put("partnerRefundNo", "refund-abc123456");
requestBody.put("reason", "some-reason");
requestBody.put("refundAmount", refundAmount);
requestBody.put("additionalInfo", additionalInfo);
returnrequestBody;
}
/** * Example code for refund using externalId */JSONObjectsnapBiResponse4 = SnapBi.directDebit()
.withBody(createDirectDebitRefundByExternalIdBody())
.refund(externalId);
/** * Example code for refund using reference no */JSONObjectsnapBiResponse1 = SnapBi.directDebit()
.withBody(createDirectDebitRefundByReferenceNoBody())
.refund(externalId);
/** * Example code for refund using Qris */JSONObjectsnapBiResponse7 = SnapBi.qris()
.withBody(createQrisRefundBody())
.refund(externalId);

3.7 Adding additional header / override the header

You can add or override the header value, by utilizing the withAccessTokenHeader or withTransactionHeader method chain. Refer to this docs to see the header value required by Snap-Bi , and see the default header on each payment method

//function to create the additional headerpublicstaticMap<String, String > createAdditionalHeader(){
Map<String, String> headers = newHashMap<>();
headers.put("X-Device-id", "device id");
headers.put("debug-id", "debug id");
returnheaders;
}
/** * Example code for Direct Debit refund using additional header */SONObjectsnapBiResponse3 = SnapBi.directDebit()
.withBody(createDirectDebitRequestBody())
.withAccessTokenHeader(createAdditionalHeader())
.withTransactionHeader(createAdditionalHeader())
.createPayment(externalId);
/** * Example code for using additional header on creating payment using VA */JSONObjectsnapBiResponse3 = SnapBi.va()
.withBody(createVaRequestBody())
.withAccessTokenHeader(createAdditionalHeader())
.withTransactionHeader(createAdditionalHeader())
.createPayment(externalId);

3.8 Reusing Access Token

If you've saved your previous access token and wanted to re-use it, you can do it by utilizing the .withAccessToken().

/** * Example reusing your existing accessToken by using .withAccessToken() */JSONObjectsnapBiResponse2 = SnapBi.va()
.withBody(createVaRequestBody())
.withAccessToken("your access token")
.createPayment(externalId);

3.9 Payment Notification

To implement Snap-Bi Payment Notification you can refer to this docs To verify the webhook notification that you recieve you can use this method below

//the request body/ payload sent by the webhookStringnotificationPayload = "{\"originalPartnerReferenceNo\":\"GP24043015193402809\",\"originalReferenceNo\":\"A120240430081940S9vu8gSjaRID\",\"merchantId\":\"G099333790\",\"amount\":{\"value\":\"102800.00\",\"currency\":\"IDR\"},\"latestTransactionStatus\":\"00\",\"transactionStatusDesc\":\"SUCCESS\",\"additionalInfo\":{\"refundHistory\":[]}}"; // Sample notification body, replace with actual data you receive from Midtrans// to get the signature value, you need to retrieve it from the webhook header called X-SignatureStringsignature = "CgjmAyC9OZ3pB2JhBRDihL939kS86LjP1VLD1R7LgI4JkvYvskUQrPXgjhrZqU2SFkfPmLtSbcEUw21pg2nItQ0KoX582Y6Tqg4Mn45BQbxo4LTPzkZwclD4WI+aCYePQtUrXpJSTM8D32lSJQQndlloJfzoD6Rh24lNb+zjUpc+YEi4vMM6MBmS26PpCm/7FZ7/OgsVh9rlSNUsuQ/1QFpldA0F8bBNWSW4trwv9bE1NFDzliHrRAnQXrT/J3chOg5qqH0+s3E6v/W21hIrBYZVDTppyJPtTOoCWeuT1Tk9XI2HhSDiSuI3pevzLL8FLEWY/G4M5zkjm/9056LTDw==";
// to get the timeStamp value, you need to retrieve it from the webhook header called X-TimestampStringtimeStamp = "2024-10-07T15:45:22+07:00";
// the url path is based on the webhook url of the payment method for example for direct debit is `/v1.0/debit/notify`StringnotificationUrlPath = "/v1.0/debit/notify";
/** * Example verifying the webhook notification */BooleanisVerified = SnapBi.notification()
.withNotificationPayload(notificationPayload)
.withSignature(signature)
.withTimeStamp(timeStamp)
.withNotificationUrlPath(notificationUrlPath)
.isWebhookNotificationVerified();

4. Examples

Examples are available on /examples folder There are:

Get help

About

This is the Official Java API client/library for Midtrans Payment API. Visit https://midtrans.com. More information about the product and see documentation at http://docs.midtrans.com for more technical details

Topics

Resources

Stars

37 stars

Watchers

8 watching

Forks

Releases

Packages

Used by

Contributors

Languages