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 Attribute | Description | Type | Required |
---|---|---|---|
token_id | Token ID represents customer's card information acquired from Get Card Token response. | String | Required |
authentication | Flag to enable the 3D secure authentication. Default value is false . | Boolean | Optional |
callback_type | Determines 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. | String | Optional |
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 Attribute | Description | Type |
---|---|---|
redirect_url | The URL to redirect the user to 3D Secure authentication page. | String |
eci | The 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 Attribute | Description | Type |
---|---|---|
transaction_id | Transaction ID given by Midtrans. | String |
order_id | Order ID specified by you. | String |
gross_amount | Total amount of transaction in IDR. | String |
payment_type | The 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_time | Timestamp of transaction in ISO 8601 format. Time Zone: GMT+7. | String |
transaction_status | Transaction status after charge card transaction. Possible values arecapture : 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_status | Detection result by Fraud Detection System (FDS). Possible values areaccept : 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_card | First 8-digits and last 4-digits of customer's card number. | String |
status_code | Status code of transaction charge result. | String |
bank | The name of the Acquiring Bank. | String |
status_message | Status message describing the result of the API request. | String |
approval_code | Approval code. It can be used for refund. This does not exist on denied transaction. | String |
eci | The 3D secure ECI Code indicating the result of the 3DS process. | String |
channel_response_code | Response code from payment channel provider. | String |
channel_response_message | Response message from payment channel provider. | String |
currency | ISO-4217 representation of three-letter alphabetic currency code. Value: IDR .Note: Currently only IDR is supported. | String |
card_type | Type of payment card used for the transaction. Possible values are credit , debit . | String |
three_ds_version | 3DS Version that used for transaction (This field only present for 3DS Transaction). Possible values are 1 , 2 | String |
three_ds_challenge_completion | 3DS 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 , false | Boolean |
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 Attribute | Description | Type |
---|---|---|
transaction_id | Transaction ID given by Midtrans. | String |
order_id | Order ID specified by you. | String |
gross_amount | Total amount of transaction in IDR. | String |
payment_type | The payment method used by the customer. | String |
transaction_time | Timestamp of transaction in ISO 8601 format. Time Zone: GMT+7. | String |
transaction_status | Transaction status after charge credit card transaction. Possible values arecapture : 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_status | Detection result by Fraud Detection System (FDS). Possible values areaccept : 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_card | First 8-digits and last 4-digits of customer's credit card number. | String |
status_code | Status code of transaction charge result. | String |
bank | The name of the acquiring bank. | String |
status_message | Status message describing the result of the API request. | String |
approval_code | Approval code. It can be used for refund. This does not exist on denied transaction. | String |
eci | The 3D secure ECI Code. | String |
channel_response_code | Response code from payment channel provider. | String |
channel_response_message | Response message from payment channel provider. | String |
currency | ISO-4217 representation of three-letter alphabetic currency code. Value: IDR .Note: Currently only IDR is supported. | String |
card_type | Type of card used for the transaction. Possible values are credit , debit . | String |
three_ds_version | 3DS Version that used for transaction (This field only present for 3DS Transaction). Possible values are 1 , 2 | String |
three_ds_challenge_completion | 3DS 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 , false | Boolean |
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.
Name | Description | Required |
---|---|---|
callbackUrl | To 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 Attribute | Description | Type |
---|---|---|
transaction_id | Transaction ID given by Midtrans. | String |
order_id | Order ID specified by you. | String |
gross_amount | Total amount of transaction in IDR. | String |
payment_type | The payment method used by the customer. | String |
transaction_time | Timestamp of transaction in ISO 8601 format. Time Zone: GMT+7. | String |
transaction_status | Transaction status after charge credit card transaction. Possible values arecapture : 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_status | Detection result by Fraud Detection System (FDS). Possible values areaccept : 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_card | First 8-digits and last 4-digits of customer's credit card number. | String |
status_code | Status code of transaction charge result. | String |
bank | The acquiring bank of the transaction. | String |
status_message | Description of transaction charge result. | String |
approval_code | Approval code. It can be used for refund. This does not exist on denied transaction. | String |
eci | The 3D secure ECI Code. | String |
channel_response_code | Response code from payment channel provider. | String |
channel_response_message | Response message from payment channel provider. | String |
currency | ISO-4217 representation of three-letter alphabetic currency code. Value: IDR .Note: Currently only IDR is supported. | String |
card_type | Type of card used for the transaction. Possible values are credit , debit . | String |
three_ds_version | 3DS Version that used for transaction (This field only present for 3DS Transaction). Possible values are 1 , 2 | String |
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.
Name | Description |
---|---|
performAuthentication | Implementation to open redirect URL in iFrame. |
onSuccess | Handle to receive successful callback response. |
onPending | Handle to receive callback response. Only applicable when merchant applied for async endpoint. |
onFailure | Handle to receive failure response. |