3DS con la API JavaScript de 3DS

En este tema se describen todos los pasos necesarios para agregar 3DS a la integración del Mastercard Gateway utilizando la API 3DS JavaScript(JS), incluido cómo usar el resultado de la autenticación para procesar un pago.

Para ver ejemplos de las solicitudes y respuestas de API utilizadas en el flujo de 3DS con la API de JavaScript de 3DS, descargue la colección de Postman.

Para obtener más información sobre algunas funciones genéricas de 3DS que puede aprovechar en su integración, consulte las Preguntas frecuentes. Una vez que haya completado su integración, consulte Pruebas de su integración 3DS para probarla.

Prerrequisitos Copied to Clipboard

Para usar 3DS con la API JS de 3DS:

Paso 1: Crear y actualizar una sesión Copied to Clipboard

3DS JS utiliza la autenticación basada en sesión. Para obtener más información sobre la autenticación basada en sesiones, consulte Opciones de autenticación. Como primer paso, debe crear una sesión, que luego puede actualizar con los campos de solicitud y los valores que desea almacenar en la sesión.
Puede crear una sesión utilizando la solicitud CREATE SESSION. Esta es una solicitud de API de servicios web del lado del servidor y es un requisito previo para la integración con la API de JS. Devuelve los siguientes campos:

  • session.id
    Identificador de sesión único que debe proporcionar en solicitudes posteriores para hacer referencia al contenido de la sesión.
  • session.authenticationLimit
    Límite en la cantidad de solicitudes de transacciones que el explorador del pagador puede enviar. Puede proporcionar un valor en la solicitud o utilizar el valor predeterminado del motor de pagos. De forma predeterminada, el motor de pagos lo establece en 5, pero puede proporcionar un valor de hasta 25. Este límite evita que usuarios malintencionados utilicen la solicitud de autenticación como un posible ataque de fraude de tarjetas y que realicen ataques de denegación de servicio (DoS) en su sitio mediante el envío de un gran número de transacciones potencialmente facturables.
    Cualquier reintento de autenticación que inicie se compara con el límite de autenticación.
  • session.aes256Key
    Clave que puede usar para descifrar los datos confidenciales que se transmiten al sitio web a través del explorador o dispositivo móvil del pagador.
  • session.version
    Versión de la sesión. puede usar este campo para implementar el bloqueo optimista del contenido de la sesión.
  • session.updateStatus
    Resumen del resultado del último intento para modificar la sesión.

Después de haber creado la sesión, puede agregar o actualizar campos en una sesión usando la solicitud UPDATE SESSION. Esto le permite agregar datos de pago y del pagador a una sesión que posteriormente puede convertirse en la entrada para determinar el riesgo asociado con un pagador en una operación de autenticación. La siguiente tabla define los campos utilizados comúnmente en una sesión.
Tabla: Campos de sesión

Campo Obligatorio/Opcional Descripción
session.id
o
sourceOfFunds.provided.card.* o
sourceOfFunds.token
Obligatorio Detalles de la tarjeta que se va a utilizar para el pago.
También puede utilizar tokens de red y tokens de pago de dispositivos como fuente de fondos en la autenticación del pagador. Para obtener más información, consulte las Preguntas frecuentes.
order.amount Obligatorio Importe total del pedido.
order.currency Obligatorio Moneda del pedido.
transaction.id Obligatorio Identificador único para esta autenticación de pago.
order.id Obligatorio Identificador único para este pedido.
authentication.channel Obligatorio Canal en el que se inicia la solicitud de autenticación. Puede especificar una de las siguientes opciones:
  • MERCHANT_REQUESTED: Indica que está solicitando la autenticación de un titular de tarjeta sin que el pagador esté disponible para interactuar. Por ejemplo, como parte del procesamiento de un pago recurrente. Esta opción no se admite actualmente.
  • PAYER_BROWSER: Indica que el pagador interactúa a través de un explorador web. Por ejemplo, con el sitio web de comercio electrónico del negocio.
