Download

Veritrans - Java Client Documentation

This is the official Java Client for Veritrans Payment API.

Please visit https://www.veritrans.co.id for more information about the products and see the documentations at http://docs.veritrans.co.id for more technical details. We also have a few sequence diagrams which can help you to understands the big picture of our various payment methods process flow.


Installation

Maven

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

<repositories>
    <repository>
        <id>jcenter</id>
        <name>bintray</name>
        <url>http://jcenter.bintray.com</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>id.co.veritrans</groupId>
        <artifactId>vt-java-client</artifactId>
        <version>1.2.1</version>
    </dependency>
</dependencies>

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

repositories {
    maven {
        url  "http://jcenter.bintray.com" 
    }
}

dependencies {
    compile 'id.co.veritrans:vt-java-client:1.2.1'
}

Jar Library

If you want to download veritrans java-client jar library on your own, you can download it directly here

Usage

VtGatewayConfig

VtGatewayConfig stores the settings that is needed by the Veritrans-Java Client to properly accessing the Veritrans Payment API. Please note that every classes related with VtGatewayConfig is immutable by design. However a builder class is provided to aid the object creation.

See VtGatewayConfig Javadoc. See VtGatewayConfigBuilder Javadoc. See id.co.veritrans.mdk.v1.config Javadoc

Server & Client Key

You must set the Server Key and Client Key as defined in your Merchant Administration Portal (MAP).

VtGatewayConfigBuilder vtGatewayConfigBuilder = new VtGatewayConfigBuilder();
vtGatewayConfigBuilder.setServerKey("Your Server Key");
vtGatewayConfigBuilder.setClientKey("Your Client Key");

Environment

You can choose to use Sandbox or Production environment. During development & testing, you might want to set it to Sandbox and use the Production environment when you're ready to go live.

See EnvironmentType Javadoc.

// config for sandbox environment
vtGatewayConfigBuilder.setEnvironmentType(EnvironmentType.SANDBOX);

// config for production environment
vtGatewayConfigBuilder.setEnvironmentType(EnvironmentType.PRODUCTION);


Connection Pool Size

Veritrans-Java Client is designed to use a HTTP Connection Pool to maintain it's HTTP Connection to Veritrans Server, thus we can take benefit from the HTTP Keep Alive feature and reuse the connection. In order to support this functionality, a connection pool size need to be set explicitly, to accomodate the needs of every different companies.
We recommend to set maximum HTTP Connection Pool Size to 16, however it is up to you to set it to a lower or higher value. Do remember that a too low or too high value could degrade the system performance.

httpConfigBuilder.setMaxConnectionPoolSize(16);
vtGatewayConfigBuilder.setHttpConfig(httpConfigBuilder.createHttpConfig());


Proxy Configuration

You can setup proxy configuration if you need connect to Veritrans Payment API through proxy server.
See ProxyConfig Javadoc
See ProxyConfigBuilder Javadoc

// this demonstrate configuring proxy settings using method chaining from the builder class
ProxyConfigBuilder proxyConfigBuilder = new ProxyConfigBuilder();

vtGatewayConfigBuilder.setProxyConfig(
    proxyConfigBuilder.setHost("proxy host address")
        .setPort(12345)
        .setUsername("proxy username or null")
        .setPassword("proxy password or null")
        .createProxyConfig()
).createVtGatewayConfig();
// this demonstrate configuring proxy settings without method chaining
ProxyConfigBuilder proxyConfigBuilder = new ProxyConfigBuilder();
proxyConfigBuilder.setHost("proxy host address");
proxyConfigBuilder.setPort(12345);
proxyConfigBuilder.setUsername("proxy username or null");
proxyConfigBuilder.setPassword("proxy password or null");

ProxyConfig proxyConfig = proxyConfigBuilder.createProxyConfig();
vtGatewayConfigBuilder.setProxyConfig(proxyConfig);


Connect and Socket Timeout Configuration

You can setup the http connect and socket timeout configuration manually. The default value is 5000 ms for connect timeout and 30000 ms for socket timeout

/* Value is on milisecond (ms) */
vtGatewayConfigBuilder.setConnectTimeout(10000)
                      .setSocketTimeout(20000);


VtGatewayFactory

