3D Secure

Migrating to 3D Secure 2anchor

Start hereanchor

  • 3D Secure 2 (3DS2) is the next iteration of the 3DS authentication protocol.
  • It satisfies the Strong Customer Authentication (SCA) requirements for European merchants transacting with European customers. In order to comply with SCA we recommend integrating 3DS2 and testing as soon as possible.
  • 3DS2 support was introduced in the Android v3, iOS v4, and JavaScript v3 versions of our Client SDKS.
  • This migration guide will walk you through upgrading a legacy 3DS1 integration
important

If you don't have an existing 3DS integration, use our full, updated 3D Secure integration guide instead of this migration guide.

About 3DS2anchor

This new version of 3DS is designed to primarily do two things:

First and foremost, the protocol allows more data elements to be passed to issuing banks, which in turn allows them to perform a much more effective risk assessment of a given authentication. As a result, issuing banks will be able to allow more authentications to proceed without challenging the cardholder.

Second, the authentication challenges themselves are designed to be more effective and secure, especially for mobile devices, resulting in fewer authentication challenges and less friction during checkout workflows. You can find a lot more details and context in our blog post about 3DS2.

Enabling 3DS2anchor

Drop-in UIanchor

important

3DS2 support requires Drop-in version 1.20.1 or higher.

To use 3DS, you will need to pass an object with relevant customer and transaction data into the threeDSecure field of the requestPaymentMethod options in order to minimize the need for issuing banks to present authentication challenges to customers. This object must contain an amount and should contain as many of the following fields as possible:

  1. JavaScript
var threeDSecureParameters = {
  amount: '500.00',
  email: 'test@example.com',
  billingAddress: {
    givenName: 'Jill', // ASCII-printable characters required, else will throw a validation error
    surname: 'Doe', // ASCII-printable characters required, else will throw a validation error
    phoneNumber: '8101234567',
    streetAddress: '555 Smith St.',
    extendedAddress: '#5',
    locality: 'Oakland',
    region: 'CA', // ISO-3166-2 code
    postalCode: '12345',
    countryCodeAlpha2: 'US'
  },
  additionalInformation: {
    workPhoneNumber: '8101234567',
    shippingGivenName: 'Jill',
    shippingSurname: 'Doe',
    shippingPhone: '8101234567',
    shippingAddress: {
      streetAddress: '555 Smith St.',
      extendedAddress: '#5',
      locality: 'Oakland',
      region: 'CA', // ISO-3166-2 code
      postalCode: '12345',
      countryCodeAlpha2: 'US'
    }
  },
};

Then, create the Drop-in and pass in the 3DS parameters accordingly.

  1. Callback
  2. Promise
braintree.dropin.create({
    authorization: 'CLIENT_AUTHORIZATION',
    container: '#dropin-container',
    threeDSecure: true
}, function (err, dropinInstance) {
    if (err) {
        // Handle any errors that might've occurred when creating Drop-in
        console.error(err);
        return;
    }

    submitButton.addEventListener('click', function (e) {
        e.preventDefault();
        dropinInstance.requestPaymentMethod({
          threeDSecure: threeDSecureParameters
        }, function (err, payload) {
            if (err) {
                // Handle errors in requesting payment method
            }
            // Send payload.nonce to your server
        });
    });
});

Hosted Fieldsanchor

important

3DS2 support requires Braintree version 3.52.0 or higher.

To use 3DS, you will need to pass an object with relevant customer and transaction data into the threeDSecure field of the requestPaymentMethod options in order to minimize the need for issuing banks to present authentication challenges to customers.

This object must contain the following fields:

  • amount
  • bin
  • nonce

And should contain as many of the following fields as possible:

You will also need to implement the required callback onLookupComplete, which will be invoked after receiving the ThreeDSecure lookup response, before initializing the challenge and completing the flow.

  1. JavaScript
var threeDSecureParameters = {
  amount: '500.00',
  nonce: NONCE_FROM_INTEGRATION, // Example: hostedFieldsTokenizationPayload.nonce
  bin: BIN_FROM_INTEGRATION, // Example: hostedFieldsTokenizationPayload.details.bin
  email: 'test@example.com',
  billingAddress: {
    givenName: 'Jill', // ASCII-printable characters required, else will throw a validation error
    surname: 'Doe', // ASCII-printable characters required, else will throw a validation error
    phoneNumber: '8101234567',
    streetAddress: '555 Smith St.',
    extendedAddress: '#5',
    locality: 'Oakland',
    region: 'CA', // ISO-3166-2 code
    postalCode: '12345',
    countryCodeAlpha2: 'US'
  },
  additionalInformation: {
    workPhoneNumber: '8101234567',
    shippingGivenName: 'Jill',
    shippingSurname: 'Doe',
    shippingPhone: '8101234567',
    shippingAddress: {
      streetAddress: '555 Smith St.',
      extendedAddress: '#5',
      locality: 'Oakland',
      region: 'CA', // ISO-3166-2 code
      postalCode: '12345',
      countryCodeAlpha2: 'US'
    }
  },
  onLookupComplete: function (data, next) {
    // use 'data' here, then call 'next()'
    next();
  }
};