authentication.redirectResponseUrl Obligatorio URL a la que desea redirigir al pagador después de completar el proceso de autenticación del pagador. No es necesario que proporcione esta URL si está seguro de que no habrá interacción con el pagador.
authentication.purpose Opcional Finalidad de la autenticación.
De forma predeterminada, este campo está configurado en PAYMENT_TRANSACTION para indicar que se debe realizar la autenticación al procesar un pago con tarjeta. No obstante, puede especificar una finalidad diferente para indicar la autenticación sin pago. Si está estableciendo un acuerdo de pago y no procesa un pago junto con él, ingrese ADD_CARD como propósito de autenticación. Consulte ¿Cómo puedo enviar una solicitud de autenticación no relacionada con el pago? Se deben proporcionar los detalles del acuerdo.
authentication.acceptVersions Opcional Versiones de 3DS que acepta para este pago. Si no especifica una versión, se acepta 3DS2. El motor de pagos utiliza 3DS2 si el emisor y la tarjeta lo admiten. Si 3DS2 no está disponible, la autenticación no continúa.
order.merchantCategoryCode Opcional Código de categoría de negocio.
Proporcione el valor si desea anular el valor predeterminado configurado en su vínculo de adquirente.
No puede eliminar campos de una sesión. Solo puede sobrescribir valores para campos existentes.

Paso 2: Inicializar la API Copied to Clipboard

Consulte la API de JS 3DS (threeDS.js) en los servidores del motor de pagos. Esto coloca un objeto ThreeDS en la ventana/espacio de nombres global.
Una vez que haya creado una sesión, inicialice la API 3DS JS usando la función configure(), con los siguientes argumentos obligatorios en el objeto de mapa threedsConfig:

  • merchantId
    Su identificador de negocio en el motor de pagos.
  • sessionId
    ID de sesión que creó utilizando la solicitud CREATE SESSION.
  • containerId
    ID de <div> en su código HTML donde la API inyecta un iframe oculto.
  • callback
    Función que se invocará una vez inicializada la API.
  • configuration
    Valor JSON que admite elementos de datos como userLanguage (idioma de la página de pago que se muestra al usuario; opcional) y wsVersion (versión de la API WS).

La función configure() debe llamarse durante la carga de la página o cuando el DOM tenga el estado listo. Debe llamarse solo una vez para la carga de la página. Después de llamar a este método, 3DS JS proporciona valores de configuración como variables miembro.

Ejemplo de configuración de la API de inicialización

<html>
    <head>
    <script src="../../../../../../../static/threeDS/1.3.0/three-ds.min.js"
            data-error="errorCallback"
            data-cancel="cancelCallback">
    </script>

    <script type="text/javascript">
        //The output of this call will return 'false', since the API is not configured yet
        console.log(ThreeDS.isConfigured());
        /**
        Configure method with the configuration{} parameter set and demonstrates the state change of the ThreeDS object before and after the configure method is invoked.
        */
        ThreeDS.configure({
            merchantId: {merchantId},
            sessionId: {sessionId},
            containerId: "3DSUI",
            callback: function () {
                if (ThreeDS.isConfigured())
                    console.log("Done with configure");
            },
            configuration: {
                userLanguage: "en-AU", //Optional parameter
                wsVersion: 81
            }
        });

        //The output of this call will return 'true', since the API is configured
        console.log(ThreeDS.isConfigured());

        //The output of the following code might look like "ThreeDS JS API Version : 1.2.0"
        console.log("ThreeDS JS API Version : " + ThreeDS.version);
    </script>
    </head>
    <body>
        <div id="3DSUI"></div>
    </body>
</html>
		

Paso 3: Iniciar autenticación Copied to Clipboard

Una vez que todos los datos del pagador y de pago se hayan recopilado en una sesión, puede iniciar la autenticación invocando la función initiateAuthentication(). Llama a la solicitud INITIATE AUTHENTICATION de la API de autenticación de pagador y determina las versiones de autenticación de pagador disponibles para usted para una tarjeta determinada, basándose en lo siguiente:

  • las versiones de 3DS configuradas en su perfil del negocio;
  • el tipo de tarjeta;
  • las preferencias que haya indicado en la solicitud;
  • la versión de 3DS en la que se inscribió la tarjeta;
  • las reglas de filtrado de transacciones 3DS configuradas por usted o por Your payment service provider (PSP).