VtGatewayFactory is a factory class which is used to obtain a reference to various Veritrans Product interface instance, eg: VtDirect instance. This class is also responsible as a manager for every Veritrans Product interface instance returned by the instance of this class. Normally you will make a single instance of VtGatewayFactory class and maintain the reference to this instance, then use it whenever you need to obtain a reference to a Veritrans Product interface. Some instance of Veritrans Product interface instance returned by this class maybe safe to be cached, such as: VtDirect and VtWeb.

If you need to have multiple VtGatewayFactory with different configuration profiles, consider to make a VtGatewayFactory instance for each configuration profile and reuse that VtGatewayFactory instance to obtain reference to Veritrans Product interface instances.
See VtGatewayFactory Javadoc

Example code to build a VtGatewayFactory:

VtGatewayConfig vtGatewayConfig = vtGatewayConfigBuilder.createVtGatewayConfig();
VtGatewayFactory vtGatewayFactory = new VtGatewayFactory(vtGatewayConfig);


VtDirect

VtDirect is an interface class, where it's instance can be used to communicate with Veritrans Payment API. VtDirect instance is safe to share with multiple threads, hence you can safely cache the instance of this class and reuse it multiple times.

See VtDirect Javadoc.
Example code to obtain reference to VtDirect instance:

VtDirect vtDirect = vtGatewayFactory.vtDirect();

Charging a transaction

VtDirect has method named charge which takes an instance of VtDirectChargeRequest subclass as the parameter. This method will make a charge request to Veritrans Payment API and return a VtResponse as a result, which can be used to determine the status of the transaction.

See VtDirectChargeRequest
See VtResponse
Visit http://docs.veritrans.co.id/en/api/methods.html#Charge for more information.

VtDirectChargeRequest

VtDirectChargeRequest has specific subclass for a specific payment method, ex: for Credit Card payment method, there is a subclass named CreditCardRequest. The list of currently supported payment methods:

See id.co.veritrans.mdk.gateway.model Javadoc
See id.co.veritrans.mdk.gateway.model.vtdirect Javadoc

It is recommended to have a single method to configure the generic VtDirectChargeRequest values. Example for Credit Card charge:

...
// somewhere in the code
CreditCardRequest vtDirectChargeRequest = new CreditCardRequest();
setVtDirectChargeRequestValues(vtDirectChargeRequest);
// continue processing
...

/**
 * This method is just for example.
 * The actual values should be obtained from another sources.
 */
public void setVtDirectChargeRequestValues(VtDirectChargeRequest vtDirectChargeRequest) {
    vtDirectChargeRequest.setTransactionDetails(new TransactionDetails());
    vtDirectChargeRequest.setCustomerDetails(new CustomerDetails());

    vtDirectChargeRequest.getTransactionDetails().setOrderId("your unique order ID");
    vtDirectChargeRequest.getTransactionDetails().setGrossAmount(10000l);

    vtDirectChargeRequest.getCustomerDetails().setEmail("user@domain.com");
    vtDirectChargeRequest.getCustomerDetails().setFirstName("firstName");
    vtDirectChargeRequest.getCustomerDetails().setPhone("0123456789");
    vtDirectChargeRequest.getCustomerDetails().setBillingAddress(new Address());

    Address billingAddress = vtDirectChargeRequest.getCustomerDetails().getBillingAddress();
    billingAddress.setAddress("Random Street 6A");
    billingAddress.setCity("Jakarta Pusat");
    billingAddress.setPostalCode("12210");
}


Bank Transfer

See BankTransfer Javadoc
See Bank Transfer Process Flow

BankTransferRequest vtDirectChargeRequest = new BankTransferRequest();
setVtDirectChargeRequestValues(vtDirectChargeRequest);
vtDirectChargeRequest.setBankTransfer(new BankTransfer());

vtDirectChargeRequest.getBankTransfer().setBank(BankTransfer.Bank.PERMATA);

VtResponse vtResponse = vtDirect.charge(vtDirectChargeRequest);

if (vtResponse.getStatusCode().equals("200") &&
    vtResponse.getTransactionStatus() == TransactionStatus.PENDING) {

    // handle successful Bank Transfer charge request
    // check the permataVaNumber in the vtResponse
} else {
    // handle denied / unexpected response
}


Bri Epay

BriEpayRequest vtDirectChargeRequest = new BriEpayRequest();
setVtDirectChargeRequestValues(vtDirectChargeRequest);