Specify version: 2 in your options object when calling threeDSecure.create(). This allows your transactions to route through the 3DS2 protocol.

  1. Callback
  2. Promise
var threeDSecure;

braintree.client.create({
  // Use the generated client token to instantiate the Braintree client.
  authorization: 'CLIENT_TOKEN_FROM_SERVER'
}, function (clientErr, clientInstance) {
  if (clientErr) {
    // Handle error in client creation
    return;
  }

  braintree.threeDSecure.create({
    version: 2, // Will use 3DS2 whenever possible
    client: clientInstance
  }, function (threeDSecureErr, threeDSecureInstance) {
    if (threeDSecureErr) {
      // Handle error in 3D Secure component creation
      return;
    }

    threeDSecure = threeDSecureInstance;
  });
});

Then, call verifyCard, passing in the 3D Secure Parameters.

  1. Callback
  2. Promise
threeDSecure.verifyCard(threeDSecureParameters, function (err, response) {
  // Handle response
});

Client-side sandbox testinganchor

Please see the Testing and Go Live guide.

Server-side sandbox testinganchor

If you call Transaction.Sale() without doing a 3DS authentication on the client-side, the issuing bank may return a soft decline indicating that the transaction requires 3DS authentication. In this case, 2099 - Cardholder Authentication Required will be returned. You can simulate this scenario by creating a test transaction in sandbox with an amount of 2099.

Verifications and recurring billinganchor

Recurring transactionsanchor

The recommended flow for recurring billing would be to request a cardholder challenge to establish SCA when the card is first authorized as part of storing it to the Braintree vault. This can be with a verification, or the first transaction of a recurring billing event. By applying 3D Secure to the first transaction or verification, you signal to the card issuer that you have established a mandate between you and your customer to charge their payment method for subsequent recurring payments as detailed in your terms and conditions. Such subsequent transactions are exempt from PSD2 SCA requirements.

Establishing SCA on verifications will be useful for scenarios where the cardholder will not be present when the charge is issued, and the amount isn’t known when the payment method is stored. For example, if you have a metered billing flow and invoice customers at the end of a month based on their usage, you can use 3D Secure on your initial card verification to establish a mandate to create future merchant initiated transactions (MIT).

For subsequent transactions from that payment method, use the recurring value in the transaction_source parameter of the Transaction.Sale() API call.

Other merchant initiated transactions (MIT)anchor

Other MIT transactions will be processed much the same way that recurring transactions would be. You would again request a cardholder challenge to establish SCA when the card is first authorized, establishing a mandate between you and your customer.

For subsequent transactions from that payment method, which would be out of scope for SCA, use the unscheduled value in the transaction_source parameter of the Transaction.Sale() API call.

Requesting a cardholder challengeanchor

To override the default behavior of 3DS2 and request the cardholder's bank to issue an authentication challenge, pass challengeRequested: true on the verifyCard() call.

One scenario where you may want to send challengeRequested is if you are experiencing a significant amount of 2099 processor declines due to frictionless 3D Secure being applied. Frictionless 3D Secure is when there was no 3D Secure challenge presented to the customer as determined by the 3D Secure lookup process. Some banks are strict in their SCA enforcement and will require the cardholder challenge even if frictionless 3D Secure is successful. Although requesting challenges can help reduce frictionless related declines, the bank has an ultimate say in whether it will or not decline a transaction.

Exceptions for already-stored payment methodsanchor

Exceptions would apply for payment methods stored before September 14, 2019, or subscriptions started before that date. For these payment methods, SCA would not have to be applied to the first authorization for subsequent transactions to be out of scope for PSD2.

As long as your payment methods are stored with Braintree, Braintree will automatically indicate to the card networks and issuers that these payment methods were stored before the PSD2 SCA enforcement date.

We expect, however, that you will have a lower decline rate if there has been at least one transaction or verification before September 14. This transaction history, in conjunction with the indicators Braintree will pass, will more clearly indicate to issuers that they will not be under regulatory pressure to decline recurring/MIT transactions from these payment methods. However, the transaction history is not expressly required.

What to expect after adopting 3DS2anchor

After adopting 3DS2, you may still see 3DS1 authentications using your updated integration. This is to be expected – 3DS2 is an industry-wide initiative, requiring many parties' participation in order for a 3DS2 authentication to be possible. Each party has steps to complete, and 3DS verification will use the 3DS2 protocol once all parties involved in a given transaction have made the appropriate upgrades:

  1. You must update your integration to pass the necessary information to support 3DS2 cardholder verifications.
  2. Braintree must work with acquirers to enable merchant accounts for 3DS2.
  3. Cardholders' issuing banks must upgrade their systems to support 3DS2 cardholder verifications.