La función también permite realizar cualquier actividad en segundo plano, como una llamada 3DS2 ACS, con fines tales como recopilar datos adicionales del pagador para respaldar una función authenticatePayer() posterior.

Para permitir que cualquier proceso de llamada al ACS se complete antes de intentar la función authenticatePayer(), invoque la función initiateAuthentication() lo antes posible en su proceso de pago y actúe de inmediato en función de la respuesta. Lo antes posible suele ser cuando el pagador termina de ingresar su número de tarjeta en la página de pago, por ejemplo, el evento onBlur del campo de entrada Número de tarjeta, o cuando selecciona una tarjeta de las registradas en su cuenta, si su sitio cuenta con capacidades de tarjeta en archivo. Espere al menos 10 segundos para que se complete la llamada al método ACS.

Puede iniciar la autenticación llamando a la función initiateAuthentication() con los siguientes argumentos obligatorios:

  • transactionId
    Identificador único para esta autenticación de pago.
  • orderId
    Identificador único para este pedido.
  • callback
    Función de devolución de llamada.
  • optionalParams (optional)
    Campos adicionales, como correlationId.

Si la autenticación 3DS del pagador está disponible, se devuelven los siguientes campos en el argumento data de la función de devolución de llamada. De lo contrario, la respuesta incluye un error.

  • data.restApiResponse
    Respuesta sin procesar de la llamada de API REST de Initiate Authentication.
  • data.correlationId
    Último ID de correlación que se usó para realizar la llamada de API REST de Initiate Authentication. Permite relacionar la respuesta con la solicitud.
  • data.gatewayRecommendation
    Recomendación sobre sus próximas acciones, basadas en las reglas de filtrado de transacciones 3DS configuradas por usted o su PSP:
    • PROCEED: Puede continuar con el Paso 4 para autenticar al pagador.
    • RESUBMIT_WITH_ALTERNATIVE_PAYMENT_DETAILS: Solicite al pagador detalles de pago alternativos, por ejemplo, una nueva tarjeta u otro método de pago, y vuelva a enviar la solicitud con los nuevos detalles. No vuelva a enviar la misma solicitud.
  • data.authenticationVersion
    Devuelve 3DS2 si la autenticación está disponible.
Ejemplo de inicio de solicitud de autenticación

var optionalParams = {
    sourceOfFunds: {
        type: "CARD"
    },
    order: {
        walletProvider: "MASTERPASS_ONLINE"
    }
};

ThreeDS.initiateAuthentication({orderId}, {transactionId}, function (data) {
    if (data && data.error) {
        var error = data.error;

        //Something bad happened, the error value will match what is returned by the Authentication API
        console.error("error.code : ", error.code);
        console.error("error.msg : ", error.msg);
        console.error("error.result : ", error.result);
        console.error("error.status : ", error.status);
    } else {
        console.log("After Initiate 3DS ", data);

        //data.response will contain information like gatewayRecommendation, authentication version, and so on.
        console.log("REST API raw response ", data.restApiResponse);
        console.log("Correlation Id", data.correlationId);
        console.log("Gateway Recommendation", data.gatewayRecommendation);
        console.log("HTML Redirect Code", data.htmlRedirectCode);
        console.log("Authentication Version", data.authenticationVersion);

        switch (data.gatewayRecommendation) {
            case "PROCEED":
                authenticatePayer();//merchant's method
                break;
            case "RESUBMIT_WITH_ALTERNATIVE_PAYMENT_DETAILS":
               tryOtherPayment();//Card does not support 3DS and transaction filtering rules require 3DS on this transaction: Ask the payer to select a different payment method.
                break;
        }
    }
}, optionalParams);
		
