Payer Authentication (3DS)

3-D Secure reduces your e-commerce payment fraud risk and increases customer confidence.

Payer Authentication is a fraud prevention service that facilitates the authentication of transactions before submitting them to the gateway for processing.

Payer Authentication enables the exchange of data between the merchant, card issuer, and the customer to validate the transaction is being performed by the rightful owner.

For the majority of transactions, the authentication occurs behind the scenes without interrupting the customer. Otherwise known as frictionless flows. In rare instances, the issuer may request a challenge. This step-up authentication flow would require the customer to validate themselves through additional information such as a one-time password.

This additional verification data is submitted in the transaction request and protects you from fraudulent transactions, chargebacks, and malicious behavior.

Quick Start Guide

2. Initialize Payer Authentication

threeDS = gateway.get3DSecure()

  • If running Payer Authentication with Collect.js: Render a Collect.js form to collect the credit card information. Use Collect.js's configure() method to supply a callback. The callback will create the 3DS interface and provide the Collect.js payment token in place of the credit card details.

3. Create an interface object with the details of the transaction

The details should include:

  • cardNumber, cardExpMonth, cardExpYear,
  • currency, amount,
  • firstName, lastName
  • email,
  • address1, city, state, country, and postalCode.
ThreeDSecureUI Parameters
Variable Description When Received
cardNumber The card number to run 3DS for '4111111111111111'

Yes, if using raw credit card data

No, if using paymentToken or customerVaultId

cardExpMonth 2 digit card expiration date for the month '07' (meaning July)

Yes, if using raw credit card data

No, if using paymentToken or customerVaultId

cardExpYear 2 or 4 digit card expiration year
'2021'
'24'

Yes, if using raw credit card data

No, if using paymentToken or customerVaultId

paymentToken Token from Collect.js '00000000-000000-000000-000000000000'

Yes, if using Collect.js

No, if using raw card data or customerVaultId

customerVaultId Merchant defined Customer Vault id. This is not the billing id or shipping id. '12345'

Yes, if using Customer Vault

No, if using raw card data or paymentToken

currency The 3 character currency code for the transaction.
'USD'
'GBP'
Yes
amount The amount of the transaction in minor units. If the customer is challenged, this value will be displayed on the challenge screen. '1000' (meaning 10 USD) Yes
email The email address of the cardholder that owns the card. Required (if available) unless market or regional mandate restricts sending this information. '[email protected]' Yes, if applicable
city The cardholder's city. Required (if available) unless market or regional mandate restricts sending this information. 'Atlanta' Yes, if applicable
address1 The cardholder's address. Required (if available) unless market or regional mandate restricts sending this information. '123 Fake St.' Yes, if applicable
address2 The cardholder's address 'APT 1' No
address3 The cardholder's address 'Unit 1' No
country The customer's country. 2 Characters, ISO 3166. Required (if available) unless market or regional mandate restricts sending this information. 'US' Yes, if applicable
firstName The first name of the cardholder 'Jane' Yes
lastName The last name of the cardholder 'Doe' Yes
postalCode The zip code or postal code of the cardholder. Required (if available) unless market or regional mandate restricts sending this information. '60605' Yes, if applicable
state The state, province, or other subdivision of the cardholder. This field must be a 2 character subdivision code defined by ISO 3166-2. Required (if available) unless market or regional mandate restricts sending this information. 'GA' Yes, if applicable
phone The phone number of the cardholder '8008675309' No
shippingCity City the cardholder would like their purchase shipping to 'Chicago' No
shippingAddress1 Address the cardholder would like their purchase shipping to '123 Fake st' No
shippingAddress2 Address the cardholder would like their purchase shipping to 'APT 2' No
shippingAddress3 Address the cardholder would like their purchase shipping to 'Unit 1' No
shippingCountry Country the cardholder would like their purchase shipping to. 2 characters, ISO 3166. 'US' No
shippingFirstName First name of the recipient 'John' No
shippingLastName Last name of the recipient 'Doe' No
shippingPostalCode Zip code or postal code the cardholder would like their purchase shipping to '60605' No
shippingState The state, province, or other subdivision of the cardholder. This field must be a 2 character subdivision code defined by ISO 3166-2. 'GA' No
processor

The processor id that will be used to run the transaction.

Processor ids can be found in the merchant portal in Transaction Routing

'myprocessor' No, if not provided the system will automatically use your default processor
challengeIndicator

The 2-digit 3DS challenge indicator you would like to pass along with the 3DS request.

