• France
status page
Merchant Back Office
assistance
FAQContact support
Search
Categories
Tags
English
French
English
Homepage
Use cases
Create a payment
Create an installment payment
Create a multi-card (split) payment
Create a payment by Alias (Token)
Create a payment link
Create a recurring payment
Manage subscriptions
Manage your transactions (refund, cancel...)
Analyze your reports
API docs
Embedded Form
REST API
Hosted payment
Mobile payment
File exchange
Logos
Push mail
Snippets
Payment methods
Plugins
Guides
Merchant Back Office
Functional guides

PCI token creation service

The activation of these features is subject to prior approval by Systempay.

This token creation service allows PCI-DSS merchants to create a token by passing card information in the query.

Under PSD2, cardholder authentication via the 3D Secure protocol is mandatory. The service authenticates the cardholder and returns authentication information at the end of the process.

General principle

This WS allows the creation of an alias of the card sent in the request. Therefore, it will be possible to use this alias during future payments without having to re-enter the buyer's card information.

To do this, the call to the PCI/Charge/CreateToken web service triggers a verification transaction. As mentioned previously, within the framework of PSD2, it is mandatory to authenticate the cardholder via the 3D Secure protocol. The process is therefore as follows:

  • Call to the PCI/Charge/CreateToken web service
  • The response can be of 2 types:
    • AuthenticationResponseData : This response indicates that it is necessary to proceed with the authentication of the cardholder. You will then need to call back the same PCI/Charge/CreateToken with the result of the instruction for 3D Secure authentication.
    • Charge/Payment : This response indicates the end of the verification and the creation of the alias. It is then possible to check the result in the response.

If the merchant or card are not enrolled in the 3D Secure program, the call to the Web Service PCI/Charge/CreateToken returns a Payment object directly. In this particular case, there is no call to the notification URL.

Since authentication plays an important role in this web service, its operation is presented below:

Authentication scenario

The service adopts an operating principle that ignores the underlying protocol to provide a unique integration experience, and not integration by protocol.

The generic process of complete authentication consists of several stages:

  • An initial call to the PCI/Charge/CreateToken service with a response of AuthenticationResult or AuthenticationInstruction type.
  • If the return belongs to theAuthenticationInstructiontype, the operation must be performed on the merchant side:
    • Creation of a visible or invisible iFrame.
    • In the iFrame, browser redirection to a target page after submitting a form that respects the definition specified in the instruction.
    • Potential interaction with the cardholder or the browser.
    • Return page of the remote server that will emit a JavaScript event containing the result of the instruction.
    • Interception of the instruction result in the form of a JavaScript event in the parent window.
    • New call to the PCI/Charge/CreateToken service with the signed instruction result received via the browser.
    • The PCI/Charge/CreateToken service returns either an instruction or a result once again.
  • If the return is of AuthenticationResult type, it will contain the final authentication result and the process is complete.

Detailed flowchart

The following flowchart presents a generic payment scenario with authentication: the initial call to the service, an instruction, an interaction, the final authentication result and the end of payment.

The payment scenario is shown here as an illustration of a possible use of the PCI/Charge/CreateToken service. The authentication scenario starts at step 3 , and ends at step 17.

CLIENT

Browser

iFrame

Merchant server

Payment gateway server

Remote server (e.g.: ACS)

The return with the instruction result to the PCI/Charge/CreateToken service (steps 16 and 17 ) allows to check the integrity of the data that has passed through the buyer's browser, and to interpret the results according to the applied protocol.

We will present the different steps of the integration in the following paragraphs.

Integration Steps
Actions to perform on the merchant server side Steps 3 , 4 , 16 and 17
Actions to perform on the JavaScript side Steps 5 , 6 , 7 and 15

Steps 1 and 2: Initiation (payment or adding a card)

A payment or card registration action has been initiated and requires authentication.The PCI/Charge/CreateToken service is now ready to be called.

Step 3: Calling the PCI/Charge/CreateToken service

The initial request allows to transmit the data required for authentication.

Among this information, it is necessary to fill in some information about the client's browser or mobile device in the device object.

This information is mostly technical and must be retrieved from the browser or the mobile device (in JavaScript for example).