Ejemplo de respuesta de Initiate Authentication
{ 
   "authentication":{ 
      "3ds2":{ 
         "methodCompleted":false,
         "methodSupported":"SUPPORTED"
      },
      "redirect":{ 
         "customized":{ 
            "3DS":{ 
               "methodPostData":"eyJ0aHJlZURTTWV0aG9kTm90aWZpY2F0aW9uVVJMIjoiaHR0cHM6Ly9xYTA0LmdhdGV3YXkubWFzdGVyY2FyZC5jb20vY2FsbGJhY2tJbnRlcmZhY2UvZ2F0ZXdheS80ZjNmMGQyMjM5NzQwODE2OWIwMWFiYzg2OTQyZTY5NzBmODA2M2M0MDU4ZjAzNjNlOTFlMmJiOTNkOTA0NzU3IiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiJhYWY5YjU5ZC0yZTA0LTRjZDUtOTQzOC01OGU4MGEzNzBiNWEifQ==",
               "methodUrl":"<method_url>"
            }
         }
      },
      "redirectHtml":"<div id=\"initiate3dsSimpleRedirect\" xmlns=\"http://www.w3.org/1999/html\"> <iframe id=\"methodFrame\" name=\"methodFrame\" height=\"100\" width=\"200\" > </iframe> <form id =\"initiate3dsSimpleRedirectForm\" method=\"POST\" action=\"https://<host_name>/acs/v2/method\" target=\"methodFrame\"> <input type=\"hidden\" name=\"threeDSMethodData\" value=\"eyJ0aHJlZURTTWV0aG9kTm90aWZpY2F0aW9uVVJMIjoiaHR0cHM6Ly9xYTA0LmdhdGV3YXkubWFzdGVyY2FyZC5jb20vY2FsbGJhY2tJbnRlcmZhY2UvZ2F0ZXdheS80ZjNmMGQyMjM5NzQwODE2OWIwMWFiYzg2OTQyZTY5NzBmODA2M2M0MDU4ZjAzNjNlOTFlMmJiOTNkOTA0NzU3IiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiJhYWY5YjU5ZC0yZTA0LTRjZDUtOTQzOC01OGU4MGEzNzBiNWEifQ==\" /> </form> <script>document.getElementById(\"initiate3dsSimpleRedirectForm\").submit();</script> </div>",
      "version":"3DS2"
   },
   "order":{
      "currency":"AUD",
      "status":"AUTHENTICATION_INITIATED"
   },
   "response":{
      "gatewayCode":"AUTHENTICATION_IN_PROGRESS",
      "gatewayRecommendation":"PROCEED"
   },
   "result":"SUCCESS",
   "sourceOfFunds":{
      "provided":{
         "card":{
            "number":"512345xxxxxx0008"
         }
      },
      "type":"CARD"
   },
   "transaction":{
      "authenticationStatus":"AUTHENTICATION_AVAILABLE"
   },
   "version":"72"
}

Paso 4: Autenticar al pagador Copied to Clipboard

Si la respuesta de INITIATE AUTHENTICATION ha indicado que la autenticación está disponible (transaction.authenticationStatus=AUTHENTICATION_AVAILABLE), puede autenticar al pagador. Invoque la función authenticatePayer() cuando el pagador haga clic en el botón Pay ahora en la página de pago. La función llama a la solicitud AUTHENTICATE PAYER de la API de autenticación de pagador.

Debe invocar la función authenticatePayer() proporcionando los siguientes argumentos obligatorios:

  • orderId
    El mismo ID de pedido que utilizó en la función initiateAuthentication() anterior.
  • transactionId
    El mismo ID de transacción que utilizó en la función initiateAuthentication() anterior.
  • callback
    Función de devolución de llamada.
  • optionalParams(Optional)
    Campos adicionales de la solicitud AUTHENTICATE PAYER, como facturación y envío.

