Skip to content

3D Secure

3D Secure (3DS) is an authentication protocol that adds an extra layer of security to online payments.

When a customer initiates a payment, 3DS requires them to complete an additional authentication step with their card issuer. This typically involves directing the customer to their bank’s website, where they enter a password or a code sent to their phone to verify the payment. This added layer of authentication helps protect your business from fraudulent transactions and ensures that payments are more secure.

3D Secure 2 (3DS2) is an updated and highly secure authentication protocol that is designed specifically to meet the Strong Customer Authentication (SCA) requirements for online payments.

Benefits

Notice

Additional layer of security added to card-not-present (CNP) transactions.

 

Enhanced authentication accuracy.

 

Reduced risk of fraudulent transactions.

 

A more secure and trustworthy payment experience for your customers, while also protecting your business from fraudulent transactions.

 

Chargeback liability shift.

When it comes to fraudulent chargebacks (for example, chargeback claim due to lost or stolen card), the responsibility typically shifts from the merchant to the card issuer once the payment is successfully authenticated with 3DS.

This means that if the payment was made with 3D Secure and the cardholder disputes the payment as fraudulent, you will not be liable for any losses. Instead, the card issuer will be responsible for refunding the cardholder and any associated fees.

Info

Chargeback Liability Shift

 

If the 3DS authentication is successful (whether following the frictionless or challenge flow), the liability for the payment is passed to the bank, protecting you from fraudulent transactions.

3DS 2 Flows

3DS2 provides an enhanced user experience by embedding the authentication process seamlessly within your checkout flow, improving upon the original 3DS protocol.

During the payment process, 3DS2 allows the merchant and payment provider to send data elements, including the customer’s shipping address, device ID, and payment history, to the cardholder’s bank. This information is used to assess the risk level of the transaction, all of which takes place in the background, within your web or mobile checkout flow.

Based on this data, the customer’s bank will either immediately authenticate the payment (frictionless flow), or request additional information before authenticating the payment (challenge flow).

Frictionless flow

The frictionless flow occurs when the bank has enough information to trust that the payment is being made by the cardholder, allowing for the payment to be authenticated without disrupting the customer’s experience. On the other hand, if the bank needs more proof, the challenge flow will be initiated, and the customer will be prompted for additional information to authenticate their payment.

Challenge flow

During a challenge flow in the 3DS2 authentication process, the issuer requests additional interaction from the shopper, aimed at verifying their identity. This can involve the use of advanced authentication measures such as biometric authentication, two-factor authentication, or other Strong Customer Authentication (SCA) factors. Such additional steps are required when the issuer deems the transaction to carry a higher risk of fraud, necessitating more comprehensive authentication to safeguard the transaction’s safety and security.

Payment with 3DS

The 3-D Secure authentication protocol follows a three-domain model, in which the Acquirer Domain and Issuer Domain are linked by the Interoperability Domain. The primary objective of this model is to authenticate a cardholder during an e-commerce transaction or provide identity verification and account confirmation.

This protocol applies to customers who shop online at merchants with online stores that comply with 3D-Secure guidelines. For further information, please visit https://www.emvco.com/emv-technologies/3d-secure/.

The flow begins with a standard authorization or purchase flow, where the initial response to the POST /{id}/card/purchase request indicates that 3D-Secure authentication is required. This indication is provided in the form of a paymentStatus: “Partial,” followed by a new complex element called “actionResponse.”

3D-Secure authentications may occur automatically and seamlessly (frictionless flow) or require explicit authentication by the customer on their issuer’s platform (challenge flow).

How it works

To perform a payment with 3DS authorization, first create an order as detailed in API Integration Guide.

Then, you may proceed to Make the Payment.

Note that you should add the DeviceInfo to the request message:

Data ElementTypeConditionDescription
deviceInfoDeviceInfoMandatoryObject that defines the customer device information.
browserAcceptHeaderStringOptionalBrowser Accept Header.
browserJavaEnabledStringOptionalBrowser Java Enabled.
browserJavascriptEnabledStringOptionalBrowser Javascript Enabled.
browserLanguageStringOptionalbrowser Language.
browserColorDepthStringOptionalbrowser Color Depth.
browserScreenHeightStringOptionalbrowser Screen Height.
browserScreenWidthStringOptionalbrowser Screen Width.
browserTZStringOptionalBrowser Time Zone.
browserUserAgentStringOptionalBrowser User Agent.
systemFamilyStringOptionalSystem Family.
systemVersionStringOptionalSystem Version.
systemArchitectureStringOptionalSystem Architecture.
deviceManufacturerStringOptionalDevice Manufacturer.
deviceModelStringOptionalDevice Model.
deviceIDStringOptionalDevice Unique Identification.
applicationNameStringOptionalApplication Name.
applicationVersionStringOptionalApplication Version.
geoLocalizationStringOptionalGeolocation.
ipAddressStringOptionalIP Address.