The goal is to facilitate customer identification (IP address) and their payment medium (browser size) for a more suitable authentication process.

See the integration documentation of the PCI/Charge/CreateToken service for more information on this field.

Here is an example describing the initial request:

/doc/en-EN/rest/V4.0/api/kb/authentication.html
https://github.com/lyra/rest-php-examples/blob/master/www/minimalEmbeddedForm.php#L9-L44
https://api.systempay.fr/api-payment/V4/PCI/Charge/CreateToken
{

  "currency": "EUR", 
  "orderId":"myOrderId",
  "paymentForms": [
    {
      "paymentMethodType": "CARD",
      "pan": "4970100000000014",
      "brand": "VISA",
      "expiryMonth": "02",
      "expiryYear": "27",
      "securityCode": "123"
    }
  ],
  "customer": {
    "email": "sample@example.com"
  },
  "device": {
    "deviceType": "BROWSER",
    "acceptHeader": "application/json",
    "ip": "89.249.65.28", 
    "javaEnabled": true,
    "language": "en",
    "colorDepth": "1",
    "screenHeight": 1024,
    "screenWidth": 768,
    "timezoneOffset": 0,
    "userAgent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0"
  }
}
/**
 * I initialize the PHP SDK
 */
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/keys.php';
require_once __DIR__ . '/helpers.php';

/** 
 * Initialize the SDK 
 * see keys.php
 */
$client = new Lyra\Client();

/**
 * I create a formToken
 */
$store = array("amount" => 250, 
"currency" => "EUR", 
"orderId" => uniqid("MyOrderId"),
"customer" => array(
  "email" => "sample@example.com"
));
$response = $client->post("V4/Charge/CreatePayment", $store);

/* I check if there are some errors */
if ($response['status'] != 'SUCCESS') {
    /* an error occurs, I throw an exception */
    display_error($response);
    $error = $response['answer'];
    throw new Exception("error " . $error['errorCode'] . ": " . $error['errorMessage'] );
}

/* everything is fine, I extract the formToken */
$formToken = $response["answer"]["formToken"];

?>

Step 4: Full response with an instruction

