3D Secure


3D Secure is an XML-based protocol designed to be an additional security layer for online credit and debit card transactions. It adds an authentication step for online payments, directly integrated to the card brands and bank servers. That means, whenever the card brands or a bank approve a sale from happening through 3DSecure, the liability and risk is shifted from the merchant to the bank. Given these circumstances, it prevents chargebacks from happening since the card brands and banks will actually be responsible for the transaction approval.

While most of the US based cards are enrolled to the 3DS, there are cards are not enrolled to it, and consequently, this service is only possible when the credit card and issuing bank participate on the program.

Frictionless mode 3DS

Frictionless mode is a trade-off: you opt for better user experience while having a lower success ratio on 3DS. If compared to Strict mode, Frictionless mode is less secure, since for all the cases when the issuing bank and credit card bank ask for additional information, the process will fail. From a technical perspective, you improve user’s experience by not sending them to a different website, since all the process happens within a hidden iframe on your website.

From our data, using this method reduces churn. In terms of success ratio, what we’ve seen is that frictionless 3DS works 30-70% of the times based off your customer base and business variables.

Authorization

Authorization process for our 3DS API consists in generating a hex-digested SHA256 signature, using four main variables:

  • Your API Key;
  • The fully qualified URL you’re trying to reach on the API;
  • JSON dumped data you’re posting for that request, with keys ordered alphabetically;
  • Your API Secret.

Let’s say you’re trying to reach the endpoint /hello on a http://example.com base url and you want to send the following data:

{
  "name": "John Doe",
  "card": "4111111111111111",
  "state": "California",
  "city": "San Francisco"
}

The first thing that you would have to do is sorting the json keys alphabetically:

{
  "card": "4111111111111111",
  "city": "San Francisco",
  "name": "John Doe",
  "state": "California"
}

Then, strip all the empty spaces from that string:

{"card":"4111111111111111","city":"San Francisco","name":"John Doe","state":"California"}

And then, signing it like this:

API_KEY='my-api-key'
URL='http://example.com/hello'
DATA='{"card":"4111111111111111","city":"San Francisco","name":"John Doe","state":"California"}'
SECRET='no-one-knows'

# It would look like this:
# my-api-keyhttp://example.com/hello{"card":"4111111111111111","city":"San Francisco","name":"John Doe","state":"California"}no-one-knows
SIGNATURE=$API_KEY$URL$DATA$SECRET
echo $SIGNATURE

# Digest/sign it!
# Should look like this: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
echo -n $SIGNATURE | openssl dgst -sha256

That signature and your API Key should be passed on all requests in the following request headers:

Header Required Value
x-mpi-api-key Yes my-api-key
x-mpi-signature Yes e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855


Check card enrollment

At the moment, we only support 3DS for VISA and MasterCard cards. Still, not all of the cards and issuing banks participate to the 3DS program. So, in order to know if a card is participating or not, you should make the first request which is to get enrollment status for a specific credit card.

HTTP Request

POST https://mpi.3dsintegrator.com/index.php/enrolled-status

Request Fields

Parameter Required? Description Type
pan Yes The credit card number string

Sample request

curl -v -X POST -H 'Content-Type: application/json' \
  -H 'x-mpi-api-key: YOUR_API_KEY' \
  -H 'x-mpi-signature: 1b742fab984f86b141991917c71c99b81109078e4874ce1c9fb925a038af0386' \
  -d '{"pan":"4111111111111111"}' \
  "https://mpi.3dsintegrator.com/index.php/enrolled-status"

The above command returns JSON structured like this:

{"enrollment_status":"N"}

Responses

Response Description Liability
enrollment_status = Y Participating bank and card issuer Card Issuer
enrollment_status = N Not participating bank or card issuer Merchant
enrollment_status = U Unknown, usually a server side error on card brand / issuing bank APIs Merchant
enrollment_status = A Attempted, but something went wrong Merchant



Based off your business nature and your own preferences you can block a transaction from happening or just let it proceed without 3DS protection. If you want to proceed without 3DS protection, just send over the transaction data to your gateway of choice; otherwise, if you want to block a transaction from happening, you can just send the customer back to the credit card details screen and ask him to try another card. At this point, our implementation is very permissive. It’s up to the merchants to choose what makes sense to them, on their business context. We usually recommend the permissive approach as getting too strict would result in loss of sales.

Payment Authentication Request

Whenever you get a enrollment_status = Y from the previous step, you’re ready to start the Payment Authentication Request. This step basically consists in exchanging the credit card data, and unique ids to your application with the API to get URLs and a token which will run the 3DSecure redirects under your mode of choice. A very important fragment of data that you will be passing at this request is also the return_url. This is the endpoint that you will receive on the next steps, a POST containing the final response for the 3DS process.

HTTP Request

POST https://mpi.3dsintegrator.com/index.php/auth-request

Request Fields