Here you can check an example request:

{
 "info": {
 "deviceInfo": {
 "browserAcceptHeader": "application/json, text/plain, */*",
 "browserJavaEnabled": "false",
 "browserLanguage": "en",
 "browserColorDepth": "24",
 "browserScreenHeight": "1080",
 "browserScreenWidth": "1920",
 "browserTZ": "-60",
 "browserUserAgent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36",
 "geoLocalization": "Lat: 38.7350528 | Long: -9.2143616",
 "systemFamily": "Windows",
 "systemVersion": "Windows",
 "deviceID": "498bfd4c3a3645b38667a7037b616c18",
 "applicationName": "Chrome",
 "applicationVersion": "106"
 },
 "customerInfo": [
 {
 "key": "customerName",
 "value": "Diogo M"
 },
 {
 "key": "customerEmail",
 "value": "{{CustomerEmail}}"
 }
 ]
 },
 "cardInfo": {
 "PAN": "{{MC3DSCardNum}}",
 "secureCode": "{{MC3DSCardCVV}}",
 "validationDate": "{{MC3DSCardExpiry}}",
 "cardholderName": "TKN {{trxDatetime}}",
 "createToken": true
 }
}

You will receive a response comprising a paymentStatus in the message. It informs whether the transaction was accepted, declined, still pending a final result, or requires additional action.

  • Success: The purchase has been processed successfully and the customer has been debited.
  • Declined: The purchase has been declined.
  • Pending: The final result of the purchase is not yet known. You will need to inquiry on the status of this transaction until it reaches a final state, or you decide to cancel it.
  • Partial: The purchase is partially accepted, but requires additional actions to the completed (e.g. 3D Secure authentication). The actionResponse element is provided for instructions on how to proceed.

If the PaymentStatus received is “Partial”, it indicates that an additional request for 3DS authentication (Challenge Flow) needs to be POSTed, before resubmitting the Card payment request.

Notification

For the Frictionless Flow you will not receive a “Partial” PaymentStatus and you should proceed to perform the Get Status.

The response will also include an actionResponse element with information on how to proceed, as shown in the example below.

Save the actionResponse.id to use in the resubmission of the payment request once the 3DS authentication terminates.

Here’s a full response example with the action response included:

{
 "transactionID": "2Cm5pP09QcP1pUq7WpPs",
  "execution": {
  "startTime": "2023-06-20T13:10:55.328Z",
 "endTime": "2023-06-20T13:10:57.484Z"
 },
  "paymentStatus": "Partial",
 "actionResponse": {
 "id": "b114d9a9-4d6b-4ff8-ab95-be4e11cc8235",
 "type": "THREEDS_CHALLENGE",
 "data": {
 "url": "https://api-aws.sibs.ro/sandbox/sibs/public/acsSample",
 "params": [
 {
 "name": "creq",
 "data": "eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6ImIxMTRkOWE5LTRkNmItNGZmOC1hYjk1LWJlNGUxMWNjODIzNSIsImFjc1RyYW5zSUQiMS4wIiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAxIn0="
 }
 ]
 }
 },
 "returnStatus": {
 "statusCode": "000",
 "statusMsg": "Partial",
 "statusDescription": "Partial"
 }
}

Then, you must perform three additional three actions:

Action 1: Redirect the cardholder to the ACS for 3DS Authentication
Action 2: Resubmit the Transaction for final authorization
Action 3: Perform a Get Status
Action 1: Redirect the cardholder to the ACS for 3DS Authentication

The customer’s browser must be redirected via POST to the 3DS Access Control Server (ACS) URL indicated by actionResponse.data.url using the actionResponse.data.params as request parameters.

The cardholder’s browser is redirected back to your origin once the authentication is finished.

Javascript example of redirection to ACS

POST "https://api-aws.sibs.ro/sandbox/sibs/public/acsSample"
creq: eyJ0aHJlZURTU(...)
Action 2: Resubmit the Transaction for final authorization

You will have to In this purchase request, add the actionProcessed object as shown below:

Data ElementTypeConditionDescription
actionProcessedActionProcessedOptional
idStringMandatory
typeStringMandatoryPossible values are
“THREEDS_METHOD”,
“THREEDS_CHALLENGE”,
“DCC”,
“INSTALLMENTS”
executedBooleanMandatory

Request example:

Request URL:

https://stargate-cer.qly.site1.sibs.pt/api/v1/payments/{transactionID}/card/purchase

Request Headers:

