Live Webinar

Evaluating 3DS: Is It Worth It?

3D Secure Buyer's Guide

3D Secure buyer's guide: what to check before you pick a vendor


First up, if 3D Secure (3DS) is a fairly new concept to you, we’ve written an everything you need to know about 3DS guide to quickly get you up to speed.

Disclaimer: Evervault has its own 3DS solution, so we are biased, but all arguments made are rooted in logic and reality.

TL;DR: If you work with one PSP and have no plans to add any more, use their built-in 3DS. If you work with more than one PSP, or plan to, a standalone 3DS vendor, like Evervault, gives you one implementation, one set of results, and the ability to retry across PSPs without re-authenticating your customer.

When you're comparing providers, here are the key things you should consider.

  • Do you want to use PSPs built-in 3DS solutions or a standalone solution?

  • Do they run their own 3DS server?

  • How complex is it to integrate, set up, and debug?

  • What’s the end user experience like?

  • What options do you have to reduce friction?

  • Does the vendor reduce your PCI compliance scope?Built-in 3DS or standalone

Built-in 3DS or standalone

If you only work with one PSP, use their built-in 3DS. Adyen, Checkout.com, and Stripe can also automate authentication decisioning and retry logic based on issuer signals, which are especially powerful when combined with their fraud products.

The moment you work with more than one PSP, or plan to, built-in 3DS breaks down (see our guide on multi-PSP routing if you’re building this out). A 3DS authentication is tied to the PSP that processed it. If you retry a failed payment on a different PSP, you have to re-authenticate the customer from scratch. This hurts conversion rates.

Without standalone 3DS

Cardholder
3DS auth

Challenge + approved

Provider A
Declined

Start again

Cardholder needs to re-authenticate to retry with different PSP

With standalone 3DS

Cardholder
3DS auth

Challenge + approved

Provider A
Declined
Provider B
Approved

Cardholder challenged once

Same auth credential

Without standalone 3DS

Cardholder
3DS auth

Challenge + approved

Provider A
Declined

Start again

Cardholder needs to re-authenticate to retry with different PSP

With standalone 3DS

Cardholder
3DS auth

Challenge + approved

Provider A
Declined
Provider B
Approved

Cardholder challenged once

Same auth credential

Without standalone 3DS

Cardholder
3DS auth

Challenge + approved

Provider A
Declined

Start again

Cardholder needs to re-authenticate to retry with different PSP

With standalone 3DS

Cardholder
3DS auth

Challenge + approved

Provider A
Declined
Provider B
Approved

Cardholder challenged once

Same auth credential

Not only does re-authentication get in the way, you lose visibility too. Every PSP reports 3DS results in their own format, so building one view of your authentication performance means pulling and reconciling data from each of them yourself. A standalone vendor gives you that unified view by default, since every authentication, regardless of which PSP you route the payment through afterward, comes from the same place.

Standalone solutions typically come in two flavors: those that only do 3DS, and those that offer 3DS alongside other products, typically payment encryption or tokenization. All 3DS products are built to the same specification as per the latest protocol version, so everyone pretty much shares ~90% of the capability.

In our experience, these are the factors that matter when evaluating standalone 3DS solutions.

What to check when you compare 3DS vendors

Do they run their own 3DS server?

Some vendors build and run their own EMVCo-certified 3DS server. Others resell someone else's solution. You can check without taking their word for it. EMVCo publishes a public list of every company holding a 3DS license. Search the vendor's name and see if they have a Server license.

Source: EMVCo 3DS Approved Products Directory

Why this matters

If a vendor is reselling someone else's server, three things are true.

Product control is limited: You can't credibly promise what you don't build, so your feature requests are unlikely to be delivered.

In contrast, because Evervault owns its 3DS Server, we can develop features like fail-on-challenge that let customers in non-SCA-mandated regions attempt 3DS authentication to shift liability, but automatically terminate the authentication if the issuer steps up to a challenge. See our Flighthub case study for more info.

A reseller doesn't have that option, because the underlying server belongs to someone else. This extends to the latest EMVCo 3DS versions. A vendor with their own server decides when to certify against a new version. A reseller doesn’t.

