Integrating with 3D Secure (SCA Elbrus and Earlier)

Warning:

This topic applies to 3D Secure 1 only. Support for 3D Secure 1 ended on October 15, 2022. Relying on 3D Secure 1 for your SuiteCommerce Advanced web store is expected to result in more failed or declined payment card transactions. See End of Support for 3D Secure 1 for more information, including information about migrating your website technologies from 3D Secure 1 to 3D Secure 2.

Sites implementing the Elbrus release of SuiteCommerce Advanced and earlier do not, by default, support 3D Secure. To integrate these implementations with 3D Secure 1.0, you must either migrate to the latest release of SCA or implement the following customization for the Proceed to Checkout touch point according to the process defined below.

In an .ss file, call the submit method on the order shopping object, and pass the following paymentauthorization object fields as checkoutsettings parameters:

In addition to the .ss file, 3D Secure 1 integration requires client-side code to display 3D Secure information in the user interface and to provide order handling. For examples of this code, see the following:

Note:

Integration with third-party checkout providers is not available for SSP applications written in SuiteScript 2.0. For more information about SuiteScript 1.0, see SuiteScript 1.0 Guide.

Sample .ss File for 3D Secure 1 Integration

          function service(request,response)
{
   var returnval = null;
   
   try
   {
      var shoppingSession = nlapiGetWebContainer().getShoppingSession();
      
      var shipMethod = shoppingSession.getOrder().getShippingMethod();
      
      if (!shipMethod || !shipMethod.shipMethod)
      {
         var shipMethods = shoppingSession.getOrder().getAvailableShippingMethods();
         nlapiLogExecution("DEBUG", "setShippingMethod", JSON.stringify(shipMethods));
         shoppingSession.getOrder().setShippingMethod(shipMethods[0]);
      }
      
      var orderHandlerUrl = shoppingSession.getAbsoluteUrl('checkout', 'samplePlaceOrder.ss');
      var orderSetting = {paymentauthorization:{type: 'threedsecure', noredirect : 'T', termurl : orderHandlerUrl}};
      returnval = shoppingSession.getOrder().submit(orderSetting);
   }
   catch (e)
   {
      var nle = nlapiCreateError(e);
      returnval = {status : 'error', reasoncode : nle.getCode(), message : nle.getDetails()};
   }
   response.writeLine(JSON.stringify(returnval)); 

        

Sample for Adding 3D Secure 1 iFrame in User Interface

          <html>
<head><%=getPageFullHead()%>
<!--add css, js packages here -->
<link rel="stylesheet" type="text/css" href="css/style2.css" >
<script language='JavaScript' type='text/javascript'>
try {
   if (window.parent != window && window.parent.document.getElementById('threedsecureframe') != null) { window.parent.location.href = window.location.href; }
   } catch(e){ }
</script>
<script type="text/javascript" src="lib/sampleShoppingLib.js"></script>
<script type="text/javascript" src="lib/sampleClientLib.js"></script>
</head>   
<body onLoad="loadShoppingCart();">

<table cellpadding=0 cellspacing=0 border=0 width=100%><NLPAGETOP></table>

<%nlapiGetWebContainer().getPageGenerator().setSelectedTab(3);%>
<table width="100%">
<tr>
<td><div id="mainContents"></div></td>
</tr>
</table>
<table border=0>
<% var checkoutSettings = nlapiGetWebContainer().getShoppingSession().getSiteSettings(['checkout']); 
var paypalUrl = nlapiGetWebContainer().getShoppingSession().getAbsoluteUrl("checkout", "samplePaypalCheckout.ss");
<tr>
<td>
<input type="submit" name="placeorder" id="placeorder" value="Submit" style="" class="nlbutton" onclick="placeOrder()">
</td>
<td>&nbsp;</td>
<td >
<form name='paypalform' action='<%=paypalUrl%>' method='post'>
<input type='image' src='<%=checkoutSettings.checkout.paypalexpress.imageurl%>' class="nlbutton"/>
</form>
</a>
</td>
</tr>
</table>
<div id="paymentauthenticator"></div>
</body>
</html> 

        

Sample Client-Side Handler for 3D Secure 1 Order Submission

          function placeOrderCallBack(req)
{
    var responseObj = JSON.parse(req.responseText);
    if (responseObj.statuscode && responseObj.statuscode == "error")
    {
        // Order is not successful since payment authorization is required
        if (responseObj.reasoncode && responseObj.reasoncode == "ERR_WS_REQ_PAYMENT_AUTHORIZATION")
        {
            if (responseObj.paymentauthorization)
            {
                // grab the frame html for threedsecure and inject it into the page. this will trigger the autherization flow
                document.getElementById('paymentauthenticator').innerHTML = responseObj.paymentauthorization.servicehtml;
                var placeOrderBtn = document.getElementById('placeorder');
                if (placeOrderBtn)
                    placeOrderBtn.parentNode.removeChild(placeOrderBtn);
                var paypalBtn = document.getElementById('paypalcheckout');
                if (paypalBtn)
                    paypalBtn.parentNode.removeChild(paypalBtn);
                
            }
        }
    }
 
} 

        
          function service(request,response)
{
   var returnval = null;
 
   try
   {
      var shoppingSession = nlapiGetWebContainer().getShoppingSession();
      var orderHandlerUrl = shoppingSession.getAbsoluteUrl('checkout', 'samplePlaceOrder.ss');
        var orderSetting = {paymentauthorization:{type: 'threedsecure', noredirect : 'T', termurl : orderHandlerUrl}};
        returnval = shoppingSession.getOrder().submit(orderSetting);   }
   catch (e)
   {
      var nle = nlapiCreateError(e);
      returnval = {status : 'error', reasoncode : nle.getCode(), message : nle.getDetails()};
   }
   response.writeLine(JSON.stringify(returnval)); 

        
          function placeOrderCallBack(req)
{
   var responseObj = JSON.parse(req.responseText);
   if (responseObj.statuscode && responseObj.statuscode == "error")
   {
      // Order is not success since payment autherization is required
      if (responseObj.reasoncode && responseObj.reasoncode == "ERR_WS_REQ_PAYMENT_AUTHORIZATION")
      {
         if (responseObj.paymentauthorization)
         {
            // grab the frame html for threedsecure and inject it into the page. this will trigger the autherization flow
            document.getElementById('paymentauthenticator').innerHTML = responseObj.paymentauthorization.servicehtml;
            var placeOrderBtn = document.getElementById('placeorder');
            if (placeOrderBtn)
               placeOrderBtn.parentNode.removeChild(placeOrderBtn);
            var paypalBtn = document.getElementById('paypalcheckout');
            if (paypalBtn)
               paypalBtn.parentNode.removeChild(paypalBtn);
         }
      }
   }
 
} 

        

sampleShoppingLib.js

          function createCartItemRow(nlCartItem, itemAttributes)
{
   var row = document.createElement('tr');
   
   for (var i = 0; i < itemAttributes.length; i++)
   {
      row.appendChild(createCartItemCell(getCartItemAttributeText(itemAttributes[i], nlCartItem[itemAttributes[i]])));
   }

   return row;
}
function getCartItemAttributeText(attrName, attrValue)
{
   if (attrName === 'options')
   {
      var attrText = '';
      if (attrValue)
      {
         for (var i = 0; i < attrValue.length; i++)
         {
            var itemOption = attrValue[i];
            attrText += itemOption.name + ':' + itemOption.displayvalue + '\n';
         }
      }
      return attrText;
   }
   else
      return attrValue;
}

function createCartItemCell(nlCartItemAttr)
{
   var cell = document.createElement('td');
   cell.setAttribute('class', 'texttable');
   var txtCell = document.createTextNode(nlCartItemAttr);
   cell.appendChild(txtCell);
   return cell;
}

function createCartTableHeader(headerItems)
{
   var theader = document.createElement('thead');
   theader.setAttribute('id', 'carttableheader');
   for (var i = 0; i < headerItems.length; i++)
   {
      theader.appendChild(createCartHeaderCell(headerItems[i]));
   }
   return theader;
}
function createCartHeaderCell(nlCartHeaderItem)
{
   var cell = document.createElement('th');
   var txtCell = document.createTextNode(nlCartHeaderItem);
   cell.appendChild(txtCell);
   return cell;
}

function createShoppingCart(nlShoppingOrder)
{   
   var headerItems = ['Name', 'Description', 'Options', 'Quantity', 'Rate', 'Amount'];
   var itemAttributes = ['name', 'salesdesc', 'options', 'quantity', 'rate', 'amount'];   
   var shoppingCart = document.createElement('table');
   shoppingCart.setAttribute('id', 'carttable');
   shoppingCart.setAttribute('width', '100%');
   
   var theader = createCartTableHeader(headerItems);
   shoppingCart.appendChild(theader);

   var tbody = document.createElement('tbody');
   
   if (nlShoppingOrder && nlShoppingOrder.items)
   {
      for (var i = 0; i < nlShoppingOrder.items.length; i++)
      {
         tbody.appendChild(createCartItemRow(nlShoppingOrder.items[i], itemAttributes));
      }
   }

   shoppingCart.appendChild(tbody);
   document.getElementById('mainContents').appendChild(shoppingCart);
}

function loadShoppingCart() {
   sendRequest('sampleGetOrderFields.ss', loadShoppingCartCallback);
   sendRequest('sampleGetCheckoutUrl.ss', loadCheckoutSettingCallback);
}

function loadCheckoutSetting() {
   sendRequest('sampleGetCheckoutUrl.ss', loadCheckoutSettingCallback);
}

function loadCheckoutSettingCallback(req) {
   var checkoutSetting = JSON.parse(req.responseText);
   var paypalBtn = document.getElementById('paypalcheckout');
   if (paypalBtn)
      paypalBtn.href = checkoutSetting.paypalexpress;
   }

function loadShoppingCartCallback(req) {
   //render the items table
   var order = JSON.parse(req.responseText);
   createShoppingCart(order);
}

function placeOrder() 
{
   sendRequest('samplePlaceOrder.ss', placeOrderCallBack);
}
function placeOrderCallBack(req)
{   
   var responseObj = JSON.parse(req.responseText);
   if (responseObj.statuscode && responseObj.statuscode == "error")
   {
      // Order is not success since payment autherization is required
      if (responseObj.reasoncode && responseObj.reasoncode == "ERR_WS_REQ_PAYMENT_AUTHORIZATION")
      {
         if (responseObj.paymentauthorization) 
         {
            // grab the frame html for threedsecure and inject it into the page. this will trigger the autherization flow
            document.getElementById('paymentauthenticator').innerHTML = responseObj.paymentauthorization.servicehtml;
            var placeOrderBtn = document.getElementById('placeorder');
            if (placeOrderBtn)
               placeOrderBtn.parentNode.removeChild(placeOrderBtn);
            var paypalBtn = document.getElementById('paypalcheckout');
            if (paypalBtn)
               paypalBtn.parentNode.removeChild(paypalBtn);
         }
      }
   }

} 

        

sampleClientLib.js

          function sendRequest(url,callback,postObjName, postData) {
   var req = createXMLHTTPObject();
   if (!req) return;
   var method = (postData) ? "POST" : "GET";
   req.open(method,url,true);
   req.setRequestHeader('User-Agent','XMLHTTP/1.0');
   if (postData) {
      req.setRequestHeader('Content-type','application/x-www-form-urlencoded');
      req.setRequestHeader(postObjName, JSON.stringify(postData));
      }
   req.onreadystatechange = function () {
      if (req.readyState != 4) return;
      if (req.status != 200 && req.status != 304) {
//         alert('HTTP error ' + req.status);
         return;
      }
      callback(req);
   }
   if (req.readyState == 4) return;
   req.send();
   //req.send(postData);
}

var XMLHttpFactories = [
   function () {return new XMLHttpRequest()},
   function () {return new ActiveXObject("Msxml2.XMLHTTP")},
   function () {return new ActiveXObject("Msxml3.XMLHTTP")},
   function () {return new ActiveXObject("Microsoft.XMLHTTP")}
];

function createXMLHTTPObject() {
   var xmlhttp = false;
   for (var i=0;i<XMLHttpFactories.length;i++) {
      try {
         xmlhttp = XMLHttpFactories[i]();
      }
      catch (e) {
         continue;
      }
      break;
   }
   return xmlhttp;
} 

        

samplePaypalCheckout.ss

          function service(request,response)
{
   var returnval = null;
   
   try
   {
      
      var shoppingSession = nlapiGetWebContainer().getShoppingSession();
      var siteSetting = shoppingSession.getSiteSettings(['touchpoints']);
   
      var viewcart = siteSetting.touchpoints.viewcart;
      var homeurl = siteSetting.touchpoints.home;
      var checkouturl = siteSetting.touchpoints.checkout;
      
      var testUrl = shoppingSession.getAbsoluteUrl('/sampleGcoCheckout.ss');
      var testUrl2 = shoppingSession.getAbsoluteUrl('lib/sampleShoppoingLib.js');
   
      var paypalSetting = {type: 'paypalexpress', continueurl : checkouturl, cancelurl : viewcart};
   
      nlapiGetWebContainer().getShoppingSession().proceedToCheckout(paypalSetting);
   }
   catch (e)
   {
      var nle = nlapiCreateError(e);
      returnval = {status : 'error', reasoncode : nle.getCode(), message : nle.getDetails()};
      
      response.writeLine(JSON.stringify(returnval));
   }
} 

        

Related Topics

Integrating with PayPal Express
Integration with Third-Party Checkout Providers

General Notices