Feature: 3D Secure (3DS)

Three Domain Secure (3DS) is a security feature which requires the customer to complete an additional verification step while making payments using card. 3DS can be enabled/disabled for specific transactions. Always enable 3DS, to prevent unnecessary security and chargeback risks.
Successful request returns redirect_url to redirect customer to the authentication page. After completing the authentication process, you will receive notification containing the transaction details and 3DS result.




3DS Charge Request

{
  "payment_type": "credit_card",
  "transaction_details": {
    "order_id": "C17550",
    "gross_amount": 145000
  },
  "credit_card": {
    "token_id": "< your token ID >",
    "authentication": true,
    "callback_type": "js_event"
  }
}

The credit_card object in Charge request to configure 3DS feature is identical with Card Charge Request, with the additional attributes given below.

JSON AttributeDescriptionTypeRequired
token_idToken ID represents customer's card information acquired from Get Card Token response.StringRequired
authenticationFlag to enable the 3D secure authentication. Default value is false.BooleanOptional
callback_typeDetermines how the transaction status is updated to the merchant frontend. Possible values are js_event (default) and form. For more details, refer Handling 3DS Callback.StringOptional



3DS Charge Response and Notifications

Sample Response

{
  "status_code": "201",
  "status_message": "Success, Credit Card transaction is successful",
  "transaction_id": "1a1a66f7-27a7-4844-ba1f-d86dcc16ab27",
  "order_id": "C17550",
  "redirect_url": "https://api.veritrans.co.id/v2/3ds/redirect/451249-2595-e14aac7f-cfb3-4ab2-98ab-5cc5e70f4b2c",
  "gross_amount": "145000.00",
  "currency": "IDR",
  "payment_type": "credit_card",
  "transaction_time": "2018-09-12 22:10:23",
  "transaction_status": "pending",
  "masked_card": "48111111-1114",
  "card_type": "credit",
  "three_ds_version": "2",
  "on_us": true
}
{
  "status_code": "201",
  "status_message": "Success, Credit Card transaction is successful",
  "transaction_id": "1a1a66f7-27a7-4844-ba1f-d86dcc16ab27",
  "order_id": "C17550",
  "redirect_url": "https://api.veritrans.co.id/v2/3ds/redirect/451249-2595-e14aac7f-cfb3-4ab2-98ab-5cc5e70f4b2c",
  "gross_amount": "145000.00",
  "currency": "IDR",
  "payment_type": "credit_card",
  "transaction_time": "2018-09-12 22:10:23",
  "transaction_status": "pending",
  "masked_card": "48111111-1114",
  "card_type": "credit",
  "three_ds_version": "2",
  "three_ds_challenge_completion": false
}
{
  "status_code": "400",
  "status_message": "One or more parameters in the payload is invalid.",
  "id": "1a1a66f7-27a7-4844-ba1f-d86dcc16ab27",
  "validation_messages": [
    "unsupported token request parameter(s)"
  ]
}
{
  "masked_card": "48111111-1114",
  "approval_code": "T58755",
  "bank": "bni",
  "eci": "05",
  "transaction_time": "2014-08-24 15:39:22",
  "gross_amount": "145000.00",
  "order_id": "C17550",
  "payment_type": "credit_card",
  "signature_key": "8d22a6b625f395a1a2cf0e62497e20be433cbad3e8a8ff36bf6b40dbd47308125ccda93546eab8a3acd91390155082658ac25b10a6294c6660642e43a5edc8bb",
  "status_code": "200",
  "transaction_id": "1a1a66f7-27a7-4844-ba1f-d86dcc16ab27",
  "transaction_status": "capture",
  "fraud_status": "accept",
  "status_message": "midtrans payment notification",
  "channel_response_code": "00",
  "channel_response_message": "Approved",
  "card_type": "credit",
  "three_ds_version": "2",
  "on_us": true
}
{
  "masked_card": "48111111-1114",
  "approval_code": "T58755",
  "bank": "bni",
  "eci": "05",
  "transaction_time": "2014-08-24 15:39:22",
  "gross_amount": "145000.00",
  "order_id": "C17550",
  "payment_type": "credit_card",
  "signature_key": "8d22a6b625f395a1a2cf0e62497e20be433cbad3e8a8ff36bf6b40dbd47308125ccda93546eab8a3acd91390155082658ac25b10a6294c6660642e43a5edc8bb",
  "status_code": "200",
  "transaction_id": "1a1a66f7-27a7-4844-ba1f-d86dcc16ab27",
  "transaction_status": "capture",
  "fraud_status": "accept",
  "status_message": "midtrans payment notification",
  "channel_response_code": "00",
  "channel_response_message": "Approved",
  "card_type": "credit",
  "three_ds_version": "2",
  "three_ds_challenge_completion": true
}
{
  "masked_card": "48111111-1114",
  "approval_code": "338016",
  "bank": "bni",
  "eci": "06",
  "transaction_time": "2014-08-24 15:39:22",
  "gross_amount": "145000.00",
  "order_id": "C17550",
  "payment_type": "credit_card",
  "signature_key": "763713b31cf59c886d3cc4a0c654a060a8e990080fe29fca75ae9e4ff9de804809c4e20977829844dac01a7ac1464a4eb095ad32482048398918987295dc5022",
  "status_code": "202",
  "transaction_id": "1a1a66f7-27a7-4844-ba1f-d86dcc16ab27",
  "transaction_status": "deny",
  "fraud_status": "accept",
  "status_message": "midtrans payment notification",
  "channel_response_code": "05",
  "channel_response_message": "Do not honor",
  "card_type": "credit",
  "three_ds_version": "2"
}
{
  "masked_card": "48111111-1114",
  "approval_code": "315762",
  "bank": "bni",
  "eci": "05",
  "transaction_time": "2014-08-24 15:39:22",
  "gross_amount": "145000.00",
  "order_id": "C17550",
  "payment_type": "credit_card",
  "signature_key": "393f8b6b27f9f6385d8391642942e9534fd20dad20c0631b75b0746bfc314482af4411c93e958b691a63e9154676905b906234d1f12fca031f5be5593f7ec2c6",
  "status_code": "201",
  "transaction_id": "1a1a66f7-27a7-4844-ba1f-d86dcc16ab27",
  "transaction_status": "capture",
  "fraud_status": "challenge",
  "status_message": "midtrans payment notification",
  "channel_response_code": "00",
  "channel_response_message": "Approved",
  "card_type": "credit",
  "three_ds_version": "2"
}
{
  "masked_card": "48111111-1114",
  "approval_code": "131755",
  "bank": "bni",
  "eci": "05",
  "transaction_time": "2014-08-24 15:39:22",
  "gross_amount": "145000.00",
  "order_id": "C17550",
  "payment_type": "credit_card",
  "signature_key": "49e158a0c3f1913eae0902875324075c562daa39b2824b865db2242adea247a228960d2f1002392fdbc29c3271c2bc78ba72e588db9047a82932d0615ddc811f",
  "status_code": "200",
  "transaction_id": "1a1a66f7-27a7-4844-ba1f-d86dcc16ab27",
  "transaction_status": "settlement",
  "fraud_status": "accept",
  "status_message": "midtrans payment notification",
  "channel_response_code": "00",
  "channel_response_message": "Approved",
  "card_type": "credit",
  "three_ds_version": "2"
}