By completing the steps in this guide, you ensure that everything on the merchant side is ready to go. You will start seeing 3DS2 authentications as other parties complete their part of the protocol.

While the rest of the industry completes their work, Braintree’s integration will automatically fall back to a 3DS1 authentication path on a transaction-by-transaction basis when 3DS2 is not available from all parties involved.

Common questionsanchor

Do you have an example of how to integrate?anchor

Yes, we have some examples in CodePen:

Can merchants customize the presentation of the bank challenge?anchor

No. The presentation will be controlled by the issuing bank. This means that unlike prior versions, you will not need to provide the iframe or utilize the addFrame and removeFrame callbacks.

What happens if some of the additional parameters are not present?anchor

The bank will decide if a challenge is necessary. Sending all additional parameters will result in the best chance for a frictionless experience.

Will vaulted credit cards be supported?anchor

Yes, create a nonce from a vaulted credit card as usual.

Advanced featuresanchor

Authentication Insightanchor

Authentication Insight provides you with more details about the regulatory environment and applicable customer authentication regulation for a potential transaction. This empowers you to make an informed decision whether to perform 3D Secure authentication.

You can use the regulation environment information contained in the Authentication Insight to make a decision about whether to perform a 3D Secure verification, or continue without a verification. If you choose to perform a 3D Secure verification, proceed as usual using the payment method nonce.

The regulation environment field currently has three possible values:

Regulation Environment Description
psd2 The impending transaction (when using the provided payment method nonce and merchant account) is believed to be within scope of PSD2 SCA regulations, and requires 3D Secure authentication.
unregulated The impending transaction is not believed to be within scope of any SCA regulations, PSD2 or otherwise.
unavailable The impending transaction’s SCA regulation environment could not be determined.

As global regulations evolve, these values will continue to be updated.

To request Authentication Insight, include authenticationInsight.merchantAccountId in the options object you pass to Hosted Fields:

  1. Callback
  2. Promise
hostedFieldsInstance.tokenize({
  authenticationInsight: {
    merchantAccountId: 'merchant-account-id'
  }
}, function (tokenizeErr, payload) {
  if (tokenizeErr) {
    // Handle error
  } else {
    // access regulation environment
    var regulationEnvironment = payload.authenticationInsight.regulationEnvironment);
  }
});

To request Authentication Insight for a vaulted payment method, use the Server SDKs.

Testinganchor

Currently, we have test cards available that can return the various regulation environment values when authentication insight is requested on tokenization, depending on the merchant account that is specified:

Test Value Card Information Regulation Environment Value
4012000033330620 country of issuance = "USA" unregulated
4023490000000008 country of issuance = "IRL"
  • psd2 if using a merchant account acquired in the European Economic Area (EEA)
  • unregulated if using a merchant account acquired outside the EEA
  • unavailable if using a merchant account where acquirer country is unknown or has not been specified

PSD2 SCA exemptionsanchor

Merchants can request exemptions for certain transactions from requiring SCA. Exemptions are granted completely at the discretion of the issuer, and are never guaranteed. If an exemption is requested, and then granted by the issuer, authentication will not be required. However, in this case, the liability remains with the merchant and is not shifted to the issuer.

Braintree's client SDKs provide the ability to request an exemption for a given authentication. If you request an exemption, Braintree will automatically request the most appropriate exemption from the issuer.

Please note that issuers are currently upgrading their systems to support 3DS2 as well as PSD2 SCA exemptions; many issuers may not support some or all exemptions at this time.

For more information on exemptions, please read our blog on PSD2 SCA exemptions.

Client-side implementationanchor

To request an exemption, set exemptionRequested: true in the verifyCard() parameters.

Server-side implementationanchor

If you perform a 3D Secure authentication, the exemption request along with any exemption granted by the issuer will automatically be applied to the associated transaction; no exemption information is then required in the Transaction.sale() call.

If you do not perform a 3D Secure authentication, but wish to request a SCA exemption to your transaction, you can do so by supplying the scaExemption field via the Transaction.sale() call.

In the future we will expand the options to allow Braintree's client SDKs to provide the ability to request an exemption for a given authentication. When an exemption is requested, Braintree will automatically request the most appropriate exemption from the issuer.

Using your own 3D Secure MPI provideranchor

If you perform a 3D Secure authentication with your own MPI provider and receive an SCA exemption from the issuer via 3D Secure, you'll need to specify which exemption was obtained in the Transaction.sale() call. This feature is currently under development and not yet available.

Recurring billing with an external vaultanchor

If you maintain your own vault, you will be able to provide a static network transaction identifier (NTI) in the previous_network_transaction_id field. You'll use a static NTI field in subsequent transactions in order to indicate that the initial transaction occurred before September 14, 2019, the PSD2 SCA enforcement date. We are currently working with the card networks to obtain the proper static NTI values and we will provide them when they are available.