Los siguientes campos se devuelven en el argumento data de la función de devolución de llamada:

  • data.restApiResponse
    Respuesta sin procesar de la solicitud AUTHENTICATE PAYER. Los campos devueltos dependen del flujo (fluido o con desafío) y del canal de autenticación definido para la sesión. Para una solicitud autenticada por sesión, la respuesta se filtra para eliminar datos que no están relacionados con el pagador y solo se devuelven los campos incluidos en la lista blanca. Para obtener más información, consulte Conceptos básicos de las sesiones.
  • data.correlationId
    Último ID de correlación que se utilizó para realizar la solicitud AUTHENTICATE PAYER. Permite relacionar la respuesta con la solicitud.
  • data.gatewayRecommendation

  • Recomendación sobre sus próximas acciones, según las reglas de filtrado de transacciones 3DS configuradas por usted o your payment service provider:
    • PROCEED:Puede proceder a completar el proceso de autenticación (flujo de desafío) o proceder a completar el pago (flujo fluido). Si la autorización para el pago fue correcta, continúe con la captura de los fondos y, si procede, envíe la mercancía.
    • DO_NOT_PROCEED_ABANDON_ORDER:no vuelva a enviar la misma solicitud. El PSP, el esquema o el emisor le exigen que abandone el pedido.
    • RESUBMIT_WITH_ALTERNATIVE_PAYMENT_DETAILS:Solicite al pagador detalles de pago alternativos (por ejemplo, una nueva tarjeta u otro método de pago) y vuelva a enviar la solicitud con los nuevos detalles. No vuelva a enviar la misma solicitud.
  • data.htmlRedirectCode
    Código de redireccionamiento. Si gatewayRecommendation es PROCEED, inserte este código en la página que se muestra al pagador.

Si el motor de pagos le recomienda PROCEED:

  • Si el ACS ha seleccionado un flujo fluido para el pagador, redirige el explorador del pagador directamente a su sitio web y usted puede continuar con el Paso 5 para enviar un pago posterior al motor de pagos. El motor de pagos obtiene los datos de autenticación relacionados con el pago y garantiza que los pagos se procesen solo si se han aprobado todas las reglas de filtrado de transacciones 3DS (configuradas por usted o your payment service provider).
  • Si el ACS ha seleccionado un flujo de desafío para el pagador, redirija al pagador hacia el ACS usando el campo htmlRedirectCode proporcionado en la respuesta. Una vez completado el desafío, el ACS redirige al pagador a su sitio web y activa una devolución de llamada que contiene los campos orderId, transactionId, gatewayRecommendation y restApiResponse. Determine el resultado del desafío según el campo gatewayRecommendation. Las mismas reglas descritas anteriormente se aplican para la respuesta de la función authenticatePayer(). Si la recomendación es PROCEED, continúe con el Paso 5.
Ejemplo de solicitud de autenticación de pagador

var optionalParams = {
    fullScreenRedirect: true,
    billing: {
        address: {
            city: "London",
            country: "GBR"
        }
    }
};
 