VtResponse vtResponse = vtDirect.charge(vtDirectChargeRequest);

if (vtResponse.getStatusCode().equals("200") &&
    vtResponse.getTransactionStatus() == TransactionStatus.PENDING) {

    // handle successful Bank Transfer charge request
    // check the redirectUrl value in the vtResponse (redirect the customer to the redirectUrl to continue the payment process)
} else {
    // handle denied / unexpected response
}


Cimb Clicks

See CimbClicks Javadoc

CimbClicksRequest vtDirectChargeRequest = new CimbClicksRequest();
setVtDirectChargeRequestValues(vtDirectChargeRequest);
vtDirectChargeRequest.setCimbClicks(new CimbClicks());

vtDirectChargeRequest.getCimbClicks().setDescription("Payment for Merchant XYZ");

VtResponse vtResponse = vtDirect.charge(vtDirectChargeRequest);

if (vtResponse.getStatusCode().equals("200") &&
    vtResponse.getTransactionStatus() == TransactionStatus.PENDING) {

    // handle successful Cimb Clicks charge request
    // check the redirectUrl value in the vtResponse (redirect the customer to the redirectUrl to continue the payment process)
} else {
    // handle denied / unexpected response
}


Credit Card (One-Time Tokenization)

See CreditCard Javadoc
See CreditCard Process Flow Without 3D Secure Authentication
See CreditCard Process Flow With 3D Secure Authentication

Every Credit Card transaction must use a Token generated by Veritrans Payment API instead of using plain card number. Please visit Acquiring Credit Card Token for further information.

CreditCardRequest vtDirectChargeRequest = new CreditCardRequest();
setVtDirectChargeRequestValues(vtDirectChargeRequest);

CreditCard creditCard = new CreditCardBuilder()
    .setTokenId("creditCardToken")          // token is obtained from HTTP POST variable.
    .setAcquirerBank(CreditCard.Bank.BNI)   // your acquirer bank for Credit Card
    .setFraudSector("fraud sector")         // merchant fraud sector (applicable only for several merchant) 
    .createCreditCard(); 

vtDirectChargeRequest.setCreditCard(creditCard);

VtResponse vtResponse = vtDirect.charge(vtDirectChargeRequest);

if (vtResponse.getStatusCode().equals("200") &&
    vtResponse.getTransactionStatus() == TransactionStatus.CAPTURED &&
    vtResponse.getFraudStatus() == FraudStatus.ACCEPTED) {

    // handle successful capture
} else if (vtResponse.getStatusCode().equals("201") &&
    vtResponse.getTransactionStatus() == TransactionStatus.CAPTURED &&
    vtResponse.getFraudStatus() == FraudStatus.CHALLENGE) {

    // handle FDS challenge (you can do this later)
} else {
    // handle denied / unexpected response
}


Credit Card (Full PAN)

Only allowed for certain merchant
For PCIDSS compliance merchant, it able to charge credit card transaction using customer credit card data instead of using token.

String IS_USE_3DS = true;
CreditCardFullPanRequest vtDirectChargeRequest = new CreditCardFullPanRequest();
setVtDirectChargeRequestValues(vtDirectChargeRequest);

CreditCardFullPan creditCardFullPan = new CreditCardFullPan("5410111111111116", "123", "01", "2020", IS_USE_3DS);
vtDirectChargeRequest.setCreditCardFullPan(creditCardFullPan);

VtResponse vtResponse = vtDirect.charge(vtDirectChargeRequest);

if vtResponse.getStatusCode().equals("201") {

    // handle successful request, redirect user to redirect_url
    // vtResponse.getRedirectUrl();
} else {

    // handle denied / unexpected response
}


Mandiri Clickpay

See MandiriClickpay Javadoc
Visit Veritrans Mandiri Clickpay Documentation for more information.

MandiriClickpayRequest vtDirectChargeRequest = new MandiriClickpayRequest();
setVtDirectChargeRequestValues(vtDirectChargeRequest);
vtDirectChargeRequest.setMandiriClickpay(new MandiriClickpay());

vtDirectChargeRequest.getMandiriClickpay().setCardNumber("4111111111111111");
vtDirectChargeRequest.getMandiriClickpay().setInput1("111111111");
vtDirectChargeRequest.getMandiriClickpay().setInput2("10000");
vtDirectChargeRequest.getMandiriClickpay().setInput3("54321");
vtDirectChargeRequest.getMandiriClickpay().setToken("000000");

