This document gives you a general guide for how to implement 3-D Secure (3DS) using TabaPay's suite of tools.
Note: this guide is currently in progress. If you have suggestions or additional questions please feel free to use the community page.
Make sure you have 3DS on your TabaPay Plan.
If you would like to implement 3DS, please make sure you have this service in your merchant agreement. If you are not sure, or would like to add it please contact the TabaPay team for more information.
Top-level structure
For an overview and required data please look at out 3DS integration overview.
3DS APIs do NOT process payment
3DS APIs only provide a way for you and the issuer to verify a customer's identity. In order to create a transaction you still have to call the create transaction API. The create transaction API has a
body param
forpullOptions
. Within this object, you should find a3DSecure
object. Please look at the3DSecure
object and it's internal fields to know what information you will need to provide thecreateTransaction
API.
Frontend integration details
Frontend does not communicate with our APIs directly
First thing to note, all contact with our API will have to go through your backend server. Any frontend application/service will have to communicate with your own servers. Your severs will then connect with the TabaPay API servers.
The details below are some suggestions to help with your own frontend integrations
Web integration
When integrating with 3DS please do not forget to collect the customer's device information. You can use the following guide to read more details: device date collection guide
SDK Mobile integration
Integrate 3DS into your native app using our iOS and Android SDKs. For more information, please read our 3DS SDK starter guide.
Backend integration details
Important requirement
3DS 2.0 requires cardholder address as part of the authentication process at the issuer. If you're using Account ID as the payment instrument for 3DS, it must have billing address associated with it. So, please ensure you create accounts by providing address always.
"Required unless market or regional mandate restricts sending this information." - (EMV® 3-D Secure Protocol and Core Functions Specification v2.3.1.0, August 2022)
Steps in this guide
The following guide is broken down into these steps:
-
Initialize API - Get the JWT
-
Device Data Collection (Frontend)
-
Lookup API - Authentication Request with the issuer
-
(Step up) - Challenge (Frontend)
-
(Step up) - Authenticate API - Verify the JWT you receive from the Challenge.
Create account
In order to Initialize
the 3DS API, you will need to provide either a customer's card information (please make sure you follow all PCI rules when handling card holder data), or a TabaPay accountID
.
A TabaPay accountID
is a Token
provided by the TabaPay API to identify a particular end user's payment information. In order to create a Token
simply call the Create Account API.
*If you are using the TabaPay PCI helpers, then you will have to use the Create Account API in order to use the 3DS API.
3DS API will accept other payment methods in the future.
We are hoping to add other payment methods, like Apple Pay, to the 3DS
Initialize
API in the near future. However for now, you have to create a TabaPayToken
through theAccount
API in order to use other payment methods.
Initialize API - Get the JWT
3DS utilizes a Json Web Token to store important information about the 3DS authentication. To start the authentication process you will need to generate this jwt
and a 3dsID
using the Initialize
API.
Initializes a 3D Secure Card Authentication Request. This creates a jwt
for 3D Secure Card Authentication.
If you are an ISO, you will need to specify a SubClientID.
URL
https://FQDN/v2/clients/ClientID/3ds/init
Merchant must connect with TabaPay’s 3D Secure Initialize
Notes:
For Clients who are an ISO, to specify your ClientID and a SubClientID, use the underscore character ("_") to separate the two values: <ClientID>_<SubClientID>
where:
- ClientID is your unique 22-character string and
- SubClientID is an assigned 4, 6 or 8-digit value.
Request
Request Data:
JSON Name | Value | Required | Default | Description |
---|---|---|---|---|
account | object | R | Account | |
account.accountID | String 22 characters | R | AccountID (you receive this from the CreateAccount API. | |
account.owner | object | O | Owner | |
account.owner.phone | object | O | Phone Number (E.164 Numbering) | |
account.owner.phone. countryCode | String 1-3 digits | O | 1 | Country Calling Code |
account.owner.phone.number | String Min: 4 digits Max: 12-14 digits | R | Phone Number | |
order | object | R | Order | |
order.orderID | String 1-50 characters | R | Order Number | |
order.currency | String 3 digits | O | 840 | ISO 4217 Currency Number |
order.amount | String Amount | R | Transaction Amount |
Response
Status Codes:
Status | Code | Description |
---|---|---|
200 | OK | A JWT is created. |
207 | A JWT is created. 207 Multi-Status | Multi-Status One or more Failures occurred while processing the Request. |
404 | Not Found | The AccountID does not point to a valid Account. |
Response Data:
JSON Name | Value | Description | Status Code (200) | Status Code (207) | Status Code (Other) |
---|---|---|---|---|---|
SC | Integer 3-digit code | HTTP Status Code | ✔ | ✔ | O |
EC | String 1 or 8 characters | Internal Error Code | ✔ | ✔ | O |
EM | String | Error Message | O | O | |
3dsID | String | An identifier representing this Request | ✔ | ||
jwt | String | JWT (JSON Web Token) | ✔ | ||
deviceCollectionURL | String URL | URL for Device Data Collection | ✔ |
Device Data Collection (Frontend)
Device Data Collection is an important part of 3DS 2.0. It allows you to send information to the issuer about the customer's device to kickstart the authentication process. In the ideal case, this information is key in reducing the rate at which your customer receives challenges. This step must be performed before you begin the lookup
request in the next step. To complete this step, please use the following guide
Please do not forget to include this device data collection step in your frontend implementation.
Lookup API - Authentication Request with the issuer
Important requirement
3DS 2.0 requires cardholder address as part of the authentication process at the issuer. If you're using Account ID as the payment instrument for 3DS, it must have billing address associated with it. So, please ensure you create accounts by providing address.
3D Secure Card Lookup.
If you are an ISO, you will need to specify a SubClientID.
URL
https://FQDN/v2/clients/ClientID/3ds/lookup
Notes:
For Clients who are an ISO, to specify your ClientID and a SubClientID, use the underscore character ("_") to separate the two values: <ClientID>_<SubClientID>
where:
- ClientID is your unique 22-character string and
- SubClientID is an assigned 4, 6 or 8-digit value.
Lookup codes
The following documentation has the values you should use for the lookup call:
Request
JSON Name | Value | Required | Default | Description |
---|---|---|---|---|
3dsID | String | R | 3dsID from 3D Secure Initialize | |
authenticationIndicator | String 2 digits | R | ||
transactionMode | String 1 character | O | ||
transactionType | String 1 character | R | ||
productCode | String 3 characters | R | ||
account | object | R | Account | |
- accountID | String 22 characters | R | AccountID | |
- owner | object | R | Owner | |
String | R | Email Address | ||
- phone | object | O | Phone Number (E.164 Numbering) | |
- countryCode | String 1-3 digits | O | 1 | Country Calling Code |
- number | String Min: 4 digits Max: 12-14 digits | R | Phone Number | |
order | Object | R | Order | |
- orderID | String 1-50 characters | R | Order Number | |
- currency | String 3 digits | O | 840 | ISO 4217 Currency Number |
- amount | String Amount | R | Transaction Amount | |
browser | Object | R | Browser Info | |
- browserInfo | String | O | Concatenated Browser Data Fields. Concatenate the below fields (in order!) with the | - javascriptEnabled - userAgent - header - javaEnabled - language - colorDepth - screenHeight - screenWidth - timezone - ipAddressSee an example Browser Fields | |
- deviceChannel | String | R | Either: - Browser - SDK |
Response
Status Codes:
Status | Code | Description |
---|---|---|
200 | OK | A Lookup Response is returned. |
207 | Multi-Status | One or more Failures occurred while processing the Request. |
404 | Not Found | The AccountID does not point to a valid Account. |
Response Data:
JSON Name | Value | Description | Status Code (200) | Status Code (200 Challenge) | Status Code (207) | Status Code (Other) |
---|---|---|---|---|---|---|
SC | Integer 3-digit code | HTTP Status Code | ✔ | ✔ | ✔ | O |
EC | String 1 or 8 characters | Internal Error Code | ✔ | ✔ | ✔ | O |
EM | String | Error Message | O | O | ||
3dsVersion | String | The 3D Secure Version that was used to process this request | ✔ | ✔ | ||
enrolled | String | Authentication Eligibility Status | ✔ | ✔ | ||
processorTransactionID | String | Processor Transaction Identifier | O | ✔ | ||
dsTransactionID | String | Directory Server Transaction Identifier | O | O | ||
status | String | Status | O | |||
ECI | String | ECI (Electronic Commerce Indicator) | O | |||
UCAF | String | UCAF (Universal Cardholder Authentication Field) - Visa uses CAVV (Cardholder Authentication Verification Value) - MasterCard uses AAV (Accountholder Authentication Value) | O | |||
XID | String | XID (Transaction ID) | O | |||
challengeURL | String | Consumer Authentication URL | ✔ | |||
payload | String | Encoded Payment Request | ✔ | |||
cardholderInfo | String | Coming Soon (subject to change) - Text provided by the ACS/Issuer to Cardholder during a Frictionless transaction. The Issuer can provide information to Cardholder. For example: Additional authentication is needed for this transaction, please contact (Issuer Name) at xxx-xxx-xxxx. The Issuing Bank can optionally support this value. The merchant is required to display this within their Checkout when present. | O | |||
signatureVerification | String | Coming Soon (subject to change) - Transaction Signature status identifier. Possible Values: Y - Indicates that the signature of the PARes has been validated successfully and the message contents can be trusted. N - Indicates that the PARes could not be validated. This result could be for a variety of reasons; tampering, certificate expiration, etc., and the result should not be trusted. | O | O | ||
stepUpURL | String | Coming Soon (subject to change) - The fully qualified URL that the client uses to post the cardholder in order to complete the Consumer Authentication transaction for the Cardinal Cruise API integration. Note: This is only for a Cardinal Cruise API Integration | O | |||
3dsRC | String | Coming Soon (subject to change) - TabaPay Error Code for 3DS, this should be 0 unless there is an issue. Please store this in your logs. | O | O | O | |
(Step up) - Challenge (Frontend)
Setting up the challenge flow:
When the issuer needs more information to authenticate a customer, they will ask for a challenge
(also known as a step up
). There are three common types of challenge:
The issuer decides which method to use, and as a merchant you will not have visibility into what is going on between the issuer and the customer. In order to know the result of the challenge, you will use an event listener:
Cardinal.on("payments.validated", function (data, jwt) {
switch(data.ActionCode){
case "SUCCESS":
// Handle successful transaction, send JWT to backend to verify
break;
case "NOACTION":
// Handle no actionable outcome
break;
case "FAILURE":
// Handle failed transaction attempt
break;
case "ERROR":
// Handle service level error
break;
}
});
Please note calling this function with the same namespace multiple times will result in a callback being triggered multiple times.
The response from the challenge will contain two fields: data
and the jwt
. You modify your payments.validated event to handle specific scenarios (specifically look at the data.actionCode)
Value | Description |
---|---|
SUCCESS | Authentication was completed successfully. You will have a UCAF, ECIFlag, and XID to send during authorization. |
CANCEL | Transaction canceled by the user. |
ERROR | An error was encountered. Refer to ErrorNumber and ErrorDescription for more details on the error. If a Payment object is present you may have additional details in the ReasonCode and ReasonDescription fields within the Payment object |
FAILURE | Authentication resulted in a failure - this includes the end user failing authentication. |
NOACTION | Authentication was not applicable and no service level errors were encountered. When the ErrorNumber is 0, generally this means you may move on to authorization, but be aware the transaction may not be eligible for liability shift. |
TIMEOUT | Returned when the challenge process reaches or exceeds the timeout interval that is specified during the cca_continue call. |
For more detailed information about ActionCodes
Please visit our 3DS challenge results page
The next step in the integration is to add logic to your payments.validated event to handle specific return values for CCA.
During the payments.validated is when you would call TabaPay's /authenticate endpoint, using the original 3dsID
and the returned jwt
from the CCA (a different jwt
from the Initialize
API)
After the authenticate
API we will provide you with the UCAF
, XID
, ECI
which you can use in the pullOptions
of the CreateTransaction
.
See more here: https://cardinaldocs.atlassian.net/wiki/spaces/CC/pages/98315/Response+Objects
Examples of what your customers might see: https://developer.visa.com/pages/visa-3d-secure/payment-flows-otp
Starting the challenge:
In order to initiate the challenge, you will need the processorTransactionID
, challengeURL
, and payload
values from the lookup API response. The Cardinal.continue
will display a modal window and automatically post the consumer's session over to the acs url for authentication.
Please note: AcsUrl
= challengeURL
AcsUrl
= challengeURL
Using the example values
Cardinal.continue('cca',
{
AcsUrl:"https://example.cardinalcommerce.com/Example/creq.jsp",
Payload:"eyJtZXNzYsndfkjasdnfkjasnfkjdnaskWdlVmVyc2lv..."
},
{
OrderDetails: {
TransactionId: "</lookup processorTransactionID here>"
}
});
Cardinal's Songbird.js will handle the entire challenge flow from here, and you will receive the authentication result after the challenge completes via the Cardinal.on("payments.validated"...
function you previously setup.
(Step up) - Authenticate API - Verify the JWT you receive from the Challenge.
The Authenticate API is called after the challenge is performed.
3D Secure Card Challenge Authentication.
If you are an ISO, you will need to specify a SubClientID.
URL
https://FQDN/v2/clients/ClientID/3ds/authenticate
Notes:
For Clients who are an ISO, to specify your ClientID and a SubClientID, use the underscore character ("_") to separate the two values: <ClientID>_<SubClientID>
where:
- ClientID is your unique 22-character string and
- SubClientID is an assigned 4, 6 or 8-digit value.
Request
JSON Name | Value | Required | Default | Description |
---|---|---|---|---|
3dsID | String | R | 3dsID from 3D Secure Initialize | |
jwt | String | R | JWT (JSON Web Token) from Challenge |
Response
Status Codes:
Status | Code | Description |
---|---|---|
200 | OK | A Lookup Response is returned. |
Response Data:
JSON Name | Value | Description | Status Code (200) | Status Code (Other) |
---|---|---|---|---|
SC | Integer 3-digit code | HTTP Status Code | ✔ | O |
EC | String 1 or 8 characters | Internal Error Code | ✔ | O |
EM | String | Error Message | O | |
actionCode | String | Result: Action Code | ✔ | |
errorNumber | String | Result: Error Number | ✔ | |
errorDescription | String | Result: Error Description | O | |
3dsVersion | String | The 3D Secure Version that was used to process this request | ✔ | |
processorTransactionID | String | Processor Transaction Identifier | ✔ | |
status | String | Status | ✔ | |
ECI | String | ECI (Electronic Commerce Indicator) | ✔ | |
UCAF | String | UCAF (Universal Cardholder Authentication Field) - Visa uses CAVV (Cardholder Authentication Verification Value) - MasterCard uses AAV (Accountholder Authentication Value) | ✔ | |
XID | String | XID (Transaction ID) | O |
Create Transaction
Almost done! Don't forget to create a transaction.
After the
authenticate
API we will provide you with theUCAF
,XID
,ECI
which you can use in thepullOptions
of theCreateTransaction
.
Electronic Commerce Indicator (ECI). The ECI value is part of the 2 data elements that indicate the transaction was processed electronically. This should be passed on the authorization transaction to the Gateway/Processor.
Create Transaction pullOptions.3DSecure.ECI
allows a single digit. Only the right-most digit of the below ECI values is expected in the pullOptions.3DSecure.ECI
field.
Possible Values:
- 02 or 05 - Fully Authenticated Transaction
- 01 or 06 - Attempted Authentication Transaction
- 00 or 07 - Non 3-D Secure Transaction
Values per Network:
- Mastercard - 02, 01, 00
- VISA - 05, 06, 07
- AMEX - 05, 06, 07
- JCB - 05, 06, 07
- DINERS CLUB - 05, 06, 07
- Cartes Bancaires (CB) Visa - 05, 06, 07
- Cartes Bancaires (CB) Mastercard - 02, 01, 00
- ELO: 05, 06, 07
- Union Pay International: 05, 06, 07
- eftpos (Visa or MC) - 05, 06, 07
For more information: https://developers.tabapay.com/reference/3ds-faq
Create Transaction:
3DS APIs only provide a way for you and the issuer to verify a customer's identity. In order to create a transaction you still have to call the create transaction API. The create transaction API has a body param
for pullOptions
. Within this object, you should find a 3DSecure
object. Please look at the 3DSecure
object and it's internal fields to know what information you will need to provide the createTransaction
API.