1.11. Recurring Sale
Introduction
Recurring Sale Flow
Note
Initial payment transaction type and implementation depends on Connecting Party business model. Please contact Denumtech support team to get relevant integration Use-Case for initial payment.
3DS Decision Making Schema
Connecting party has to implement all steps marked in green and purple. Below are the description for steps which reference specific API commands according to the step ID:
Non3D Flow
Sale transaction should be considered as non3D (no 3DS authentication) if all conditions are met:
Note
Please note that transaction status “unknown” might appear for both 3DS and non3D transactions. See details in Statuses.
3DS 2.x.0 Frictionless Flow
Connecting party has to implement all steps marked in green. Below are the description for steps which reference specific API commands according to the step ID:
3DS Method HTML Page Example
3DS Method HTML Page example below performs 3DS Method initiation through iframe technique and holding of the Payer’s browser until the 3DS Method is not finished on the Connecting Party server. Once it is finished or timeout is reached Connecting Party has to follow the next steps following 3DS Decision Making Schema and redirect Payer’s browser to the corresponding URL (either Challenge Flow or payment result page). Normal timeout value is 30 sec.
3DS Method HTML Page consists of the following parameters:
Parameter |
Description |
---|---|
tds-method-url-frame-3ds-method-url |
ACS 3DS Method URL is received by the Connecting Party in the /api/v2/status/ response. |
tdsMethodUploadUrl |
Connecting Party’s URL, where the result comes after the completion of the flow. |
threeDSMethodData |
JSON value containing threeDSServerTransID and threeDSMethodNotificationURL. See below how to construct threeDSMethodData. |
Construct threeDSMethodData
In order to construct threeDSMethodData the Connecting Party has to use the following parameters.
Parameter |
Description |
---|---|
threeDSServerTransID |
Universally unique transaction identifier assigned by the 3DS Server to identify a single transaction.
Received in the /api/v2/status/ response as tds-method-url-frame-3ds-server-trans-id parameter.
|
threeDSMethodNotificationURL |
The URL that will receive the notification of 3DS Method completion from the ACS. The Connecting Party is responsible for providing valid threeDSMethodNotificationURL. Normally when the Connecting Party receives any request on this URL is has to return 3DS Method Done HTML Page (see example below). |
threeDSMethodData construction example
Construct threeDSMethodData JSON
{"threeDSServerTransID":"3d671629-a410-4a5d-9288-b38ceadd41f2","threeDSMethodNotificationURL":"https://merchant.com/3ds-method-complete/"}
Apply base64 url encoding to resultant JSON
eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6IjNkNjcxNjI5LWE0MTAtNGE1ZC05Mjg4LWIzOGNlYWRkNDFmMiIsInRocmVlRFNNZXRob2ROb3RpZmljYXRpb25VUkwiOiJodHRwczovL21lcmNoYW50LmNvbS8zZHMtbWV0aG9kLWNvbXBsZXRlLyJ9
Generating Fingerprint.
The 3DS Method can be optionally used by issuers to gather browser fingerprints using JavaScript. This is done by loading a URL in a hidden iframe, before the authentication. This iframe will then execute some fingerprinting JavaScript, before POST’ing to the prespecified URL belonging to the requestor. The 3DS Method fingerprint result is tied to the authentication by the threeDSServerTransID
function gatherBrowserData() {
var colorDepth = screen.colorDepth; // 24
var javaEnabled = navigator.javaEnabled(); // true
var browserLanguage = navigator.language; // en_US
var screenHeight = screen.height; // 1080
var screenWidth = screen.width; // 1920
var userAgent = navigator.userAgent; // Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36
var browserTimezoneZoneOffset = new Date().getTimezoneOffset(); // 0
}
Construct 3DS Method HTML page example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>ACS v2 3DS Method ...</title>
<style>
.progress{
position: absolute;
height: 10px;
width: 100%;
}
.progress .color{
position: absolute;
background-color: #444;
width: 100%;
height: 10px;
animation: progres 11s linear;
}
@keyframes progres{
0%{
width: 0%;
background-color: #ddd;
}
25%{
width: 50%;
background-color: #ccc;
}
50%{
width: 75%;
background-color: #bbb;
}
75%{
width: 85%;
background-color: #aaa;
}
100%{
width: 100%;
background-color: #777;
}
};
</style>
<script>
var fallbackTimeout = null;
function processForm() {
document.title = "ACS v2 AReq ...";
document.getElementById( "browserJavaEnabled" ).value = navigator.javaEnabled();
document.getElementById( "browserJavascriptEnabled" ).value = true;
document.getElementById( "browserLanguage" ).value = navigator.language;
document.getElementById( "browserColorDepth" ).value = screen.colorDepth;
document.getElementById( "browserScreenHeight" ).value = screen.height;
document.getElementById( "browserScreenWidth" ).value = screen.width;
document.getElementById( "browserTZ" ).value = new Date().getTimezoneOffset();
document.autoForm.submit();
}
function onPostMessage(event) {
if(!event.data.hasOwnProperty('methodNotification')) {
return;
}
if(fallbackTimeout != null) {
clearTimeout(fallbackTimeout);
fallbackTimeout = null;
}
document.getElementById( "threeDSCompInd" ).value = 'Y';
processForm();
}
function onPageLoaded() {
fallbackTimeout = setTimeout(processForm, 10 * 1000);
document.methodForm.submit();
window.addEventListener('message', onPostMessage);
}
</script>
</head>
<body onload="onPageLoaded()">
<div class="progress">
<div class="color"></div>
</div>
<iframe style="width:0; height:0; border:0;" name="methodFrame"></iframe>
<form name="methodForm" target="methodFrame" action="[=tds-method-url-frame-3ds-method-url]" method="POST">
<input type="hidden" name="threeDSMethodData" value="[=threeDSMethodData]">
</form>
<form name="autoForm" action="[=tdsMethodUploadUrl]" method="post">
<input type="hidden" name="threeDSServerTransID" value="[=threeDSServerTransID]"/>
<input type="hidden" name="threeDSCompInd" id="threeDSCompInd" value="N"/>
<input type="hidden" name="browserJavaEnabled" id="browserJavaEnabled" value="" />
<input type="hidden" name="browserJavascriptEnabled" id="browserJavascriptEnabled" value="" />
<input type="hidden" name="browserLanguage" id="browserLanguage" value="" />
<input type="hidden" name="browserColorDepth" id="browserColorDepth" value="" />
<input type="hidden" name="browserScreenHeight" id="browserScreenHeight" value="" />
<input type="hidden" name="browserScreenWidth" id="browserScreenWidth" value="" />
<input type="hidden" name="browserTZ" id="browserTZ" value="" />
<noscript>
<input type="submit" name="submit" value="Upload 3DS Method Result"/>
</noscript>
</form>
</body>
</html>
Process 3DS Method Notification
When 3DS Method is completed, the Connecting Party receives HTTP POST request at threeDSMethodNotificationURL with threeDSMethodData, which contains threeDSServerTransID (in base64 encoded JSON).
Get threeDSMethodData
threeDSMethodData=eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6IjNkNjcxNjI5LWE0MTAtNGE1ZC05Mjg4LWIzOGNlYWRkNDFmMiJ9Cg
Apply base64 url decoding to get JSON, which contains threeDSServerTransID
{"threeDSServerTransID":"3d671629-a410-4a5d-9288-b38ceadd41f2"}
3DS Method Done HTML Page Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>ACS v2 3DS Method Notification Handler...</title>
<script>
window.parent.postMessage({ methodNotification: "COMPLETE" }, "*");
</script>
</head>
<body>
<p>This should not be displayed</p>
</body>
</html>
3DS 2.x.0 Challenge Flow
CReq HTML Page Example
CReq HTML Page redirects the Payer’s browser to ACS Server URL, provided in tds-creq-form-acs-url parameter. The result CRes value will be returned from ACS to notificationURL provided by Connecting Party on the previous step.
Field |
Description |
Necessity |
---|---|---|
creq |
ACS 3DS CReq data, which received by the Connecting Party in the /api/v2/status/ response. The same as tds-creq-form-creq. |
Required |
threeDSSessionData |
value which will be posted back within CRes to notificationURL at the end of the process. Max length: 1024 bytes, format: Alphanumeric, Base64url encoded without padding. |
Optional |
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Redirecting ...</title>
<script type="text/javascript" language="javascript">
function makeSubmit() {
document.returnform.submit();
}
</script>
</head>
<body onLoad="makeSubmit()">
<form name="returnform" action="https://acs.bank-domain.com/mdpayacs/creq" method="POST">
<input type="hidden" name="creq" value="eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6ImM1NDA5N2VhLTc0ZTctNDE2My05MTQ4LTNjMTY1NTg3NGIwMCIsImFjc1RyYW5zSUQiOiIxMjU1NTkyMi1lZmYzLTRjOTQtOTk4Mi0yMDM3NjJhMzdmMjkiLCJjaGFsbGVuZ2VXaW5kb3dTaXplIjoiMDIiLCJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIn0=">
<input type="hidden" name="threeDSSessionData" value="NjY4MDU3NQ">
<noscript>
<input type="submit" name="submit" value="Press this button to continue"/>
</noscript>
</form>
</body>
</html>
3DS 1.0.2 Authentication Flow
PaReq HTML Page Example
PaReq HTML Page redirects the Payer’s browser to ACS Server URL, provided in tds-pareq-form-acs-url parameter.
PaReq HTML Page consists of the following parameters:
Field |
Description |
Necessity |
---|---|---|
tds-pareq-form-acs-url |
ACS 3DS PaReq URL is received by the Connecting Party in the /api/v2/status/ response |
Required |
PaReq |
ACS 3DS PaReq data, which received by the Connecting Party in the /api/v2/status/ response. The same as tds-pareq-form-pareq |
Required |
TermURL |
URL of termination page, where the Payer gets redirected back with PaRes data submitted |
Required |
MD |
Merchant Data (Connecting Party Data), which comes back to your termination page |
Optional |
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Loading acs..</title>
<script type="text/javascript" language="javascript">
function makeSubmit() {
document.returnform.submit();
}
</script>
</head>
<body onLoad="makeSubmit()">
<form name="returnform" action="$tds-pareq-form-acs-url" method="POST">
<input type="hidden" name="MD" value="some_merchant_data"/>
<input type="hidden" name="PaReq" value="$tds-pareq-form-pareq"/>
<input type="hidden" name="TermUrl" value="https://termination.page"/>
<noscript>
<input type="submit" name="submit" value="Submit"/>
</noscript>
</form>
</body>
</html>