VtResponse vtResponse = vtDirect.charge(vtDirectChargeRequest);

if (vtResponse.getStatusCode().equals("200") &&
    vtResponse.getTransactionStatus() == TransactionStatus.SETTLED) {

    // handle successful Mandiri Clickpay charge request
} else {
    // handle denied / unexpected response
}


BCA KlikPay

See BcaKlikpay Javadoc

BcaKlikpayRequest vtDirectChargeRequest = new BcaKlikpayRequest();
setVtDirectChargeRequestValues(vtDirectChargeRequest);
vtDirectChargeRequest.setBcaKlikpay(new BcaKlikpay());

vtDirectChargeRequest.getBcaKlikpay().setType(1);
vtDirectChargeRequest.getBcaKlikpay().setMiscFee(10000L);
vtDirectChargeRequest.getBcaKlikpay().setDescription("Product X");

VtResponse vtResponse = vtDirect.charge(vtDirectChargeRequest);

if (vtResponse.getStatusCode().equals("200") &&
    vtResponse.getTransactionStatus() == TransactionStatus.PENDING) {

    // handle successful  BCA Klikpay charge request
    // check the redirectUrl value in the vtResponse (redirect the customer to the redirectUrl to continue the payment process)
} else {
    // handle denied / unexpected response
}


Klik BCA

See Klik BCA Javadoc

KlikBcaRequest vtDirectChargeRequest = new KlikBcaRequest();
setVtDirectChargeRequestValues(vtDirectChargeRequest);
vtDirectChargeRequest.setKlikBca(new KlikBca());

vtDirectChargeRequest.getKlikBca().setUserId("user ID");
vtDirectChargeRequest.getKlikBca().setDescription("Transaction description");

VtResponse vtResponse = vtDirect.charge(vtDirectChargeRequest);

if (vtResponse.getStatusCode().equals("200") &&
    vtResponse.getTransactionStatus() == TransactionStatus.PENDING) {

    // handle successful  BCA Klikpay charge request
    // show instruction to customer on how to pay with klikbca
} else {
    // handle denied / unexpected response
}


VtWeb

VtWeb is an interface class, where it's instance can be used to communicate with Veritrans Payment API, but VtWeb charge functionality will be responded with redirect url which is used to redirect customers to Veritrans's Payment Page. VtWeb instance is safe to share with multiple threads, hence you can safely cache the instance of this class and reuse it multiple times.

See VtWeb Javadoc.
Example code to obtain reference to VtWeb instance:

VtWeb vtWeb = vtGatewayFactory.vtWeb();


Charging a transaction

VtWebChargeRequest vtWebChargeRequest = new VtWebChargeRequest();
setVtWebChargeRequestValues(vtWebChargeRequest);
vtWebChargeRequest.setVtWeb(new VtWebParam());
vtWebChargeRequest.getVtWeb().setCreditCardUse3dSecure(true);

VtResponse vtResponse = vtWeb.charge(vtWebChargeRequest);
if (vtResponse.getStatusCode().equals("201")) {
    // Redirect user to redirecturl param [vtResponse.getRedirectUrl()]
} else {
    // Handle denied / unexpected response
}

Set enabled payment method

You can specify manually on every request which payment method that want to be enabled on transaction.

VtWebChargeRequest vtWebChargeRequest = new VtWebChargeRequest();
setVtWebChargeRequestValues(vtWebChargeRequest);
vtWebChargeRequest.setVtWeb(new VtWebParam());
vtWebChargeRequest.getVtWeb().setEnabledPayments(new VtWebParam.PaymentMethod[]{VtWebParam.PaymentMethod.CREDIT_CARD, VtWebParam.PaymentMethod.CIMB_CLICKS});

Handle VtWeb URL parameter response

After customer finishes transaction on vtWeb page, it will be redirected to merchant web page based on redirect url config that already setup before. Veritrans will response with several url parameter that can be handle by merchant :

<!-- Success transaction example -->
http://www.example.com/finish?order_id=asf1434355961&status_code=200&transaction_status=capture

<!-- Deny transaction example -->
http://www.example.com/deny?order_id=asf1434356038&status_code=202&transaction_status=deny

<!-- Pending transaction example -->
http://www.example.com/pending?order_id=asf1434356096&status_code=201&transaction_status=pending