Requests that the card issuer does or doesn't challenge a customer.

'01' - No preference

'02' - No challenge requested

'03' - Challenge requested (3DS Requestor preference)

'04' - Challenge requested (Mandate)

'05' - No challenge requested (transactional risk analysis is already performed)

'06' - No challenge requested (data share only)

'07' - No challenge requested (strong consumer authentication is already performed)

'08' - No challenge requested (utilise allowlist exemption if no challenge required)

'09' - Challenge requested (allowlist prompt requested if challenge required)

No, if not provided the system will automatically use '01' - No preference.
browserJavaEnabled

The string value of the browser's setting for if Java is enabled.

As this is a deprecated field for most modern browsers, a try/catch is recommended to future-proof your integration.

try {
    const userBrowserJavaEnabled = String(window.navigator.javaEnabled());
} catch(e) {
    const userBrowserJavaEnabled = String(false);
}
/* In threeDsService.createUI(): */
browserJavaEnabled: userBrowserJavaEnabled
Yes, if you are manually collecting device data.
browserJavascriptEnabled

The string value of the browser's setting for if Javascript is enabled.

Since using Gateway.js requires the user's browser to have Javascript enabled, it is safe to default this to true.

String(true)
Yes, if you are manually collecting device data.
browserLanguage The string value of the browser's setting for the user's selected language.
window.navigator.language || window.navigator.userLanguage
Yes, if you are manually collecting device data.
browserColorDepth The string value of the user's screen's color depth.
String(window.screen.colorDepth)
Yes, if you are manually collecting device data.
browserScreenHeight The string value of the user's screen's height.
String(window.screen.height)
Yes, if you are manually collecting device data.
browserScreenWidth The string value of the user's screen's width.
String(window.screen.width)
Yes, if you are manually collecting device data.
browserTimeZone The string value of the user's timezone
String(new Date().getTimezoneOffset())
Yes, if you are manually collecting device data.
deviceChannel This is required to be 'Browser' 'Browser' Yes, if you are manually collecting device data.
* cardholder_info should not be passed into the API and should be displayed to the customer if a value is present.

If running 3DS with Collect.js, paymentToken will replace card details.

If running payer Authentication with Customer Vault, only include customerVaultToken, currency, and amount.

To respond to various results from processing, your application can subscribe to events emitted from the created interface.

4. Start the authentication process

Mount the interface to the DOM by providing a selector. The frame will be mounted inside the provided element.

JavaScript frameworks such as React, Vue, or Angular may control the DOM in such a way that would cause the frame to become detached from the DOM. To ensure that a mounted interface remains on the page, you may need to prevent them from managing the mount point.

5. Attach callbacks

Callbacks listen for when the customer finishes authenticating themselves.

  • Listen for the threeDSecureInterface to ask the user for a password
  • Listen for the threeDSecureInterface to provide all the needed 3DS data
  • Listen for the threeDSecureInterface to indicate that the customer has failed to authenticate
  • Listen for any errors that might occur.

6. Send 3DS data to your backend

Implement a callback for the complete event that sends the 3DS data to your backend.

7. Submit the 3DS data via the Payment API with your private key.

Payer Authentication Variables
Variable Description When Received
cavv

Cardholder Authentication Verification Value

The value that signifies that a customer was successfully authenticated.

On all successful authentications
xid A transaction identifier from authentication processing Occasionally provided for some card brands
directory_server_id A transaction identifier assigned by the directory server. On all successful 3DS2 authentications
eci A number that indicates the result of the attempt to authenticate the cardholder. Values are dependent on the card brand. On successful authentications
cardholder_auth

A string describing if a customer was successfully verified or attempted.

"verified" indicates that a cardholder's bank successfully verified the user.

"attempted" indicates that a cardholder is enrolled in 3DS, but their bank does not support 3DS.

Examples: verified, attempted

On successful authentications
three_ds_version
Determines which version of 3DS was used.
Examples: 1.0.2, 2.1.0, 2.2.0
On all successful authentications
cardholder_info*
Text provided by the ACS/Issuer to Cardholder.
Example: Additional authentication is needed for this transaction, please contact (Issuer Name) at xxx-xxx-xxxx.
Occasionally provided for frictionless transactions
* cardholder_info should not be passed into the API and should be displayed to the customer if a value is present.

HTML Example Files