Authorization: ‘Digest <transactionSignature>’
X-IBM-Client-Id: ‘<ClientId>’
Content-Type: application/json
{
 "info": {
 "deviceInfo": {
 "browserAcceptHeader": "application/json, text/plain, */*",
 "browserJavaEnabled": "false",
 "browserLanguage": "en",
 "browserColorDepth": "24",
 "browserScreenHeight": "1080",
 "browserScreenWidth": "1920",
 "browserTZ": "-60",
 "browserUserAgent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36",
 "geoLocalization": "Lat: 38.7350528 | Long: -9.2143616",
 "systemFamily": "Windows",
 "systemVersion": "Windows",
 "deviceID": "498bfd4c3a3645b38667a7037b616c18",
 "applicationName": "Chrome",
 "applicationVersion": "106"
 },
 "customerInfo": [
 {
 "key": "customerName",
 "value": "Diogo M"
 },
 {
 "key": "customerEmail",
 "value": "{{CustomerEmail}}"
 }
 ]
 },
  "cardInfo": {
 "PAN": "{{MC3DSCardNum}}",
 "secureCode": "{{MC3DSCardCVV}}",
 "validationDate": "{{MC3DSCardExpiry}}",
 "cardholderName": "TKN {{trxDatetime}}",
 "createToken": true
 },
 "actionProcessed": {
 "id": "{{actionId}}",
 "type": "THREEDS_CHALLENGE",
 "executed": true
 }
}

Expected response:

As we’ve seen before, the paymentStatus in the response informs on whether the transaction itself was declined, processed successfully, or requires yet another action.

A successful technical response comprises of an HTTP-200 status and a returnStatus.statusCode=”000″.

If the payment status is ‘Partial’, proceed as before from Action 1.

Here’s an example of a successful payment:

{
 "transactionID": "2Cm5pP09QcP1pUq7WpPs",
 "execution": {
 "startTime": "2023-06-20T13:11:14.236Z",
 "endTime": "2023-06-20T13:11:17.535Z"
 },
 "paymentStatus": "Success",
 "returnStatus": {
 "statusCode": "000",
 "statusMsg": "Success",
 "statusDescription": "Success"
 },
 "actionResponse": {
 "data": {
 "params": []
 }
 }
}
Action 3: Perform a Get Status

After the payment has been fully processed, you can check the status of your transaction by sending a GET request.

Ensure that the Authorization HTTP header is set to the same Bearer token that was used in the initial payment Order.

Request URL:

https://stargate-cer.qly.site1.sibs.pt/api/v1/payments/{transactionID}/status

Request Headers:

Authorization: ‘Bearer <AuthToken>’
X-IBM-Client-Id: ‘<ClientId>’

A successful technical response comprises of an HTTP-200 status and a returnStatus.statusCode=”000″.

Here are some examples of the possible result codes:

Result codestatusMsgDescriptionAction
HTTP-200SuccessSuccess response.n/a.
HTTP-400Bad RequestThe JSON payload is not matching the API definition or some mandatory HTTP headers are missing.Please check in API Market for the correct syntax.
HTTP-401UnauthorizedOn the Authorization, Bearer token is invalid/expired or not associated with the Terminal used.Please check in SIBS Backoffice under the Credentials if the token is valid and create a new one if needed.
HTTP-403ForbiddenThe ClientID set on the X-IBM-Client-Id HTTP header is not valid or does not possess a valid subscription to the API.Please check in SIBS Backoffice under the SPG APP 2.0 if the ClientID is correct. If the problem persists contact SIBS Gateway support for a ClientID reset.
HTTP-405Method Not AllowedThe HTTP Method used is not matching any of the API definitions available.Please check in API Market for the correct HTTP Method.
HTTP-429Too Many RequestsThe API calls rate limit has been exceeded.Please check in API Market for information on the rate limits that apply to the API.
HTTP-500Internal Server ErrorThe API call has failed… and its most likely on our side.You should retry the operation, and if the problem persists contact SIBS Gateway support for assistance.
HTTP-503Service UnavailableThe API call is not currently available. Usually we are always on, but short availability issues may occur during scheduled maintenance.You should wait and try again later.

Here’s a response example:

{
 "merchant": {
 "terminalId": "101774",
  "merchantTransactionId": "Order Id: r7cxvi0saj"
 },
 "transactionID": "2Cm5pP09QcP1pUq7WpPs",
 "amount": {
 "currency": "PLN",
 "value": "50.50"
 },
 "paymentType": "PURS",
 "paymentStatus": "Success",
 "paymentMethod": "CARD",
 "execution": {
 "endTime": "2023-06-20T13:11:23.411Z",
 "startTime": "2023-06-20T13:11:23.327Z"
 },
 "returnStatus": {
 "statusCode": "000",
 "statusMsg": "Success",
 "statusDescription": "Success"
 }
}