Other Features

Check Transaction Status

VtDirect

String orderId = "your unique order ID";
VtResponse vtResponse = vtDirect.status(orderId);
// continue processing based on the vtResponse

VtWeb

String orderId = "your unique order ID";
VtResponse vtResponse = vtWeb.status(orderId);
// continue processing based on the vtResponse

Check Multiple Transaction Status

ArrayList<String> listOrderIds = new ArrayList<String>();
listOrderIds.add(orderId1);
listOrderIds.add(orderId2);

// Build status request from list of order ID
StatusRequest statusRequest = new StatusRequestBuilder()
    .setOrderIds(listOrderIds)
    .setPage(1)
    .setRowPerPage(10)
    .createStatusRequest();

VtResponse vtResponse = vtDirect.status(statusRequest);

Querying Transaction Status

// Build get status query parameter
final GetStatusParameter parameter = new GetStatusParameterBuilder()
    .setFraudStatus(FraudStatus.CHALLENGE)
    .setTransactionStatus(TransactionStatus.AUTHORIZED)
    .setPaymentMethod(PaymentMethod.CREDIT_CARD)
    .setPage(2)
    .setRowPerPage(10)
    .createGetStatusParameter();

VtResponse response = vtDirect.queryStatus(parameter);


Credit Card: Accept an FDS challenge capture

VtDirect

String orderId = "your unique order ID";
VtResponse vtResponse = vtDirect.approve(orderId);

if (vtResponse.getStatusCode().equals("200") &&
    vtResponse.getTransactionStatus() == TransactionStatus.CAPTURED) {

    // handle successful capture approval
} else {
    // handle denied / unexpected response
}

VtWeb

String orderId = "your unique order ID";
VtResponse vtResponse = vtWeb.approve(orderId);

if (vtResponse.getStatusCode().equals("200") &&
    vtResponse.getTransactionStatus() == TransactionStatus.CAPTURED) {

    // handle successful capture approval
} else {
    // handle denied / unexpected response
}


Cancel Transaction

VtDirect

String orderId = "your unique order ID";
VtResponse vtResponse = vtDirect.cancel(orderId);

if (vtResponse.getStatusCode().equals("200") &&
    vtResponse.getTransactionStatus() == TransactionStatus.CANCELLED) {

    // handle successful transaction cancel
} else {
    // handle denied / unexpected response
}

VtWeb

String orderId = "your unique order ID";
VtResponse vtResponse = vtWeb.cancel(orderId);

if (vtResponse.getStatusCode().equals("200") &&
    vtResponse.getTransactionStatus() == TransactionStatus.CANCELLED) {

    // handle successful transaction cancel
} else {
    // handle denied / unexpected response
}


Status Code (Response)

Status Codes used by Veritrans API are categorized into 2xx, 3xx, 4xx dan 5xx. You can check detail of all status code that responded from transaction request in here


Notification Handler (Notification URL)

Notification URL is used by Veritrans Payment API to notify a merchant once a payment process has been completed or failed. It is invoked by Veritrans Payment API through HTTP POST by sending a JSON Message in the request body. The structure of the JSON Message is identical with the JSON Response when invoking the Veritrans Payment API.

There is a static method provided by VtResponse to help you deserializing the JSON Message into a VtResponse instance. This method accepts JSON String or a Raw Input Stream. Do remember that it is still the caller responsibility to close the InputStream.

Below is an example code to handle Notification URL using Java Servlet API:

...
void doPost(HttpServletRequest req, HttpServletResponse resp) {
    try {
        ServletInputStream inputStream = req.getInputStream();
        VtResponse vtResponse = VtResponse.deserializeJson(inputStream);

        // if necessary, we can utilize VtDirect's or VtWeb's Check Transaction Status Feature to make sure the notification is really coming from Veritrans
        String orderId = vtResponse.getOrderId();
        vtResponse = vtDirect.status(orderId); // we used VtDirect in this example, however we can use VtWeb too

        if (vtResponse.getTransactionStatus() == TransactionStatus.SETTLED) {
            // handle settled / successful charge request
        } else {
            // handle denied / unexpected response
        }
    } catch (JsonDeserializeException e) {
        // handle JSON deserialization error
        ...
    } finally {
        resp.setStatus(HttpServletResponse.SC_OK);
    }
}
...