Parameter Required? Description Type
pan Yes The credit card number string
card_exp_month Yes Card expiration month in two digits. string (2 digits)
card_exp_year Yes Card expiration year in two digits. string (2 digits)
amount Yes Amount of the transaction. Maximum allowed precision is 2 decimal cases float (precision: 2)
transaction_id Yes An unique identifier for the transaction in course. string
message_id Yes An unique identifier for the order. Can be the same than transaction_id string
return_url Yes Callback URL for processing the transaction. Protocol must be https. string

Sample request

curl -v -X POST -H 'Content-Type: application/json' \
  -H 'x-mpi-api-key: YOUR_API_KEY' \
  -H 'x-mpi-signature: 16851d38cdc413e3481fedc17b03fb080eaf45a1ab20a4e6b9c7c2bb93a72799' \
  -d '{"amount":2,"card_exp_month":"12","card_exp_year":"20","message_id":"0001","pan":"4111111111111111","return_url":"https://localhost/3ds/callback","transaction_id":"0001"}' \
  "https://mpi.3dsintegrator.com/index.php/auth-request"

The above command returns JSON structured like this:

{
  "AcsUrl": "https://mpi.3dsintegrator.com/demoacs/",
  "PaReq": "eJx1kduOgkAMhl/FmL2mHJWQ2oRFE7nQGOV+M4FGSJaDA4i==",
  "TermUrl": "https://localhost/3ds/callback",
  "MD": "0001"
}

Responses

Response Description Type
AcsUrl Participating bank / card issuer page to run the redirects string
PaReq The payment authentication request token string
TermUrl The url you will be receiving callbacks, passed as return_url on the request. string
MD Attempted, but something went wrong string

After having the PaReq token, you have to make a choice in regards to which 3DS flavor you will be using: strict or frictionless. For strict, your user will be forwarded to VISA or MasterCard confirmation page. For frictionless, the process will happen inside your own system, inside an iframe, with a supporting endpoint, but you will have a lower approval rate.

Payment Authentication Response

Once you have the PaRes token, you are then ready to finish the 3D Secure authentication and make a decision of wether you will let this transaction pass or not. At this point, you will be doing a request to one last endpoint, with your PaRes data and the card authentication details provided on the Payment Authorization Request step, so the card brands and issuing banks can gather the information they need to provide a verdict and prevent that transaction from charging back.

HTTP Request

POST https://mpi.3dsintegrator.com/index.php/auth-response

Request Fields

Parameter Required? Description Type
pares Yes The Payment Authentication Response token. string
pan Yes The credit card number string
card_exp_month Yes Card expiration month in two digits. string (2 digits)
card_exp_year Yes Card expiration year in two digits. string (2 digits)
amount Yes Amount of the transaction. Maximum allowed precision is 2 decimal cases float (precision: 2)
transaction_id Yes An unique identifier for the transaction in course. string
message_id Yes An unique identifier for the order. Can be the same than transaction_id string
return_url Yes Callback URL for processing the transaction. Protocol must be https. string

Sample request

curl -v -X POST -H 'Content-Type: application/json' \
  -H 'x-mpi-api-key: YOUR_API_KEY' \
  -H 'x-mpi-signature: c2cc490e0d1c34f4498f14159230b69af396ff56d6509bdcbba26cbf43179f5e' \
  -d '{"amount":2,"card_exp_month":"12","card_exp_year":"2020","message_id":"0001","pan":"4111111111111111","pares":"PARES","return_url":"https://localhost/3ds/callback","transaction_id":"0001"}' \
  "https://mpi.3dsintegrator.com/index.php/auth-response"

The above command returns JSON structured like this:

{
  "pares":"eJzNWdnO4siSf...[REDACTED for readability purposes]...HlhAAAAAAA=",
  "success":true,
  "id":" 0001",
  "status":"Y",
  "time":"20170929 09:35:08",
  "cavv":"AAACACZ5YQAAABlwJHlhAAAAAAA=",
  "xid":"ICAgICAgICAgICAgICAgIDAwMDE=",
  "cavv_algorithm":"2",
  "eci":"05",
  "error":""
}

Responses

Response Description Type
pares The Payment Authentication Response token. string
id The transaction_id provided. Please notice that sometimes it has carriage return / leading and trailing spaces. string
success If the request to 3DS API succeeded or not. Not related to liability shift. boolean
status Request status and liability indicator. See table “Statuses” below. string
time Time that the response / verdict was given. YYYYMMDD HH:MM:SS formatted. string
cavv Cardholder Authentication Verification Value. Should be forwarded to the gateway for liability shift. string
xid 3DS Internal Transaction ID. Should be forwarded to the gateway for liability shift. string
cavv_algorithm The algorithm used to create the cryptogram cointained in cavv field. Sometimes should be forwarded to the gateway string
eci Electronic Commerce Indicator. Indicates the the authentication results of this specific transaction. See “Liability” table below. string



Based off the response you get above, you know if the liability of this transaction has been shifted to the issuing card or bank. In order to understand if that happened, you need to take under consideration the fields status and eci even though our API responds with a success field. the success field just means that the request was successful, not that the liability was shifted.


Statuses