Every hop adds latency and risk: Requests routed through a reseller go through an extra layer before reaching the actual 3DS server. Small delays compound. And when something breaks, the reseller's team has to first work out whether the problem is theirs or the underlying vendor's, then file a ticket and wait in someone else's support queue.

It’s more expensive: The reseller needs to take their cut.

How complex is it to integrate, set up, and debug?

Conforming to the 3DS spec and building a good implementation of it are different things. Two 3DS solutions can both be EMVCo-certified and still be wildly different products. Virtually all 3DS solutions default to exposing the entire spec and leaving you to figure it out. We think that’s a terrible developer experience, so we’ve abstracted as much of that complexity as possible but give you full customizability for more complex use-cases.

When assessing vendors, you want to be looking at:

Integration

With Evervault, integration takes less than an hour: one backend call, one frontend SDK load. This should be the standard, but it isn’t. Most other vendors hand you a multi-step flow you have to build and maintain across front- and back-end yourself.

See what an integration actually looks like

Integrating your average 3DS solution could take weeks, if not months, because they push the implementation burden onto you. This is the logic you’d need to write, debug, and maintain across both front-end and back-end.

  1. You call the 3DS provider’s API to create the authentication request

  2. It returns a method_url that you pass to your frontend (this is technically optional but it provides a bunch of extra metadata, like device info, that helps improve authentication rates)

  3. You load an iframe with the method_url

  4. Handle the response to check if it will challenge (meaning the customer needs to complete authentication)

  5. Redirect to the ACS (issuer) for the challenge

  6. Capture the result and send it to the backend

  7. Complete the flow with another API call (ARes, etc.)

In contrast, this is what it looks like with Evervault.

  1. Call Evervault from your backend to create a 3DS session (this returns a session_id)

  2. Load Evervault’s JavaScript SDK on your frontend using the session_id

We handle everything else for you (loading the iframe with the method_url, managing redirects, handling challenges, etc.), including any spec changes as new protocols are released.

Orchestration logic

The 3DS specification is a huge 400+ page PDF and is inconsistent across card schemes. With Evervault, you describe what you want in plain language. (e.g., 'request an exemption', and we translate that into the correct network-specific request).

{
  "merchant": "merchant_12345",
  "card": {
    "number": "4242424242424242",
    "expiry": {
      "month": "09",
      "year": "26"
    },
  },
  "payment": {
    "type": "one-off",
    "amount": 1000,
    "currency": "eur"
  },
  "challenge": {
    "preference": "no-challenge-requested",
    "reason": "low-risk"
  },
}
{
  "merchant": "merchant_12345",
  "card": {
    "number": "4242424242424242",
    "expiry": {
      "month": "09",
      "year": "26"
    },
  },
  "payment": {
    "type": "one-off",
    "amount": 1000,
    "currency": "eur"
  },
  "challenge": {
    "preference": "no-challenge-requested",
    "reason": "low-risk"
  },
}
{
  "merchant": "merchant_12345",
  "card": {
    "number": "4242424242424242",
    "expiry": {
      "month": "09",
      "year": "26"
    },
  },
  "payment": {
    "type": "one-off",
    "amount": 1000,
    "currency": "eur"
  },
  "challenge": {
    "preference": "no-challenge-requested",
    "reason": "low-risk"
  },
}

Most 3DS solutions kind of just implement the EMVCo spec as-is, leaving you to learn the spec and configure each request to its requirements.

What it looks like with most 3DS solutions

The authentication request (AReq) on its own has almost 100 fields on it, many of which can’t be understood intuitively. EMVCo (who made the spec) doesn’t provide an interactive reference site for the spec, so you have to work out of the PDF they provide.

There are also a lot of edge cases to manage with 3DS, especially for handling exemptions and non-standard flows (like corporate cards). On top of that, every card scheme (Visa, Mastercard, Amex) implements 3DS slightly differently (values, exemptions, protocol behavior, rules, etc.) so you have to build for each one individually. There might be some shared logic you can use, but at some point you have code that’s unique to each card brand.

