Integrating with 3D Secure

To integrate your SSP application's checkout with 3D Secure, you must do the following for the Proceed to Checkout touch point:

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

  • type - set to “threedsecure”

  • noredirect - indicates whether platform returns a status object with required fields for 3D Secure instead of doing a redirect when 3D Secure authorization is required, default is F

    Note the following:

    • If noredirect is set to F threedsecure , redirect goes to the default 3D Secure authorization page.

    • If noredirect is set to T when 3D Secure authorization is required, the submit method returns the order status as error, with a reason code of ERR_WS_REQ_PAYMENT_AUTHORIZATION, along with values for the paymentauthorization JSON object. You can use these values to handle the integration with 3D Secure.

  • termurl - URL for client-side handler to process 3D Secure callback, to submit order with 3D Secure response parameters

In addition to the .ss file, 3D secure 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.


Sample .ss File for 3D Secure 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 Frame 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 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)); } }