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
, andpostalCode
.
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 |
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. |
|
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. |
|
Yes, if you are manually collecting device data. |
browserLanguage | The string value of the browser's setting for the user's selected language. |
|
Yes, if you are manually collecting device data. |
browserColorDepth | The string value of the user's screen's color depth. |
|
Yes, if you are manually collecting device data. |
browserScreenHeight | The string value of the user's screen's height. |
|
Yes, if you are manually collecting device data. |
browserScreenWidth | The string value of the user's screen's width. |
|
Yes, if you are manually collecting device data. |
browserTimeZone | The string value of the user's timezone |
|
Yes, if you are manually collecting device data. |
deviceChannel | This is required to be 'Browser' | 'Browser' | Yes, if you are manually collecting device data. |
If running 3DS with Collect.js,
paymentToken
will replace card details.If running payer Authentication with Customer Vault, only include
customerVaultToken
,currency
, andamount
.
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
threeDSecureInterfac
e 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 |
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>
Updated 2 months ago