That means you have to work with all of the complexities around AReqs (authentication requests), ARes (authentication responses), CReq (challenge requests), CRes (challenge responses), PReq (preparation requests), and PRes (preparation responses). And build logic that handles entire payloads (numeric codes, parameter mappings, network-specific logic, etc.). Even with some of the better APIs, you still end up with calls like this.

{
  "acctNumber": "************4242",
  "acctType": "03",
  "acquirerBIN": "444444",
  "acquirerMerchantID": "2020202020202020",
  "browserAcceptHeader": "*/*",
  "browserColorDepth": "32",
  "browserIP": "37.228.206.193",
  "browserJavaEnabled": false,
  "browserJavascriptEnabled": true,
  "browserLanguage": "en-GB",
  "browserScreenHeight": "982",
  "browserScreenWidth": "1512",
  "browserTZ": "0",
  "browserUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36",
  "cardExpiryDate": "2609",


  "mcc": "4011",
  "merchantCountryCode": "372",
  "merchantName": "Test Merchant",
  "messageCategory": "01",
  "notificationURL": "https://redirect.mysite.com",
  "purchaseAmount": "1000",
  "purchaseCurrency": "978",
  "purchaseDate": "20251209171958",
  "purchaseExponent": "2",
  "threeDSCompInd": "Y",
  "threeDSRequestorAuthenticationInd": "01",
  "threeDSRequestorChallengeInd": "05",
  "threeDSRequestorID": "10020202*TestMerchant",
  "threeDSRequestorName": "3DSS_TestMerchant",
  "threeDSRequestorURL": "https://test-merchant.com",
  "threeDSServerOperatorID": "10085939",
  "threeDSServerRefNumber": "3DS_LOA_SER_EVLT_02020_202020",
  "threeDSServerTransID": "d479e672-787a-4d19-aa70-e60e71521afa",
  "threeDSServerURL": "https://visa.mysite.app/hooks/3ds/result",
  "transType": "01"
 }

{
  "acctNumber": "************4242",
  "acctType": "03",
  "acquirerBIN": "444444",
  "acquirerMerchantID": "2020202020202020",
  "browserAcceptHeader": "*/*",
  "browserColorDepth": "32",
  "browserIP": "37.228.206.193",
  "browserJavaEnabled": false,
  "browserJavascriptEnabled": true,
  "browserLanguage": "en-GB",
  "browserScreenHeight": "982",
  "browserScreenWidth": "1512",
  "browserTZ": "0",
  "browserUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36",
  "cardExpiryDate": "2609",


  "mcc": "4011",
  "merchantCountryCode": "372",
  "merchantName": "Test Merchant",
  "messageCategory": "01",
  "notificationURL": "https://redirect.mysite.com",
  "purchaseAmount": "1000",
  "purchaseCurrency": "978",
  "purchaseDate": "20251209171958",
  "purchaseExponent": "2",
  "threeDSCompInd": "Y",
  "threeDSRequestorAuthenticationInd": "01",
  "threeDSRequestorChallengeInd": "05",
  "threeDSRequestorID": "10020202*TestMerchant",
  "threeDSRequestorName": "3DSS_TestMerchant",
  "threeDSRequestorURL": "https://test-merchant.com",
  "threeDSServerOperatorID": "10085939",
  "threeDSServerRefNumber": "3DS_LOA_SER_EVLT_02020_202020",
  "threeDSServerTransID": "d479e672-787a-4d19-aa70-e60e71521afa",
  "threeDSServerURL": "https://visa.mysite.app/hooks/3ds/result",
  "transType": "01"
 }