Status Definition
Y Liability has been shift - see table Liability below section to see detailed coverage.
N Liability has not been shifted. Although, there are no reasons explicitly provided.
U Liability has not been shifted. There was an error with the card brand or issuing bank API.
A Liability may have been shifted or not - see table Liability for a verdict

Liability

Verdict MasterCard (ECI) Visa (ECI)
3DS authentication succeeded and liability shifted 2 or 02 5 or 05
3DS authentication attempted, but was not or could not be completed 1 or 01 6 or 06
3DS authentication failed or could not be attempted;
Card and/or issuing bank are not secured by 3DS, technical errors, or improper configuration.
0 or 00 7 or 07



As stated before, the business decisions on processing a transaction that had a failed 3DS attempt or liability not shifted or not is totally yours. Our 3DS process was built in a way that you, the merchant, can choose what makes more sense to your business. 3DS protection is only one of the products we offer to fight chargebacks, so if you want full protection, we recommend taking a look also on our Fraud Portal, Alerts API, Chargeback Representment and our Kount checks in order to have more data to drive you on a decision of blocking a transaction or not. In these cases, the more data you have, the more power you have to make an assertive decision.

Javascript SDK

This SDK is the simplest way to integrate risk based authentication to your online shop cart.

Installation

This is the front-end implementation of the SDK. Below is the instructions for leveling up your form to use 3D Secure.

1. Add the javascript

Include the following code on the billing page (where you get the credit card information) before closing the tag </body>.

<script src="https://js.paycertify.com/3ds.js"></script>

2. Initialize the ThreeDS library

The following code will start the library with the checkout form including the credit card data (first parameter) and the server side integration url (second parameter). You can also add some options to customize the integration.

<script>
var threeDS = new PayCertify.ThreeDS('payment-form', 'http://example.com/3ds/check_enrollment', { timeout: 5000 })
    threeDS.init();
</script>

You can use the following options to make 3DS integration fits better your checkout form:

Field Description Default
interval The interval in miliseconds which the javascript will wait to check 3DS form for an answer. 500
timeout Timeout in seconds that the javscript SDK will wait for an 3DS answer before executing the callback. 10000
fallback Change it to true if you want to fallback to strict mode when frictionless method fails. false
onSuccess Callback executed when 3DS is executed and successful. function
onError Callback executed when 3DS fails. function

3. Describe your inputs

To work properly, you should describe your inputs from checkout form to be sent to the server. You should add to some inputs the attribute data-threeds with the type of information the input contains. As you see on the following table:


Value Description
id Unique identifier for the transaction.
transaction-amount Transaction amount.
cc-num Credit card number.
cc-month Credit card expiration month. (MM)
cc-year Credit card expiration year. (YYYY)


You can use as the following example:

<form class="" action="index.html" method="post" id="payment-form">
  <!-- your checkout fields ... -->
  <input type="text" name="name" />
  <input type="text" name="address" />
  <!-- 3DS fields ... -->
  <input type="hidden" name="transaction_id" data-threeds="id" />
  <input type="text" name="card_number" data-threeds="cc-num" />
  <input type="text" name="card_expiration_month" data-threeds="cc-month" />
  <input type="text" name="card_expiration_year" data-threeds="cc-year" />
  <input type="text" name="transaction_amount" data-threeds="transaction-amount" />
</form>

4. Execute 3DS integration on server-side

On your server side, you should have an endpoint waiting for the 3DS information to check card enrollment. The Javascript SDK will be waiting for a JSON in the following format:

{
  "AcsUrl": "https://mpi.3dsintegrator.com/demoacs/",
  "PaReq": "eJx1kduOgkAMhl/FmL2mHJWQ2oRFE7nQGOV+M4FGSJaDA4i==",
  "TermUrl": "https://example.com/3ds/callback",
  "MD": "0001"
}

Then, you should receive the callback with the 3DS response (TermUrl from JSON response) in order to get the 3DS Authorization. The Javascript will be waiting for an JSON response as following:

{
  "pares":"eJzNWdnO4siSf...[REDACTED for readability purposes]...HlhAAAAAAA=",
  "cavv":"AAACACZ5YQAAABlwJHlhAAAAAAA=",
  "xid":"ICAgICAgICAgICAgICAgIDAwMDE=",
  "cavv_algorithm":"2",
  "eci":"05",
  "error":""
}

5. Sending the form

After all these steps, 3DS data was now added to your form and it will continue the natural form submitting flow to your checkout route. The following fields were added to your form and can be used to forward 3DS Data to your gateway.

Field Description
cavv Cardholder Authentication Verification Value. Should be forwarded to the gateway for liability shift.
xid 3DS Internal Transaction ID. Should be forwarded to the gateway for liability shift.
cavv_algorithm The algorithm used to create the cryptogram cointained in cavv field. Sometimes should be forwarded to the gateway.
eci Electronic Commerce Indicator. Indicates the the authentication results of this specific transaction.

Forwarding 3DS data

After you get the Payment Authentication Response, you should forward specific parameters to our gateway so the transaction can finally be protected.