The 3DS response is identical with Card Payment Charge Response, with the additional attributes given below.

JSON AttributeDescriptionType
redirect_urlThe URL to redirect the user to 3D Secure authentication page.String
eciThe 3D secure ECI Code indicating the result of the 3DS process.String



Handling 3DS Callback

By default, 3DS callback scheme is set as js_event. It is optimized for merchants who prefer to open the 3DS page without leaving from their page.

Midtrans JavaScript library provides functions to handle the redirect URL and its callback response.

var redirect_url = '<redirect_url Retrieved from Charge Response>';

// callback functions
var options = {
  performAuthentication: function(redirect_url){
    // Implement how you will open iframe to display 3ds authentication redirect_url to customer
    popupModal.openPopup(redirect_url);
  },
  onSuccess: function(response){
    // 3ds authentication success, implement payment success scenario
    console.log('response:',response);
    popupModal.closePopup();
  },
  onFailure: function(response){
    // 3ds authentication failure, implement payment failure scenario
    console.log('response:',response);
    popupModal.closePopup();
  },
  onPending: function(response){
    // transaction is pending, transaction result will be notified later via 
    // HTTP POST notification, implement as you wish here
    console.log('response:',response);
    popupModal.closePopup();
  }
};

// trigger `authenticate` function
MidtransNew3ds.authenticate(redirect_url, options);