{
  "acctNumber": "************4242",
  "acctType": "03",
  "acquirerBIN": "444444",
  "acquirerMerchantID": "2020202020202020",
  "browserAcceptHeader": "*/*",
  "browserColorDepth": "32",
  "browserIP": "37.228.206.193",
  "browserJavaEnabled": false,
  "browserJavascriptEnabled": true,
  "browserLanguage": "en-GB",
  "browserScreenHeight": "982",
  "browserScreenWidth": "1512",
  "browserTZ": "0",
  "browserUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36",
  "cardExpiryDate": "2609",


  "mcc": "4011",
  "merchantCountryCode": "372",
  "merchantName": "Test Merchant",
  "messageCategory": "01",
  "notificationURL": "https://redirect.mysite.com",
  "purchaseAmount": "1000",
  "purchaseCurrency": "978",
  "purchaseDate": "20251209171958",
  "purchaseExponent": "2",
  "threeDSCompInd": "Y",
  "threeDSRequestorAuthenticationInd": "01",
  "threeDSRequestorChallengeInd": "05",
  "threeDSRequestorID": "10020202*TestMerchant",
  "threeDSRequestorName": "3DSS_TestMerchant",
  "threeDSRequestorURL": "https://test-merchant.com",
  "threeDSServerOperatorID": "10085939",
  "threeDSServerRefNumber": "3DS_LOA_SER_EVLT_02020_202020",
  "threeDSServerTransID": "d479e672-787a-4d19-aa70-e60e71521afa",
  "threeDSServerURL": "https://visa.mysite.app/hooks/3ds/result",
  "transType": "01"
 }

This is not ideal. Our belief is you should understand 3DS enough to know what you want to happen, and then express that intent with our product (e.g., "I want to request a 3DS exemption here") in plain language. We take that intent and translate it into the correct 3DS request for each network.

Error codes

The passing of 3DS spec complexity onto you is probably most destructive when it comes to debugging. Often you’re left to decode strings like N/A_06 or U_85 by searching documentation or the EMVCo spec itself. That's real engineering time lost on every failure investigation.

At Evervault, if the protocol definition is vague, we add our own English-language representation of what the code maps to, giving you extra context. We’ve been through the pain of deciphering EMVCo specifications. You shouldn’t have to.

Here are some examples of what we mean by human-readable error codes.

What Happened

Evervault

Without Evervault

The issuer has rejected the authentication. Don’t attempt authorization.

transaction-not-permitted

transStatus:"R"

transStatusReason: “12”

Authentication denied due to suspected fraud.

suspected-fraud

transStatus:"N"

transStatusReason: “11”

The ACS is having technical issues and currently unavailable.

acs-unavailable

transStatus:“N”

transStatusReason: “22”

The directory server encountered a system failure.

directory-server-unavailable

errorCode: “403”

errorComponent: “D”

Let’s explore the first example in the table to illustrate the friction involved.

A customer tries to pay, and 3DS authentication fails.