<html>
    <body>
    <script src="https://secure.networkmerchants.com/js/v1/Gateway.js"></script>
    <script>
        // Initialize Gateway.js
        const gateway = Gateway.create('collect_checkout_0000000000000000000000');

        // Initialize the ThreeDSService
        const threeDS = gateway.get3DSecure();

        // Create a 3DS Frame
        // This will start out 0px x 0px during fingerprinting.
        // If the customer is prompted to complete a challenge, it will resize automatically.
        const options = {
            cardNumber: "4111111111111111",
            cardExpMonth: "01",
            cardExpYear: "2024",
            currency: 'USD',
            amount: '10.00',
            email: '[email protected]',
            phone: '8008675309',
            city: 'New York',
            state: 'NY',
            address1: '123 First St.',
            country: 'US',
            firstName: 'Jane',
            lastName: 'Doe',
            postalCode: '60001'
        };

        const threeDSecureInterface  = threeDS.createUI(options);

        // Mount the threeDSecureInterface to the DOM
        // This begins the collection of 3DS data.
        threeDSecureInterface.start('body');

        // Listen for the threeDSecureInterface to ask the user for a password
        threeDSecureInterface.on('challenge', function(e) {
            console.log('Challenged');
        });

        // Listen for the threeDSecureInterface to provide all the needed 3DS data
        threeDSecureInterface.on('complete', function(e) {
            fetch('direct-post-back-end.php', {
                method: 'POST',
                body: JSON.stringify({
                    ...options,
                    cavv: e.cavv,
                    xid: e.xid,
                    eci: e.eci,
                    cardHolderAuth: e.cardHolderAuth,
                    threeDsVersion: e.threeDsVersion,
                    directoryServerId: e.directoryServerId,
                    cardHolderInfo: e.cardHolderInfo,
                })
            })
        });

        // Listen for the threeDSecureInterface to indicate that the customer
        // has failed to authenticate
        threeDSecureInterface.on('failure', function(e) {
            console.log('failure');
            console.log(e);
        });

        // Listen for any errors that might occur.
        gateway.on('error', function (e) {
            console.error(e);
        })
    </script>
    </body>
</html>
<html>
<body>
    <label>Credit Card Number</label>
    <div id="ccnumber"></div>
    <label>CC EXP</label>
    <div id="ccexp"></div>
    <label>CVV</label>
    <div id="cvv"></div>
    <button id="payButton">Pay Now</button>

    <div id="threeDSMountPoint"></div>
    <script src="https://secure.networkmerchants.com/js/v1/Gateway.js"></script>
    <script
       src="https://secure.networkmerchants.com/token/Collect.js"
       data-tokenization-key="000000-111111-222222-333333"
    ></script>
    <script>
        const gateway = Gateway.create('checkout_public_00000000000000000000000000000000');
        const threeDS = gateway.get3DSecure();

        window.addEventListener('DOMContentLoaded', () => {
           CollectJS.configure({
               variant: 'inline',
               callback: (e) => {
                   const options = {
                       paymentToken: e.token,
                       currency: 'USD',
                       amount: '1000',
                       email: '[email protected]',
                       phone: '8008675309',
                       city: 'New York',
                       state: 'NY',
                       address1: '123 Fist St.',
                       country: 'US',
                       firstName: 'John',
                       lastName: 'Doe',
                       postalCode: '60001'
                   };

                   const threeDSecureInterface = threeDS.createUI(options);
                   threeDSecureInterface.start('#threeDSMountPoint');

                   threeDSecureInterface.on('challenge', function(e) {
                       console.log('Challenged');
                   });

                   threeDSecureInterface.on('complete', function(e) {
                       console.log(e);
                       fetch('direct-post-back-end.php', {
                           method: 'POST',
                           body: JSON.stringify({
                               ...options,
                               cavv: e.cavv,
                               xid: e.xid,
                               eci: e.eci,
                               cardHolderAuth: e.cardHolderAuth,
                               threeDsVersion: e.threeDsVersion,
                               directoryServerId: e.directoryServerId,
                               cardHolderInfo: e.cardHolderInfo,
                           })
                       })
                   });

                   threeDSecureInterface.on('failure', function(e) {
                       console.log('failure');
                       console.log(e);
                   });
               }
           })

           gateway.on('error', function (e) {
               console.error(e);
           })
        })
    </script>