/**
 * Example helper functions to open Iframe popup, you may replace this with your own 
 * method of open iframe. In this example, PicoModal library is used by including 
 * this script tag on the HTML:
 * <script src="https://cdnjs.cloudflare.com/ajax/libs/picomodal/3.0.0/picoModal.js"></script>
 */
var popupModal = (function(){
  var modal = null;
  return {
    openPopup(url){
      modal = picoModal({
        content:'<iframe frameborder="0" style="height:90vh; width:100%;" src="'+url+'"></iframe>',
        width: "75%",
        closeButton: false,
        overlayClose: false,
        escCloses: false
      }).show();
    },
    closePopup(){
      try{
        modal.close();
      } catch(e) {}
    }
  }
}());

/**
 * Alternatively, instead of opening 3ds authentication redirect_url using iframe,
 * you can also redirect customer using:
 * MidtransNew3ds.redirect( redirect_url, { callbackUrl : 'https://mywebsite.com/finish_3ds' });
 **/
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sample</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/picomodal/3.0.0/picoModal.js"></script>
    <script id="midtrans-script" type="text/javascript" src="https://api.midtrans.com/v2/assets/js/midtrans-new-3ds.min.js" data-environment="sandbox" data-client-key="<INSERT YOUR CLIENT KEY HERE>"></script>
</head>
<body>
    <script>
        /**
         * Example helper functions to open Iframe popup, you may replace this with your own 
         * method of open iframe. In this example, PicoModal library is used by including 
         * this script tag on the HTML:
         */
        var popupModal = (function(){
            var modal = null;
            return {
                openPopup(url){
                modal = picoModal({
                    content:'<iframe frameborder="0" style="height:90vh; width:100%;" src="'+url+'"></iframe>',
                    width: "75%",
                    closeButton: false,
                    overlayClose: false,
                    escCloses: false
                }).show();
                },
                closePopup(){
                try{
                    modal.close();
                } catch(e) {}
                }
            }
        }());
    </script>

    <script>
        var redirect_url = '<redirect_url Retrieved from Charge Response>';

        // callback functions
        var options = {
            performAuthentication: function(redirect_url){
                // Implement how you will open iframe to display 3ds authentication redirect_url to customer
                popupModal.openPopup(redirect_url);
            },
            onSuccess: function(response){
                // 3ds authentication success, implement payment success scenario
                console.log('response:',response);
                popupModal.closePopup();
                // // Simulate an HTTP redirect:
                window.location.replace("http://midtrans.com?status=success");
            },
            onFailure: function(response){
                // 3ds authentication failure, implement payment failure scenario
                console.log('response:',response);
                popupModal.closePopup();
            },
            onPending: function(response){
                // transaction is pending, transaction result will be notified later via 
                // HTTP POST notification, implement as you wish here
                console.log('response:',response);
                popupModal.closePopup();
            }
        };

        // trigger `authenticate` function
        MidtransNew3ds.authenticate(redirect_url, options);
    </script>   
</body>
</html>

Callback via form is a simple web redirection. From the merchant website, the customer is redirected to 3DS page and then back to merchant website. For callback via js-event open 3DS page in an iFrame, and the callback happens as a JSON.