Why it failed: The issuer (the customer's bank) rejected the authentication because this card isn't allowed to make this kind of transaction. That could be because the bank has blocked online payments on the card, the cardholder has set controls that block this type of merchant, or the card can't be used in this country. It's the issuer's decision, not a problem with your setup, and the issuer is also asking you not to go ahead with authorization.

What to do about it: Don't retry. The same card will get the same answer, whether you try again on the same PSP or route it to a different one. The best next step is to ask the customer to use a different card or payment method, or to contact their bank if they want to use this one.

What to do about it: Don't retry. The same card will get the same answer, whether you try again on the same PSP or route it to a different one. The best next step is to ask the customer to use a different card or payment method, or to contact their bank if they want to use this one.

Most 3DS vendors

{
  "transStatus": "R",
  "transStatusReason": "12"
}
{
  "transStatus": "R",
  "transStatusReason": "12"
}
{
  "transStatus": "R",
  "transStatusReason": "12"
}

To work out what this means, someone on your team has to look up both codes in the EMVCo spec. Until then, they can't tell the difference between a card that's blocked for good from a card that's only blocked by a temporary error and that's worth retrying.

Evervault

{
  "status": "failure",
  "failureReason": "transaction-not-permitted",   ← ①
  "ares": {
    "transStatus": {
      "value": "R",
      "detail": "Authentication/Account Verification Rejected; Issuer is rejecting authentication/verification"   ← ②
    },
    "transStatusReason": {
      "value": "12",
      "detail": "Transaction not permitted to cardholder"
    }
  }
}
{
  "status": "failure",
  "failureReason": "transaction-not-permitted",   ← ①
  "ares": {
    "transStatus": {
      "value": "R",
      "detail": "Authentication/Account Verification Rejected; Issuer is rejecting authentication/verification"   ← ②
    },
    "transStatusReason": {
      "value": "12",
      "detail": "Transaction not permitted to cardholder"
    }
  }
}
{
  "status": "failure",
  "failureReason": "transaction-not-permitted",   ← ①
  "ares": {
    "transStatus": {
      "value": "R",
      "detail": "Authentication/Account Verification Rejected; Issuer is rejecting authentication/verification"   ← ②
    },
    "transStatusReason": {
      "value": "12",
      "detail": "Transaction not permitted to cardholder"
    }
  }
}

See what happened at a glance. transaction-not-permitted tells you right away that this card won't work for this payment, so your checkout can prompt the customer for another payment method without anyone checking the spec.

Dig deeper when you need to. The raw codes are still there, each with a description, so your team has the full picture for investigating patterns or following up with an issuer.

What’s the end user experience like?

Some vendors, like Evervault, keep the 3DS challenge inside your checkout.

Others redirect the customer to a separate page or a new tab. A redirect breaks the customer's flow, adds a page load, and usually needs cookies to hold onto session state while the customer bounces back and forth. Browsers are getting more aggressive about blocking third-party cookies these days, so this can just break, mid-checkout, for no reason the customer will understand. EMVCo's own UX guidance actually recommends embedding the challenge inline for this reason, as it cuts cart abandonment.

Keep it inline instead, and the customer never leaves your page. It's just a modal you can theme with your own fonts, colors, and copy. You can also fingerprint the customer's device and hand that data to the issuer before they decide whether to challenge, which nudges the odds toward a frictionless approval in the first place.

What options do you have to reduce friction?

3DS is mandated in some markets so there’s not much you can do to reduce friction. But in markets where it’s not mandated, you can get many of the benefits of 3DS with zero friction.

  • Fail-on-challenge: This feature lets you attempt 3DS to secure liability shift, but if the issuer steps up to a challenge, it aborts the authentication request and proceeds to authorization. This is an awesome way to maximize the benefits of 3DS while ensuring zero friction.

    The trade-off is if the issuer wants to challenge and you abort, you don't get liability shift on that transaction. But if zero friction is your priority, that's the whole point: you still get liability shift on everything that passes frictionlessly, and your customers never sit through a challenge screen.

    Most vendors don’t support this, but it’s a favorite among our customers. Here’s how it works.

    If the vendor does support fail-on-challenge, confirm they only charge per successful authentication (as Evervault does); otherwise, you'll be paying for attempts that never went anywhere.

  • 3DS data-only: Use this authentication method to send enriched data to issuers to increase acceptance rates by 2.2%+, without actually authenticating the customer, which means no fraud liability shift. With Visa transactions, this can lead to an 0.05% interchange fee reduction under Digital Commerce Authentication Program (DCAP).

Does the vendor reduce your PCI compliance scope?

A standalone 3DS provider needs the card number to run an authentication. It can't use the tokens your PSP gave you, because those tokens only work with that PSP. That leaves two options:

  1. Handle raw card data yourself, which brings much of your infrastructure into PCI scope.

  2. Use a third party to collect and secure it for you. That usually means one more vendor, one more integration, and one more copy of your card data to keep in sync with your 3DS provider.

The simpler setup is one vendor that both secures the card data and runs 3DS on it. That's how Evervault works. Card data is encrypted in the customer's browser before it reaches your servers, so raw card numbers never touch your infrastructure. The same encrypted card can then be authenticated with 3DS, routed to any PSP, and retried elsewhere, with no re-collection and no extra vendor in the middle.

If you're working out how to collect cards to enable multi-PSP routing without taking on a large compliance burden, we’ve written a four-part guide on the topic. It covers how PCI DSS applies to you, how the main card collection options compare, what the requirements look like in practice, and where Apple Pay, Google Pay, and network tokens fit.

One platform for 3DS and everything around it

Evervault runs its own EMVCo-certified 3DS server and secures your card data, so raw card numbers never touch your systems. You can authenticate once and route to any PSP.


Subscribe to our newsletter

Sign up to get access to the latest product insights.

© 2026 Evervault Inc. All rights reserved.