ThreeDS.authenticatePayer({orderId}, {transactionId}, function (data) {
    if (!data.error) {
        //data.response will contain all the response payload from the AUTHENTICATE_PAYER call.
        console.log("REST API response ", data.restApiResponse);
        console.log("HTML redirect code", data.htmlRedirectCode);
        displayReceipt(data);
    }
}, optionalParams);
 
 
function displayReceipt(apiResponse) {
    var responseBody = {
        "apiResponse": apiResponse
    };
 
    var xhr = new XMLHttpRequest();
    xhr.open('PUT', '3dsreceipt', true);
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.onreadystatechange = function () {
        if (xhr.readyState == XMLHttpRequest.DONE) {
            document.documentElement.innerHTML = this.response;
        }
    }
    xhr.send(JSON.stringify(responseBody));
}

	
Ejemplo de respuesta de Authenticate Payer
{
   "authentication":{
      "3ds":{
         "transactionId":"6dfa4509-1bf2-425b-965b-d44dd11f5f91"
      },
      "3ds2":{
         "3dsServerTransactionId":"8c4a911c-289a-46c2-a615-887e1cc01a6a",
         "acsTransactionId":"2a8234c9-e8ac-449d-a693-97a113b491fc",
         "directoryServerId":"A000000004",
         "dsTransactionId":"6dfa4509-1bf2-425b-965b-d44dd11f5f91",
         "methodCompleted":false,
         "methodSupported":"SUPPORTED",
         "protocolVersion":"2.1.0",
         "requestorId":"test2ID",
         "requestorName":"test2Name",
         "transactionStatus":"C"
      },
      "method":"OUT_OF_BAND",
      "payerInteraction":"REQUIRED",
      "redirect":{
         "customized":{
            "3DS":{
               "acsUrl":"https://<host_name>/acs/v2/prompt",
               "cReq":"eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6ImNhODM1ZDQxLTBlMDktNGI3OC1hNmUyLWQwZjJiNjFlZjBjOCJ9"
            }
         },
         "domainName":"<domain_name>"
      },
      "redirectHtml":"<div id=\"threedsChallengeRedirect\" xmlns=\"http://www.w3.org/1999/html\"> <form id =\"threedsChallengeRedirectForm\" method=\"POST\" action=\"https://<host_name>/acs/v2/prompt\" target=\"challengeFrame\"> <input type=\"hidden\" name=\"creq\" value=\"eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6ImNhODM1ZDQxLTBlMDktNGI3OC1hNmUyLWQwZjJiNjFlZjBjOCJ9\" /> </form> <iframe id=\"challengeFrame\" name=\"challengeFrame\" width=\"100%\" height=\"100%\" ></iframe> <script id=\"authenticate-payer-script\"> var e=document.getElementById(\"threedsChallengeRedirectForm\"); if (e) { e.submit(); e.remove(); } </script> </div>",
      "version":"3DS2"
   },
   "correlationId":"test",
   "device":{
      "browser":"MOZILLA",
      "ipAddress":"127.0.0.1"
   },
   "merchant":"TEST_3DS2-1",
   "order":{
      "amount":100,
      "authenticationStatus":"AUTHENTICATION_PENDING",
      "creationTime":"2021-04-13T02:22:59.113Z",
      "currency":"AUD",
      "id":"807a01b6-e6c8-4aa7-b8da-799bfff89496",
      "lastUpdatedTime":"2021-04-13T02:44:07.161Z",
      "merchantCategoryCode":"1234",
      "status":"AUTHENTICATION_INITIATED",
      "totalAuthorizedAmount":0,
      "totalCapturedAmount":0,
      "totalRefundedAmount":0,
      "valueTransfer":{
         "accountType":"NOT_A_TRANSFER"
      }
   },
   "response":{
      "gatewayCode":"PENDING",
      "gatewayRecommendation":"PROCEED"
   },
   "result":"PENDING",
   "sourceOfFunds":{
      "provided":{
         "card":{
            "expiry":{
               "month":"1",
               "year":"39"
            },
            "number":"512345xxxxxx0008",
            "scheme":"MASTERCARD"
         }
      },
      "type":"CARD"
   },
   "timeOfLastUpdate":"2021-04-13T02:44:07.161Z",
   "timeOfRecord":"2021-04-13T02:22:59.113Z",
   "transaction":{
      "acquirer":{
         "merchantId":"99554411"
      },
      "amount":100,
      "authenticationStatus":"AUTHENTICATION_PENDING",
      "currency":"AUD",
      "id":"42090084",
      "type":"AUTHENTICATION"
   },
   "version":"60"
}

Integraciones avanzadas

La solicitud enviada por el explorador del pagador a su sitio web al completar el método authenticatePayer() se parametriza, permitiéndole determinar el resultado de la autenticación. Los campos de autenticación individuales, por ejemplo, authentication.3ds2.transactionStatus.data, pueden ser útiles en una integración avanzada o si necesita proporcionar los datos de autenticación en un pago procesado a través de otro motor de pagos. Para obtener más detalles, consulte ¿Cómo implemento integraciones de sesiones de pago avanzadas?

Paso 5: Usar la autenticación en un pago Copied to Clipboard