JSON AttributeDescriptionType
transaction_idTransaction ID given by Midtrans.String
order_idOrder ID specified by you.String
gross_amountTotal amount of transaction in IDR.String
payment_typeThe payment method used by the customer.
Value: credit_card.
Note: For any transactions using payment card (credit or debit), payment_type is credit_card.
String
transaction_timeTimestamp of transaction in ISO 8601 format. Time Zone: GMT+7.String
transaction_statusTransaction status after charge card transaction. Possible values are
capture: Transaction is accepted by the bank and ready for settlement.
deny: transaction is denied by the bank or FDS.
authorize: card is authorized in Pre-authorization feature.
pending: Credit card is pending and you will need to rely on the http notification webhook to receive the final transaction status.
String
fraud_statusDetection result by Fraud Detection System (FDS). Possible values are
accept: Approved by FDS.
challenge: Questioned by FDS.
Note: Approve transaction to accept it or transaction will get cancelled automatically during settlement.
deny: Denied by FDS. Transaction automatically failed.
String
masked_cardFirst 8-digits and last 4-digits of customer's card number.String
status_codeStatus code of transaction charge result.String
bankThe name of the Acquiring Bank.String
status_messageStatus message describing the result of the API request.String
approval_codeApproval code. It can be used for refund. This does not exist on denied transaction.String
eciThe 3D secure ECI Code indicating the result of the 3DS process.String
channel_response_codeResponse code from payment channel provider.String
channel_response_messageResponse message from payment channel provider.String
currencyISO-4217 representation of three-letter alphabetic currency code. Value: IDR.
Note: Currently only IDR is supported.
String
card_typeType of payment card used for the transaction. Possible values are credit, debit.String
three_ds_version3DS Version that used for transaction (This field only present for 3DS Transaction). Possible values are 1, 2String
three_ds_challenge_completion3DS Challenge completion state to indicate the customer has been submitted the OTP or not(it doesn't matter if the OTP is valid or not). Possible values are true, falseBoolean

📘

Note

If you receive pending transaction_status, you will need to rely on the http notification webhook to receive the final transaction status




Redirecting to 3DS Page (3DS 2.0 Compatible)

After proceeding card transaction to Charge API request, if the transaction needs 3DS authentication, you will receive redirect_url in the response. You can optionally use built-in MidtransNew3ds.redirect function to redirect the customer.

After 3DS process is completed, the customer is redirected back to the website specified in callbackUrl or the Finish Redirect URL configured on your MAP account.
This final redirect is HTTP POST method. It contains JSON string encapsulated as value of response key of the POST form-data.

Callback response object attributes are listed below.

var options = {
    // In case, Merchant needs to override for each transactions
    callbackUrl = "<ANY LINK>"
}

MidtransNew3ds.redirect(redirect_url, options);
<form id="veritrans" method="post" action="<callbackUrl>">
    <input type="hidden" name="response" value="<JSON FORMAT CALLBACK OBJECT>"/>
</form>
JSON AttributeDescriptionType
transaction_idTransaction ID given by Midtrans.String
order_idOrder ID specified by you.String
gross_amountTotal amount of transaction in IDR.String
payment_typeThe payment method used by the customer.String
transaction_timeTimestamp of transaction in ISO 8601 format. Time Zone: GMT+7.String
transaction_statusTransaction status after charge credit card transaction. Possible values are
capture : Transaction is accepted by the bank and ready for settlement.
deny: transaction is denied by the bank or FDS.
authorize: Credit card is authorized in pre-authorization feature.
pending: Credit card is pending and you will need to rely on the http notification webhook to receive the final transaction status..
String
fraud_statusDetection result by Fraud Detection System (FDS). Possible values are
accept : Approved by FDS.
challenge: Questioned by FDS. Note: Approve transaction to accept it or transaction gets automatically canceled during settlement.
deny: Denied by FDS. Transaction automatically failed.
String
masked_cardFirst 8-digits and last 4-digits of customer's credit card number.String
status_codeStatus code of transaction charge result.String
bankThe name of the acquiring bank.String
status_messageStatus message describing the result of the API request.String
approval_codeApproval code. It can be used for refund. This does not exist on denied transaction.String
eciThe 3D secure ECI Code.String
channel_response_codeResponse code from payment channel provider.String
channel_response_messageResponse message from payment channel provider.String
currencyISO-4217 representation of three-letter alphabetic currency code. Value: IDR.
Note: Currently only IDR is supported.
String
card_typeType of card used for the transaction. Possible values are credit, debit.String
three_ds_version3DS Version that used for transaction (This field only present for 3DS Transaction). Possible values are 1, 2String
three_ds_challenge_completion3DS Challenge completion state to indicate the customer has submit the OTP or not(it doesn't matter if the OTP is valid or not). Possible values are true, falseBoolean

📘

Note

If you receive pending transaction_status, you will need to rely on the http notification webhook to receive the final transaction status


Optional parameter is given below.

NameDescriptionRequired
callbackUrlTo override where the customer gets redirected after 3DS authentication is done.Optiona



Opening 3DS Page via iFrame (3DS 2.0 Compatible)

Optionally, you can use MidtransNew3ds.performAuthentication function to open redirect_url as iFrame. It is a substitute to the redirection scheme.

After 3DS process is completed by a customer, your website receives JSONP callback containing the transaction result.

Callback response object attributes are listed below.

// Open 3DSecure dialog box
function openDialog(url) {
    // make sure to load fancybox in a script tag
    $.fancybox.open({
        href: url,
        type: 'iframe',
        autoSize: false,
        width: 400,
        height: 420,
        closeBtn: false,
        modal: true
    });
}

// Close 3DSecure dialog box
function closeDialog() {
    $.fancybox.close()
}

var options = {
  performAuthentication: function(url) {
    openDialog(url)
  },
  onSuccess: function(response) {
    // Successful handling
    closeDialog()
  },
  onPending: function(response) {
    // Pending handling
    closeDialog()
  },
  onFailure: function(response) {
    // Failure handling
    closeDialog()
  }
}

MidtransNew3ds.authenticate(redirect_url,options)
JSON AttributeDescriptionType
transaction_idTransaction ID given by Midtrans.String
order_idOrder ID specified by you.String
gross_amountTotal amount of transaction in IDR.String
payment_typeThe payment method used by the customer.String
transaction_timeTimestamp of transaction in ISO 8601 format. Time Zone: GMT+7.String
transaction_statusTransaction status after charge credit card transaction. Possible values are
capture : Transaction is accepted by the bank and ready for settlement.
deny: transaction is denied by the bank or FDS.
authorize: Credit card is authorized in pre-authorization feature.
pending: Credit card is pending and you will need to rely on the http notification webhook to receive the final transaction status.
String
fraud_statusDetection result by Fraud Detection System (FDS). Possible values are
accept : Approved by FDS.
challenge: Questioned by FDS. Note: Approve transaction to accept it or transaction gets automatically canceled during settlement.
deny: Denied by FDS. Transaction automatically failed.
String
masked_cardFirst 8-digits and last 4-digits of customer's credit card number.String
status_codeStatus code of transaction charge result.String
bankThe acquiring bank of the transaction.String
status_messageDescription of transaction charge result.String
approval_codeApproval code. It can be used for refund. This does not exist on denied transaction.String
eciThe 3D secure ECI Code.String
channel_response_codeResponse code from payment channel provider.String
channel_response_messageResponse message from payment channel provider.String
currencyISO-4217 representation of three-letter alphabetic currency code. Value: IDR.
Note: Currently only IDR is supported.
String
card_typeType of card used for the transaction. Possible values are credit, debit.String
three_ds_version3DS Version that used for transaction (This field only present for 3DS Transaction). Possible values are 1, 2String

📘

Note

If you receive pending transaction_status, you will need to rely on the http notification webhook to receive the final transaction status


Available options are given below.

NameDescription
performAuthenticationImplementation to open redirect URL in iFrame.
onSuccessHandle to receive successful callback response.
onPendingHandle to receive callback response. Only applicable when merchant applied for async endpoint.
onFailureHandle to receive failure response.
Language
Authorization
Basic
base64
:
Click Try It! to start a request and see the response here!