</body>
</html>
<html>
<body>
<script src="https://secure.networkmerchants.com/js/v1/Gateway.js"></script>
<script>
   const gateway = Gateway.create('collect_checkout_0000000000000000000');
   const threeDS = gateway.get3DSecure();

   const options = {
       customerVaultId: "myCustomerVaultToken",
       currency: 'USD',
       amount: '1000'
   };

   const threeDSsecureInterface = threeDS.createUI(options);
   threeDSsecureInterface.start('body');

   threeDSsecureInterface.on('challenge', function(e) {
       console.log('Challenged');
   });

   threeDSsecureInterface.on('complete', function(e) {
       fetch('direct-post-back-end.php', {
           method: 'POST',
           body: JSON.stringify({
               ...options,
               cavv: e.cavv,
               xid: e.xid,
               eci: e.eci,
               cardHolderAuth: e.cardHolderAuth,
               threeDsVersion: e.threeDsVersion,
               directoryServerId: e.directoryServerId,
               cardHolderInfo: e.cardHolderInfo,
           })
       })
           .then(e => {

           })
   });

   threeDSsecureInterface.on('failure', function(e) {
       console.log('failure');
       console.log(e);
   });

   gateway.on('error', function (e) {
       console.error(e);
   })
</script>
</body>
</html>

Manual Device Data Collection

Payer Authentication attempts to collect device data from the customer's browser, but sometimes this process can timeout and cause the request to fail. You can account for these timeouts by manually collecting the eight device data fields for the options array passed to the threeDS.createUI() call.

  • browserJavaEnabled, browserJavascriptEnabled, browserLanguage, browserColorDepth, browserScreenHeight, browserScreenWidth, browserTimeZone, deviceChannel

The example below uses the base Gateway.js integration, but you can also collect the device data fields for any integrations documented above.

        <html>
    <body>
    <script src="https://secure.networkmerchants.com/js/v1/Gateway.js"></script>
    <script>
        // Initialize Gateway.js
        const gateway = Gateway.create('collect_checkout_0000000000000000000000');

        // Initialize the ThreeDSService
        const threeDS = gateway.get3DSecure();

        // Create a 3DS Frame
        // This will start out 0px x 0px during fingerprinting.
        // If the customer is prompted to complete a challenge, it will resize automatically.

        // window.navigator.javaEnabled() is deprecated in modern browsers, use a try/catch to future-proof your code
        try {
            const userBrowserJavaEnabled = String(window.navigator.javaEnabled());
        } catch(e) {
            const userBrowserJavaEnabled = String(false);
        }

        const options = {
            cardNumber: "4111111111111111",
            cardExpMonth: "01",
            cardExpYear: "2024",
            currency: 'USD',
            amount: '10.00',
            email: '[email protected]',
            phone: '8008675309',
            city: 'New York',
            state: 'NY',
            address1: '123 First St.',
            country: 'US',
            firstName: 'Jane',
            lastName: 'Doe',
            postalCode: '60001',
            browserJavaEnabled: userBrowserJavaEnabled,
            browserJavascriptEnabled: String(true),
            browserLanguage: window.navigator.language || window.navigator.userLanguage,
            browserColorDepth: String(window.screen.colorDepth),
            browserScreenHeight: String(window.screen.height),
            browserScreenWidth: String(window.screen.width),
            browserTimeZone: String(new Date().getTimezoneOffset()),
            deviceChannel: 'Browser'
        };

        const threeDSecureInterface  = threeDS.createUI(options);

        // Mount the threeDSecureInterface to the DOM
        // This begins the collection of 3DS data.
        threeDSecureInterface.start('body');

        // Listen for the threeDSecureInterface to ask the user for a password
        threeDSecureInterface.on('challenge', function(e) {
            console.log('Challenged');
        });

        // Listen for the threeDSecureInterface to provide all the needed 3DS data
        threeDSecureInterface.on('complete', function(e) {
            fetch('direct-post-back-end.php', {
                method: 'POST',
                body: JSON.stringify({
                    ...options,
                    cavv: e.cavv,
                    xid: e.xid,
                    eci: e.eci,
                    cardHolderAuth: e.cardHolderAuth,
                    threeDsVersion: e.threeDsVersion,
                    directoryServerId: e.directoryServerId,
                    cardHolderInfo: e.cardHolderInfo,
                })
            })
        });

        // Listen for the threeDSecureInterface to indicate that the customer
        // has failed to authenticate
        threeDSecureInterface.on('failure', function(e) {
            console.log('failure');
            console.log(e);
        });

        // Listen for any errors that might occur.
        gateway.on('error', function (e) {
            console.error(e);
        })
    </script>
    </body>
</html>