Cuando el resultado de la función authenticatePayer() indica que puede proceder con el pago (gatewayRecommendation=PROCEED), puede iniciar una operación WS API AUTHORIZE o PAY. Además de los campos estándar, debe proporcionar los siguientes campos:

  • order.id
    Utilice el mismo orderId que proporcionó en las funciones initiateAuthentication() y authenticatePayer().
  • authentication.transactionId: utilice el mismo transactionId que proporcionó en las funciones initiateAuthentication() y authenticatePayer(). No es necesario incluir ninguno de los campos en el objeto authentication, ya que el motor de pagos utiliza el authentication.transactionId para buscar los resultados de autenticación que almacenó cuando le pidió que realizara la autenticación. El motor de pagos pasa la información requerida al adquirente.
Ejemplo de solicitud Pay
URL https://evopaymentsmexico.gateway.mastercard.com/api/rest/version/<version>/merchant/<your_merchant_ID>/order/<your_order_ID>/transaction/<your_transaction_ID>
Método HTTP PUT
 
   {
      "apiOperation":"PAY",
      "authentication":{
          "transactionId":"<your_transaction_ID>"
      },
      "session": {
          "id": "<your_session_id>"
      },
      "transaction":{
          "reference":"<your_order_ID>"
      }
  } 
  
	
Ejemplo de una respuesta de Pay
{
   "authentication":{
      "3ds":{
         "acsEci":"02",
         "authenticationToken":"kHyn+7YFi1EUAREAAAAvNUe6Hv8=",
         "transactionId":"39c25b96-7bc3-4586-bee8-056479fed3af"
      },
      "3ds2":{
         "dsTransactionId":"39c25b96-7bc3-4586-bee8-056479fed3af",
         "protocolVersion":"2.1.0",
         "transactionStatus":"Y"
      },
      "transactionId":"249213216",
      "version":"3DS2"
   },
   "authorizationResponse":{
      "posData":"1605S0100130",
      "transactionIdentifier":"TidTest"
   },
   "device":{
      "browser":"MOZILLA",
      "ipAddress":"127.0.0.1"
   },
   "gatewayEntryPoint":"WEB_SERVICES_API",
   "merchant":"TEST_3DS2-1",
   "order":{
      "amount":100.00,
      "authenticationStatus":"AUTHENTICATION_SUCCESSFUL",
      "chargeback":{
         "amount":0,
         "currency":"AUD"
      },
      "creationTime":"2021-04-13T02:11:06.102Z",
      "currency":"AUD",
      "id":"807a01b6-e6c8-4aa7-b8da-799bfff89496",
      "lastUpdatedTime":"2021-04-13T02:11:57.049Z",
      "merchantAmount":100.00,
      "merchantCategoryCode":"1234",
      "merchantCurrency":"AUD",
      "reference":"807a01b6-e6c8-4aa7-b8da-799bfff89496",
      "status":"CAPTURED",
      "totalAuthorizedAmount":100.00,
      "totalCapturedAmount":100.00,
      "totalRefundedAmount":0.00
   },
   "response":{
      "acquirerCode":"00",
      "gatewayCode":"APPROVED"
   },
   "result":"SUCCESS",
   "sourceOfFunds":{
      "provided":{
         "card":{
            "brand":"MASTERCARD",
            "expiry":{
               "month":"1",
               "year":"39"
            },
            "fundingMethod":"CREDIT",
            "issuer":"<issuer>",
            "number":"512345xxxxxx0008",
            "scheme":"Mastercard",
            "storedOnFile":"NOT_STORED"
         }
      },
      "type":"CARD"
   },
   "timeOfLastUpdate":"2021-04-13T02:11:57.049Z",
   "timeOfRecord":"2021-04-13T02:11:56.973Z",
   "transaction":{
      "acquirer":{
         "batch":1,
         "id":"<acquirer_id>",
         "merchantId":"99554411"
      },
      "amount":100.00,
      "authenticationStatus":"AUTHENTICATION_SUCCESSFUL",
      "authorizationCode":"028941",
      "currency":"AUD",
      "id":"1",
      "receipt":"1908266016",
      "reference":"807a01b6-e6c8-4aa7-b8da-799bfff89496",
      "source":"INTERNET",
      "stan":"496",
      "terminal":"1234",
      "type":"PAYMENT"
   },
   "version":"60"
}