The response will contain an instruction in the following form (in this example it's a 3DS v1 authentication (deprecated)):

{
  "answer": {
	  "id": "c82794e9-9c20-44a8-9297-b70e1e7c4006",
	  "operationSessionId": "c7f9c8711d994aa5818f886dc995e9eb",
	  "protocol": {
			"name": "THREEDS",
			"network": "VISA",
			"version": "1.0.2",
			"challengePreference":"NO_PREFERENCE",
			"simulation":false,
			"_type": "V4/PCI/Charge/Authenticate/Protocol"
		},
		
	  "value": {  		
			"instructionType": "FORM",
			"name": "CHALLENGE",
			"timeout" : "15",
			"target": {
				"element": "IFRAME",
				"visible": true,
				"width": 400,
				"height": 400,
				"_type": "V4/PCI/Charge/Authenticate/InstructionTarget"
			},

			"http": {
				"method": "POST",
				"url": "https://acs.sg.com/1.0.2",
				"headers": {
					"Accept": "text/html"
				},
				"body": {
					"termUrl": "https://pass.sample-acs.net/v1/notify/threeds/v1/pares",
					"MD": "eJwljEmSokAAAL8yd2O6imLVCA+oINAKCLLekALZd2ggePz0dF/ylJnEB/xAG8GQLLcRiKRoZgtWnHtkwniZfw2qontZg4mvIv2SrOOGIMERCDJ/CHSg2QMkNpqEcNt/52iDEP1/bdVYFFsyDM0BgKIOgyKp++HAQQ6CKcD93yZYyqgawK/4A6VlbYPzWv0OZu3Gj04+rf6LMlQP8db81Tm7JXBxyrM3cKIYaV7GedZVQdLkWAo6W+ufqbUMjQxLQvkUIG8k384FpmsJfG2fQ0qzI3rulyLFqkPMYD9No8B48rkcrmI59ar3Yk29l6k8EQJPDlc9p+OqPzuxhul33WZx2TvmyNBxswb2U9OmCHFhelH8WI6e3nV2xVACYrHwadbjVpKbxxjWjywfgi7EK3ZWGTMnsSl2baxnlWKWhmXuqpOXX2JBhDDUebZccWyNOagnJHKm+kgz//4OF8oyrWig5hIAw1LL7jNTTkiw76DgJDl2VXKxGc4h0O1W9e4k1b4LPeRfzsh6H4//ANdloIQ=",
					"paReq": "eJxVUslu2zAQ/RVBd5mLLZk2RgzSBlkOCYLGPqSXgss4VmNJDkkHdr4+pKosPXHezPDN4xvC2bHdZa/ofNN3dc4mNM+wM71tuqc6X68uC5FnPqjOql3fYZ2f0OdnElZbh3jxgObgUMIteq+eMGtsnf8RSghqDS0st7yY0WpeaKNZoamwrFpQzSvMJdyf/8IXCeNoGSdPOJAPGCmd2aouSFDm5cfNnWTVdC6AjAhadDcXkvHprKyA/EPQqRblrRpu2hX6AGRIgekPXXAnyUsK5APAwe3kNoS9XxLSjrcmpm+BpAqQLw33hxT5yHRsrFRv9vlxuq0e//6+Ut3O6XV4sFeXpb5e10BSB1gVUHLKBOO0yhhflvMlZUCGPKg2SZDllEY5I4B9mnH+vfI9A9FpFzdzkotkwycCPO7jYmJHdO8zBovexBeMx5f8n9fJUBOSdxsurFa0VJrPNqg0ZTjb2LnhJU8+D02JvoleMUEXA38CQBINGTdIxu3H6L9f8Q7HNMYj"
				},
				"_type": "V4/PCI/Charge/Authenticate/HttpRequest"
			},
			"_type": "V4/PCI/Charge/Authenticate/AuthenticationInstruction"
	  },
	  "_type": "V4/AuthenticationResponseData"
  }
}

It consists of:

The Function
id Unique identifier of the authentication transaction in progress.
operationSessionId Unique session identifier for the current operation. It has to be passed to each new call.
protocol Indicates which protocol will be eventually applied during the authentication.
value Represents the result of the authentication or the instruction to follow. If value is of type AuthenticationInstruction , it is an instruction to be executed, if it is of type AuthenticationResult , it is the result of authentication.

Authentication typically takes place over multiple calls to the PCI/Charge/CreateToken service. In order to maintain the transaction, it is necessary to pass the id attribute received in this response on each call.

Step 5: Preparation of the instruction handling page

If an instruction was returned in the previous step, the page displayed in this step must allow:

  • To set up a listener for the type of event returned by the iFrame, which will trigger a POST to the merchant server with the instruction result (see step 15 ).
  • To create a hidden or visible iFrame (see steps 6 and 7 ).

Step 6: Creation of an iFrame

The instruction received in step 4 is as follows:

{
    
    "instructionType": "FORM",
    "name": "CHALLENGE",
    "timeout" : "15",
    "target": {
        "element": "IFRAME",
        "visible": true,
        "width": 400,
        "height": 400,
        "_type": "V4/PCI/Charge/Authenticate/InstructionTarget"
    },

    "http": {
        "method": "POST",
        "url": "https://acs.sg.com/1.0.2",
        "headers": {
            "Accept": "text/html"
        },
        "body": {
            "termUrl": "https://pass.sample-acs.net/v1/notify/threeds/v1/pares",
            "MD": "eJwljEmSokAAAL8yd2O6imLVCA+oINAKCLLekALZd2ggePz0dF/ylJnEB/xAG8GQLLcRiKRoZgtWnHtkwniZfw2qontZg4mvIv2SrOOGIMERCDJ/CHSg2QMkNpqEcNt/52iDEP1/bdVYFFsyDM0BgKIOgyKp++HAQQ6CKcD93yZYyqgawK/4A6VlbYPzWv0OZu3Gj04+rf6LMlQP8db81Tm7JXBxyrM3cKIYaV7GedZVQdLkWAo6W+ufqbUMjQxLQvkUIG8k384FpmsJfG2fQ0qzI3rulyLFqkPMYD9No8B48rkcrmI59ar3Yk29l6k8EQJPDlc9p+OqPzuxhul33WZx2TvmyNBxswb2U9OmCHFhelH8WI6e3nV2xVACYrHwadbjVpKbxxjWjywfgi7EK3ZWGTMnsSl2baxnlWKWhmXuqpOXX2JBhDDUebZccWyNOagnJHKm+kgz//4OF8oyrWig5hIAw1LL7jNTTkiw76DgJDl2VXKxGc4h0O1W9e4k1b4LPeRfzsh6H4//ANdloIQ=",
            "paReq": "eJxVUslu2zAQ/RVBd5mLLZk2RgzSBlkOCYLGPqSXgss4VmNJDkkHdr4+pKosPXHezPDN4xvC2bHdZa/ofNN3dc4mNM+wM71tuqc6X68uC5FnPqjOql3fYZ2f0OdnElZbh3jxgObgUMIteq+eMGtsnf8RSghqDS0st7yY0WpeaKNZoamwrFpQzSvMJdyf/8IXCeNoGSdPOJAPGCmd2aouSFDm5cfNnWTVdC6AjAhadDcXkvHprKyA/EPQqRblrRpu2hX6AGRIgekPXXAnyUsK5APAwe3kNoS9XxLSjrcmpm+BpAqQLw33hxT5yHRsrFRv9vlxuq0e//6+Ut3O6XV4sFeXpb5e10BSB1gVUHLKBOO0yhhflvMlZUCGPKg2SZDllEY5I4B9mnH+vfI9A9FpFzdzkotkwycCPO7jYmJHdO8zBovexBeMx5f8n9fJUBOSdxsurFa0VJrPNqg0ZTjb2LnhJU8+D02JvoleMUEXA38CQBINGTdIxu3H6L9f8Q7HNMYj"
        },
        "_type": "V4/PCI/Charge/Authenticate/HttpRequest"
    },
    "_type": "V4/PCI/Charge/Authenticate/AuthenticationInstruction"
}

The different properties of the iFrame to be created can be found in the target element:

		"target": {
		  "element": "IFRAME",
		  "visible": true,
		  "width": 400,
		  "height": 400
		}

If it must be visible ( value.target.visible attribute set to true ), create the iFrame with these parameters (using width and height ) and display it, or create a hidden iFrame.

Handling the iframe display timeout

It is also necessary to manage the maximum display time of the iframe if the value.timeout attribute is present in the instruction (timeout defined in seconds). To do so, it will be necessary to allow to trigger an event of LYRA_AUTH_INSTRUCTION_RESULT type populated as follows:

{
    eventName: 'LYRA_AUTH_INSTRUCTION_RESULT',
    value: {
        name: "Add here the instruction name you have received in the answer",
        value: 'TIMEOUT',
        protocol: "Add here the protocol object you have received in the answer"
    }
}

Example of implementation:

    function createInstructionIframe(instruction) {
        // Get instruction container element
        container = document.getElementById('instructionContainer');

        // Clean instruction container
        container.innerHTML = ';

        // Create iframe element
        var iframe = document.createElement('iframe');
        iframe.id = 'instructionIframe';
        iframe.name = 'instructionIframe';
        iframe.src = 'about:blank';
        iframe.style.width = instruction.value.target.width+"px";
        iframe.style.height = instruction.value.target.height+"px";
        iframe.style.visibility = instruction.value.target.visible ? 'visible' : 'hidden';

        // Handle timeout
        if(instruction.value.timeout){
            setTimeout(() => {
                const instructionResultTimeout = {
                    eventName: 'LYRA_AUTH_INSTRUCTION_RESULT',
                    value: {
                        name: instruction.value.name,
                        value: 'TIMEOUT',
                        protocol: {
                            name: instruction.protocol.name,
                            version: instruction.protocol.version,
                            network: instruction.protocol.network,
                            challengePreference: instruction.protocol.challengePreference,
                            simulation: instruction.protocol.simulation
                        },
                    },
                };
                window.postMessage(JSON.stringify(instructionResultTimeout), '*');
            }, instruction.value.timeout * 1000);
        }

        // Add iframe to container
        container.appendChild(iframe);

        // Create form to post
        var form = document.createElement('form');
        form.id = 'instructionForm';
        form.name = 'instructionForm';
        form.target = 'instructionIframe';
        form.method = instruction.value.http.method;
        form.action = instruction.value.http.url;
        form.style = 'visibility: hidden';

        // Create form body
        Object.keys(instruction.value.http.body).forEach(function (name) {
            form.innerHTML += '<input name="' + name + '" value="' + instruction.value.http.body[name] + '">';
        });
        var body = document.createElement('form');

        // Add form to container
        container.appendChild(form);

        // Triger form submit
        form.submit();
    }

Step 7: Form submission

Once the iFrame has been created, it must be filled with a form following the instructions of the ‘http’ tag:

"http": {
	"method": "POST",
	"url": "https://acs.sg.com/1.0.2",
	"headers": {
		"Accept": "text/html"
	},
	"body": {
		"termUrl": "https://pass.sample-acs.net/v1/notify/threeds/v1/pares",
		"MD": "eJwljEmSokAAAL8yd2O6imLVCA+oINAKCLLekALZd2ggePz0dF/ylJnEB/xAG8GQLLcRiKRoZgtWnHtkwniZfw2qontZg4mvIv2SrOOGIMERCDJ/CHSg2QMkNpqEcNt/52iDEP1/bdVYFFsyDM0BgKIOgyKp++HAQQ6CKcD93yZYyqgawK/4A6VlbYPzWv0OZu3Gj04+rf6LMlQP8db81Tm7JXBxyrM3cKIYaV7GedZVQdLkWAo6W+ufqbUMjQxLQvkUIG8k384FpmsJfG2fQ0qzI3rulyLFqkPMYD9No8B48rkcrmI59ar3Yk29l6k8EQJPDlc9p+OqPzuxhul33WZx2TvmyNBxswb2U9OmCHFhelH8WI6e3nV2xVACYrHwadbjVpKbxxjWjywfgi7EK3ZWGTMnsSl2baxnlWKWhmXuqpOXX2JBhDDUebZccWyNOagnJHKm+kgz//4OF8oyrWig5hIAw1LL7jNTTkiw76DgJDl2VXKxGc4h0O1W9e4k1b4LPeRfzsh6H4//ANdloIQ=",
		"paReq": "eJxVUslu2zAQ/RVBd5mLLZk2RgzSBlkOCYLGPqSXgss4VmNJDkkHdr4+pKosPXHezPDN4xvC2bHdZa/ofNN3dc4mNM+wM71tuqc6X68uC5FnPqjOql3fYZ2f0OdnElZbh3jxgObgUMIteq+eMGtsnf8RSghqDS0st7yY0WpeaKNZoamwrFpQzSvMJdyf/8IXCeNoGSdPOJAPGCmd2aouSFDm5cfNnWTVdC6AjAhadDcXkvHprKyA/EPQqRblrRpu2hX6AGRIgekPXXAnyUsK5APAwe3kNoS9XxLSjrcmpm+BpAqQLw33hxT5yHRsrFRv9vlxuq0e//6+Ut3O6XV4sFeXpb5e10BSB1gVUHLKBOO0yhhflvMlZUCGPKg2SZDllEY5I4B9mnH+vfI9A9FpFzdzkotkwycCPO7jYmJHdO8zBovexBeMx5f8n9fJUBOSdxsurFa0VJrPNqg0ZTjb2LnhJU8+D02JvoleMUEXA38CQBINGTdIxu3H6L9f8Q7HNMYj"
	},
	"_type": "V4/PCI/Charge/Authenticate/HttpRequest"
}
  • The method property indicates the HTTP verb to be associated with the form.
  • url indicates which server is targeted by the form action.
  • The HTTP request headers in headers.
  • The form parameters in body (e.g. termUrl, MD and paReq).

Once the form has been generated and placed in the iFrame, all you need to do is trigger it when the page is loading.

In case the timeout set in the iframe creation code is triggered, the LYRA_AUTH_INSTRUCTION_RESULT event will be caught by the listener whose details are described in step 15. This will allow the process to continue and have a final result.

Steps 8 to 14: User authentication

Once the form has been posted, the code of the issuing bank will take over the process to allow secure authentication (silent or interactive). At the end of this step, the LYRA_AUTH_INSTRUCTION_RESULT event will be issued from the iFrame to indicate the end of the process. Example:

{
    "eventName": "LYRA_AUTH_INSTRUCTION_RESULT",
    "value" : {
        "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
        "name": "CHALLENGE",
        "protocol": {
            "name": "THREEDS",
            "version": "2.1.0",
            "network": "VISA",
            "challengePreference" : "NO_PREFERENCE",
            "simulation": "false"
        }
    }
}

Step 15: Retrieval of the JavaScript event emitted in step 14

In order to interpret the LYRA_AUTH_INSTRUCTION_RESULT event, it is necessary to implement a listener on the main page. It must be capable of parsing JSON code and must be written as follows:

window.addEventListener('message', function (messageEvent) {
    
    var data = messageEvent.data;
    try {
        var messageData = JSON.parse(data);
        if (messageData.eventName === 'LYRA_AUTH_INSTRUCTION_RESULT') {
            try {
                // callback call with messageData.value content
                container = document.getElementById('instructionContainer');
                var form = document.createElement('form');
                
                form.method = 'POST';
                form.action = "https://myhost.com/payment/authentication/result.php";
                form.style = 'visibility: hidden';					
                    
                form.innerHTML += "<input name='messageData' value='" + data + "'>";  
                                
                var body = document.createElement('form');
                
                container.appendChild(form);
                form.submit();
            } catch (err) {
                // error callback call
            } finally {
                // always close the iFrame/popin
                container = document.getElementById('instructionContainer');
                container.remove();
            }
        }
    } catch (err) {
        // process eventual exceptions during callbacks
    }
    
}, false);

After that, you must return this data to the merchant server.

Step 16: Returning the instruction result to the merchant server

Once the instruction result is retrieved on the merchant server side, it must be returned via a new call to the PCI/Charge/CreateToken service. The request should contain the instructionResult object as well as the operationSessionId session identifier, received in the response of step 4 :

/doc/en-EN/rest/V4.0/api/kb/authentication.html
https://github.com/lyra/rest-php-examples/blob/master/www/minimalEmbeddedForm.php#L9-L44
https://api.systempay.fr/api-payment/V4/PCI/Charge/CreateToken
{
  "instructionResult": {
    "name" : "CHALLENGE",
    "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
    "protocol" : {
      "name" : "THREEDS",
      "network": "VISA",
      "version" : "1.0.2",
      "challengePreference": "NO_PREFERENCE",
      "simulation": false
    }
  },
  "operationSessionId": "c7f9c8711d994aa5818f886dc995e9eb"
}
/**
 * I initialize the PHP SDK
 */
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/keys.php';
require_once __DIR__ . '/helpers.php';

/** 
 * Initialize the SDK 
 * see keys.php
 */
$client = new Lyra\Client();

/**
 * I create a formToken
 */
$store = array("amount" => 250, 
"currency" => "EUR", 
"orderId" => uniqid("MyOrderId"),
"customer" => array(
  "email" => "sample@example.com"
));
$response = $client->post("V4/Charge/CreatePayment", $store);

/* I check if there are some errors */
if ($response['status'] != 'SUCCESS') {
    /* an error occurs, I throw an exception */
    display_error($response);
    $error = $response['answer'];
    throw new Exception("error " . $error['errorCode'] . ": " . $error['errorMessage'] );
}

/* everything is fine, I extract the formToken */
$formToken = $response["answer"]["formToken"];

?>

Step 17: Receiving the response from the payment gateway server

As in step 4 , the merchant server receives a new response, which can either be final ( AuthenticationResult ) or request a new instruction ( AuthenticationInstruction ). In the latter case, the flow resumes at step 5. Here is an example of the final message:

    {
        "answer": {
          "shopId": "33148340",
          "orderCycle": "CLOSED",
          "orderStatus": "PAID",
          "serverDate": "2020-03-23T14:31:14+00:00",
          "orderDetails": {
              "orderTotalAmount": 0,
              "orderEffectiveAmount": 0,
              "orderCurrency": "EUR",
              "mode": "TEST",
              "orderId": "myOrder"
          },
          "customer": {
              "billingDetails": {
                  "address": null,
                  "category": null,
                  "cellPhoneNumber": null,
                  "city": null,
                  "country": null,
                  "district": null,
                  "firstName": null,
                  "identityCode": null,
                  "language": "FR",
                  "lastName": null,
                  "phoneNumber": null,
                  "state": null,
                  "streetNumber": null,
                  "title": null,
                  "zipCode": null
              },
              "email": "sample@example.com",
              "reference": null,
              "shippingDetails": {
                  "address": null,
                  "address2": null,
                  "category": null,
                  "city": null,
                  "country": null,
                  "deliveryCompanyName": null,
                  "district": null,
                  "firstName": null,
                  "identityCode": null,
                  "lastName": null,
                  "legalName": null,
                  "phoneNumber": null,
                  "shippingMethod": null,
                  "shippingSpeed": null,
                  "state": null,
                  "streetNumber": null,
                  "zipCode": null
              },
              "extraDetails": {
                  "browserAccept": null,
                  "fingerPrintId": null,
                  "ipAddress": "10.33.160.29",
                  "browserUserAgent": "PostmanRuntime/7.23.0"
              },
              "shoppingCart": {
                  "insuranceAmount": null,
                  "shippingAmount": null,
                  "taxAmount": null,
                  "cartItemInfo": null
              }
          },
          "transactions": [
              {
                  "shopId": "33148340",
                  "uuid": "ca83e404cd134bef95dff577927d2e09",
                  "amount": 0,
                  "currency": "EUR",
                  "paymentMethodType": "CARD",
                  "paymentMethodToken": null,
                  "status": "PAID",
                  "detailedStatus": "ACCEPTED",
                  "operationType": "VERIFICATION",
                  "effectiveStrongAuthentication": "DISABLED",
                  "creationDate": "2020-03-23T14:31:13+00:00",
                  "errorCode": null,
                  "errorMessage": null,
                  "detailedErrorCode": null,
                  "detailedErrorMessage": null,
                  "metadata": null,
                  "transactionDetails": {
                      "liabilityShift": "NO",
                      "effectiveAmount": 0,
                      "effectiveCurrency": "EUR",
                      "creationContext": "VERIFICATION",
                      "cardDetails": {
                          "paymentSource": "EC",
                          "manualValidation": "NO",
                          "expectedCaptureDate": null,
                          "effectiveBrand": "VISA",
                          "pan": "497010XXXXXX0055",
                          "expiryMonth": 11,
                          "expiryYear": 2021,
                          "country": "FR",
                          "issuerCode": 17807,
                          "issuerName": "BP Occitane",
                          "effectiveProductCode": null,
                          "legacyTransId": "923865",
                          "legacyTransDate": "2020-03-23T14:31:13+00:00",
                          "paymentMethodSource": "TOKEN",
                          "authorizationResponse": {
                              "amount": null,
                              "currency": null,
                              "authorizationDate": null,
                              "authorizationNumber": null,
                              "authorizationResult": null,
                              "authorizationMode": "MARK"
                          },
                          "captureResponse": {
                              "refundAmount": null,
                              "captureDate": null,
                              "captureFileNumber": null,
                              "refundCurrency": null
                          },
                          "threeDSResponse": {
                              "authenticationResultData": {
                                  "transactionCondition": null,
                                  "enrolled": null,
                                  "status": null,
                                  "eci": null,
                                  "xid": null,
                                  "cavvAlgorithm": null,
                                  "cavv": null,
                                  "signValid": null,
                                  "brand": null
                              }
                          },
                          "authenticationResponse": {
                              "id": "451d6c8b-8ba9-4a10-854f-34308e5cff3b",
                              "operationSessionId": "c7f9c8711d994aa5818f886dc995e9eb",
                              "protocol": {
                                  "name": "THREEDS",
                                  "network": "VISA",
                                  "version": "1.0.2",
                                  "challengePreference": "NO_PREFERENCE",
                                  "simulation": false
                              },
                              "value": {
                                  "authenticationType": "CHALLENGE",
                                  "authenticationId": {
                                    "authenticationIdType":"xid",
                                    "value":"c82794e99c2044a89297b70e1e7c4006"
                                  },
                                  "authenticationValue": {
                                      "authenticationValueType": "CAVV",
                                      "value": "FsXD4Ox0VEI2MseoR0VhN5pX952I"
                                  },
                                  "status": "SUCCESS",
                                  "commerceIndicator": "05",
                                  "extension": {
                                    "enrolled": "Y",
                                    "algorithm": "2",
                                    "signatureValid": true
                                  },
                                  "reason": {
                                      "_type": "V4/PCI/Charge/Authenticate/AuthenticationResultReason"
                                  }
                              }
                          },
                          "installmentNumber": null,
                          "installmentCode": null,
                          "markAuthorizationResponse": {
                              "amount": 0,
                              "currency": "EUR",
                              "authorizationDate": "2020-03-23T14:31:13+00:00",
                              "authorizationNumber": "3fefaa",
                              "authorizationResult": "0"
                          },
                          "cardHolderName": null,
                          "identityDocumentNumber": null,
                          "identityDocumentType": null
                      },
                      "parentTransactionUuid": null,
                      "mid": "1549425",
                      "sequenceNumber": 1,
                      "taxAmount": null,
                      "preTaxAmount": null,
                      "taxRate": null,
                      "externalTransactionId": null,
                      "_type": "V4/TransactionDetails"
                  }
              }
          ]
      }
    }

Step 18: The merchant server resumes operations

If the previous response is a final result, the token creation is complete.

Appendix

Example: v2 3DS authentication with ACS authentication

  • An initial call to the PCI/Charge/CreateToken service with a v2 3DS enrolled card.
  • A return with a FINGERPRINT instruction (3DS Method).
  • A redirection to the ACS in the invisible iFrame, loading and execution of the JavaScript code of the ACS fingerprint.
  • A return via the browser with an instruction result.
  • A new call to the PCI/Charge/CreateToken service transmitting this result.
  • A return of the payment gateway server with a CHALLENGE instruction of redirection to the ACS with a CReq (visible iFrame).
  • The instruction has occurred (redirection to the ACS with a CReq and user interaction).
  • The return via browser is an instruction result: new call to the PCI/Charge/CreateToken service transmitting this result.
  • The server return is the final result of the authentication.

Glossary

3DS Method JavaScript code of the ACS executed in the Buyer’s browser for the purpose of making fingerprints.
3DS Requestor The requestor upon 3DS authentication, usually the Merchant or their payment gateway.
3DS Server 3DS Server. Component of the 3DS Requestor domain that initiates the 3DS v2 process and communicates with the DS or the ACS during transaction authentications. It facilitates the interaction between the 3DS Requestor and the DS.
ACS Access Control Server. Component that checks whether authentication is available for a card number and authenticates specific transactions.
Application 3DS Requestor Application on the Buyer’s mobile device that can process a 3DS transaction thanks to the use of 3DS SDK. The application is available by means of integration with 3DS SDK.
Challenge Interactive authentication phase between the Buyer and their bank (ACS).
CReq v2 3DS request message of cardholder authentication, sent to the ACS.
DS Directory Server. Component that maintains the list of intervals for cards with possible authentication allowing MPIs / 3DS Servers / ACS to communicate with each other during authentications.
Fingerprinting Corresponds to getting a fingerprint. Unique Buyer identification using browser data.
SDK 3DS 3D Secure development kit. Software component included in a 3DS Requestor Application.
IAN Server-to-server notification of authentication results (Instant Authentication Notification).
operationUrl Url sent to authentication script initialization methodkr-authenticate.js.
operationSessionId Unique identifier for the authentication session.

List of supported protocols

PROTOCOL Version
3D Secure 2.1.0
3D Secure 2.2.0

Test cards

The test card reference page can be found here.

© 2025 {'|'} All rights reserved to Systempaylegal
25.18-1.11