/**
* Container for a Payment Requests. Provides Payment Parameters for Redirect or Direct Link requests.
*
* Requirements:
* - Payment Processor of appropriated Payment Method must point to Payment Method ID (prefixed by PAYMENT_PROCESSOR_PREFIX)
* - Appropiated Credit Card Type must be same as according BRAND (eg. VISA, MasterCard etc.)
*
* @module lib/libPayment.ds
*/
var dwutil = require('dw/util'),
dworder = require('dw/order'),
dwcustomer = require('dw/order'),
dwsystem = require('dw/system'),
dwweb = require('dw/web'),
dwnet = require('dw/net'),
dwcrypto = require('dw/crypto'),
dwvalue = require('dw/value'),
dwsvc = require('dw/svc'),
dwobject = require('dw/object');
/**
* @constructor
*
* @param {dw.order.LineItemCtnr} lineItemCtnr
* @param {String} orderNo
* @param {Number} amount
* @param {String} paymentMethod
* @param {dw.system.Request} request
* @param {String} locale
*/
function PaymentCtnr(lineItemCtnr, orderNo, amount, paymentMethod, request, locale) {
/************* Constructor - initialize general container members *******/
try {
var IngenicoConfiguration = getIngenicoConfiguration();
var PAYMENT_PROCESSOR_PREFIX = "PAYMENT_";
var DEFAULT_LANGUAGE = "fr_FR";
var ACCEPT_URL = dwweb.URLUtils.https('PAYMENT_HOSTED_TOKENIZATION_PAGE_CREDIT_CARD-3DSAccept');
var DECLINE_URL = dwweb.URLUtils.https('PAYMENT_HOSTED_TOKENIZATION_PAGE_CREDIT_CARD-3DSDecline');
var EXCEPTION_URL = dwweb.URLUtils.https('PAYMENT_HOSTED_TOKENIZATION_PAGE_CREDIT_CARD-3DSExcept');
// use same URL for back and cancel
var CANCEL_URL = dwweb.URLUtils.https('PAYMENT_HOSTED_TOKENIZATION_PAGE_CREDIT_CARD-3DSCancel');
var BACK_URL = dwweb.URLUtils.https('PAYMENT_HOSTED_TOKENIZATION_PAGE_CREDIT_CARD-3DSCancel');
// Operation should be left empty otherwise back office configuration
// will be overritten!
var OPERATION = "";
var TEMPLATE_URL = dwweb.URLUtils.https('PAYMENT_HOSTED_TOKENIZATION_PAGE_CREDIT_CARD-Template');
var log = dwsystem.Logger.getLogger("payment");
//login data
var pspId = IngenicoConfiguration.PSPID;
var userId = IngenicoConfiguration.apiUserID;
var userPwd = IngenicoConfiguration.apiUserPassword;
//orig
var orig = IngenicoConfiguration.transactionTracker;
var orderId = orderNo;
var order = lineItemCtnr;
var payId = null;
var amount = !empty(amount) ? (amount*100).toFixed() : null;
var address = null;
var profile = null;
var email = null;
var fullName = null; //firstname + lastname
var address1 = null;
var city = null;
var postalCode = null;
var phoneNo = null;
var country = null;
var language = !empty(request) ? dwutil.Locale.getLocale(request.getLocale()).ID : null;
var customLanguage = IngenicoConfiguration.language;
// Fallback to Fr_fr
language = empty(language) ? DEFAULT_LANGUAGE : language;
if (customLanguage != null) {
language = customLanguage ;
}
var currency = null;
var ccNumber = null;
var ccExpiry = null;
var ccHolder = null;
var cardType = null;
var paypaltxtoken=null;
var paypalpayid=null;
var billFirstname=null;
var billLastname=null;
var civility=null;
// set DW Payment Method ID if specified - otherwise Payment Method
// of first Payment instrument is used
var paymentMethodID = !empty(paymentMethodID) ? paymentMethodID : null;
var paymentMethod = null;
// Status of Payment 0 - Incomplete or invalid ; 5 - Authorized;9 - Payment requested ...
var status = null;
// SHA
var shaIn = IngenicoConfiguration.shaPasword;
var hashMethod = hashMethod || IngenicoConfiguration.shaMethod;
var digest = new dwcrypto.MessageDigest(hashMethod);
// Basket or Order
if (!empty(lineItemCtnr)) {
// Get Payment Instrument of specified Payment Method - otherwise first Payment Instrument is used
var paymentInstruments = !empty(paymentMethodID) ? lineItemCtnr.getPaymentInstruments(paymentMethodID) : lineItemCtnr.getPaymentInstruments();
if (!paymentInstruments.empty) {
// this is only one value
var paymentInstrument = paymentInstruments[0];
if (!empty(paymentInstrument)) {
var paymentTransaction = paymentInstrument.getPaymentTransaction();
// Set Payment Method again to ensure appropiate Payment Method is used
paymentMethodID = paymentInstrument.getPaymentMethod();
// Retrieve Payment Method from Payment Processor
paymentMethod = dworder.PaymentMgr.getPaymentMethod(paymentMethodID).getPaymentProcessor().getID().replace(PAYMENT_PROCESSOR_PREFIX, "");
if (paymentMethod!='ECOMMERCE_PAYPAL') {
cardType = paymentInstrument.getCreditCardType();
// Used for Credit Card Direct Link
ccNumber = paymentInstrument.getCreditCardNumber();
ccExpiry = formatExpiryNumbers(paymentInstrument.getCreditCardExpirationMonth(), paymentInstrument.getCreditCardExpirationYear());
ccHolder = paymentInstrument.getCreditCardHolder();
} else {
paypaltxtoken = paymentInstrument.custom.paypalToken;
paypalpayid = paymentInstrument.custom.paypalPayerID;
}
if (!empty(paymentTransaction)) {
// Retrieve Amount if not specified
amount = empty(amount) ? (paymentTransaction.getAmount().getValue()*100).toFixed() : amount;
if ((amount) <= 0) {
throw Error("Invalid authorization Amount 0.00 at payment transaction; Basket total gross price: " + lineItemCtnr.getTotalGrossPrice());
}
payId = paymentTransaction.getTransactionID();
status = paymentTransaction.custom.paymentStatus;
} else {
throw Error("No Payment Trancsaction available");
}
} else {
throw Error("No Payment Instrument available");
}
} else {
throw Error("No Payment Instrument available");
}
var currency = lineItemCtnr.getCurrencyCode();
email = lineItemCtnr.getCustomerEmail();
// Get Address
address = lineItemCtnr.getBillingAddress();
if (!empty(address)) {
fullName = address.getFullName();
address1 = address.getAddress1();
city = address.getCity();
postalCode = address.getPostalCode();
phoneNo = address.getPhone();
country = address.getCountryCode();
billFirstname=address.getFirstName();
billLastname=address.getLastName();
}
var customer = lineItemCtnr.getCustomer();
if (!empty(customer) && customer.isAuthenticated()) {
profile = customer.getProfile();
if (profile.gender.value==1) {
civility='M';
} else {
civility='F';
}
}
var payIdSub = lineItemCtnr.custom.payment_payidSUB;
}
} catch (error) {
throw error;
}
/************* General setter used for Payment Direct Link *******/
this.setPaymentMethod = function(pm) {
paymentMethod = pm;
};
/************* General getter used for Payment Redirect and Payment Direct Link *******/
this.getPspId = function() {
return pspId;
};
this.getOrder = function() {
return order;
};
this.getUserId = function() {
return userId;
};
this.getUserPwd = function() {
return userPwd;
};
this.getOrderId = function() {
return orderId;
};
this.getAmount = function() {
return amount;
};
this.getEmail = function() {
return email;
};
this.getCurrency = function() {
return currency;
};
this.getLanguage = function() {
return language;
};
this.getFullName = function() {
return fullName;
};
this.getAddress1 = function(value) {
return address1;
};
this.getCity = function() {
return city;
};
this.getPostalCode = function() {
return postalCode;
};
this.getPhoneNo = function() {
return phoneNo;
};
this.getCountry = function() {
return !empty(country) ? country.value : country;
};
this.getAcceptUrl = function() {
return ACCEPT_URL;
};
this.getDeclineUrl = function() {
return DECLINE_URL;
};
this.getExceptionUrl = function() {
return EXCEPTION_URL;
};
this.getCancelUrl = function() {
return CANCEL_URL;
};
this.getBackUrl = function() {
return BACK_URL;
};
this.getOperation = function() {
return OPERATION;
};
this.getTemplateUrl = function() {
return TEMPLATE_URL;
};
this.getPaymentMethodId = function() {
return paymentMethodID;
};
this.getCreditCardType = function() {
return cardType;
};
this.getPaymentProcessorId = function() {
return (PAYMENT_PROCESSOR_PREFIX + paymentMethod).toUpperCase();
};
this.getPaymentMethod = function() {
return paymentMethod;
};
this.getCCHolder = function() {
return ccHolder;
};
this.getCCNumber = function() {
return ccNumber;
};
this.getCCExpiry = function() {
return ccExpiry;
};
this.getPayId = function() {
return payId;
};
this.getPayIdSub = function() {
return payIdSub;
};
this.getStatus = function() {
return status;
};
this.getPayPalTXTOKEN = function() {
return paypaltxtoken;
};
this.getPayPalPayID = function() {
return paypalpayid;
};
this.getBillFirstName = function() {
return billFirstname;
};
this.getBillLastName = function() {
return billLastname;
};
this.getCivility = function() {
return civility;
};
this.getOrig = function() {
return orig;
};
// Status critical issue fix
this.checkStatus = function(statusCode, errorCode) {
// Possible results are: FAIL, RETRY, SUCCESS
var result = "SUCCESS";
switch(statusCode.toString()) {
case "0": //0 Incomplete or invalid
if(this.retryErrorCodes(errorCode))
result = "RETRY";
else
result = "FAIL";
break;
case "1": //1 Cancelled by customer
if(this.retryErrorCodes(errorCode))
result = "RETRY";
else
result = "FAIL";
break;
case "2": //2 Authorisation declined
if(this.retryErrorCodes(errorCode))
result = "RETRY";
else
result = "FAIL";
break;
case "6": //6 Authorised and cancelled
if(this.retryErrorCodes(errorCode))
result = "RETRY";
else
result = "FAIL";
break;
case "7": //7 Payment deleted
if(this.retryErrorCodes(errorCode))
result = "RETRY";
else
result = "FAIL";
break;
default:
result = "SUCCESS";
break;
}
if(statusCode.toString().length > 1 && statusCode.toString() != "93") {
result = "RETRY";
}
return result;
};
// Error codes list with RETRY
this.retryErrorCodes = function(errorCode) {
var retryErrorCodes = {
'0020001001': 'Authorisation failed. Please retry.',
'0020001002': 'Authorisation failed. Please retry.',
'0020001003': 'Authorisation failed. Please retry.',
'0020001004': 'Authorisation failed. Please retry.',
'0020001005': 'Authorisation failed. Please retry.',
'0020001006': 'Authorisation failed. Please retry.',
'0020001007': 'Authorisation failed. Please retry.',
'0020001008': 'Authorisation failed. Please retry.',
'0020001009': 'Authorisation failed. Please retry.',
'0020001010' : 'Authorisation failed. Please retry.',
'30001010' : 'A technical problem has occurred. Please contact the helpdesk.',
'30001011' : 'A technical problem has occurred. Please contact the helpdesk.',
'30001015' : 'There has been a connection error to the receiving bank. Please try later or choose another payment method.',
'30001057' : 'There has been a connection error to the receiving bank. Please try later or choose another payment method.',
'30001058' : 'There has been a connection error to the receiving bank. Please try later or choose another payment method.',
'30001998' : 'A technical problem has occurred. Please try again.',
'30001999' : 'There has been a connection error with the receiving bank. Please try later or choose another payment method.',
'30611001' : 'Amount exceeds card limit',
'30961001' : 'Processing temporarily not possible',
'40001001': 'A technical problem has occurred. Please try again.',
'40001002': 'A technical problem has occurred. Please try again.',
'40001003': 'A technical problem has occurred. Please try again.',
'40001004': 'A technical problem has occurred. Please try again.',
'40001005': 'A technical problem has occurred. Please try again.',
'40001006': 'A technical problem has occurred. Please try again.',
'40001007': 'A technical problem has occurred. Please try again.',
'40001008': 'A technical problem has occurred. Please try again.',
'40001009' : 'A technical problem has occurred. Please try again.',
'40001010' : 'A technical problem has occurred. Please try again.',
'40001012' : 'There has been a connection error with the receiving bank. Please try later or choose another payment method.',
'40001018' : 'A technical problem has occurred. Please try again.',
'40001019' : 'Sorry, an error has occurred during processing. Please retry the transaction (using the Back button of the browser). If the problem persists, contact your merchant\'s helpdesk.',
'40001020' : 'Sorry, an error occurred during processing. Please retry the operation (using the Back button of the browser). If the problem persists, please contact your merchant\'s helpdesk.',
'40001134' : 'Authentication failed. Please retry or cancel.',
'40001135' : 'Authentication temporarily unavailable. Please retry or cancel.',
'40001136' : 'Technical problem with your browser. Please retry or cancel.',
'40001137' : 'Your bank is temporarily unavailable. Please try again later or choose another payment method.',
'50001174' : 'Cardholder Name is too long'
};
return retryErrorCodes[errorCode.toString()] != null ? true : false;
}
/************* Get request parameters for Redirect *******/
this.getRequestParameters = function() {
var query = '';
if (empty(this.getOrderId()) || empty(this.getAmount()) || empty(this.getCurrency())) {
throw Error("No Order ID, Amount and Currency available");
}
// Add parameter uppercase for sort of sha sign
var paymentRequestParameters = new dwutil.HashMap();
// Mandatory Parameters
paymentRequestParameters.put('PSPID', this.getPspId());
paymentRequestParameters.put('ORDERID', this.getOrderId());
paymentRequestParameters.put('AMOUNT', this.getAmount());
paymentRequestParameters.put('CURRENCY', this.getCurrency());
paymentRequestParameters.put('LANGUAGE', this.getLanguage());
// Email
paymentRequestParameters.put('EMAIL', this.getEmail());
// Address
paymentRequestParameters.put('CN', this.getFullName());
paymentRequestParameters.put('OWNERADDRESS', this.getAddress1());
paymentRequestParameters.put('OWNERTOWN', this.getCity());
paymentRequestParameters.put('OWNERZIP', this.getPostalCode());
paymentRequestParameters.put('OWNERTELNO', this.getPhoneNo());
paymentRequestParameters.put('OWNERCTY', this.getCountry());
// Redirect URLS
paymentRequestParameters.put('ACCEPTURL', this.getAcceptUrl());
paymentRequestParameters.put('DECLINEURL', this.getDeclineUrl());
paymentRequestParameters.put('EXCEPTIONURL', this.getExceptionUrl());
paymentRequestParameters.put('CANCELURL', this.getCancelUrl());
paymentRequestParameters.put('BACKURL', this.getBackUrl());
//ORIG
paymentRequestParameters.put('ORIG', this.getOrig());
// Payment
paymentRequestParameters.put('PM', this.getPaymentMethod());
// Operation
paymentRequestParameters.put('OPERATION', this.getOperation());
// Template
paymentRequestParameters.put('TP', this.getTemplateUrl());
//Additional Parameters
paymentRequestParameters.put('PARAMPLUS', 'dw_paymentmethodid=' + this.getPaymentMethodId());
// add SHA Sign
paymentRequestParameters.put("SHASIGN", getSHASignParameterFromRequest(paymentRequestParameters, shaIn, digest,this.getOrderId()));
return paymentRequestParameters;
};
/************* Get parameters for Direct Link Requests *******/
//Paypal Order Query
this.getPayPalOrderQuery = function(timeout) {
var query = '';
if (empty(this.getOrderId()) || empty(this.getAmount()) || empty(this.getCurrency())) throw Error("No Order ID, Amount and Currency available");
// Add parameter alphabetical sorted for sha sign
var queryMap = new dwutil.HashMap();
// required for credit card
queryMap.put("ORDERID", this.getOrderId());
queryMap.put("AMOUNT", this.getAmount());
queryMap.put("CURRENCY",this.getCurrency());
queryMap.put("LANGUAGE",this.getLanguage());
queryMap.put("EMAIL", this.getEmail());
queryMap.put("OWNERADDRESS", this.getAddress1());
queryMap.put("OWNERCTY", this.getCountry());
queryMap.put("OWNERTELNO", this.getPhoneNo());
queryMap.put("OWNERTOWN", this.getCity());
queryMap.put("ORIG", this.getOrig());
queryMap.put("OWNERZIP", this.getPostalCode());
queryMap.put("TXTOKEN", this.getPayPalTXTOKEN());
queryMap.put("PAYID", this.getPayPalPayID());
queryMap.put("PM", "PAYPAL");
queryMap.put("SHASIGN", this.getSHASignParameterFromQuery(queryMap). toUpperCase());
return getURIParametersFromMap(queryMap);
};
//New Order Query for Direct Debits
this.getNewOrderQueryDirectDebits = function(operation, data, timeout, locale, customer) {
var query = '';
if (empty(this.getOrderId()) || empty(this.getAmount()) || empty(this.getCurrency())) {
throw Error("No Order ID, Amount and Currency available");
}
// Add parameter alphabetical sorted for sha sign
var queryMap = new dwutil.HashMap();
// required for direct debits
queryMap.put("ORDERID", this.getOrderId());
queryMap.put("AMOUNT", this.getAmount());
if (!empty(operation)) {
queryMap.put("OPERATION", operation);
}
queryMap.put("ED", this.getCCExpiry());
queryMap.put("CURRENCY", this.getCurrency());
queryMap.put("LANGUAGE", this.getLanguage());
// address
queryMap.put("CN", this.getCCHolder());
queryMap.put("EMAIL", this.getEmail());
queryMap.put("OWNERADDRESS", this.getAddress1());
queryMap.put("OWNERCTY", this.getCountry());
queryMap.put("OWNERTELNO", this.getPhoneNo());
queryMap.put("OWNERTOWN", this.getCity());
queryMap.put("ORIG", this.getOrig());
queryMap.put("OWNERZIP", this.getPostalCode());
queryMap.put("PM", this.getPaymentMethodId().replace(/_/g, " "));
// direct debits fields
if (data['iban']) {
queryMap.put("CARDNO", data['iban']);
} else {
if (data['konto'] && data['blz']) {
queryMap.put("CARDNO", data['konto'] + 'BLZ' + data['blz']);
}
}
// New SEPA version
var enableNewSEPAVersion = IngenicoConfiguration.enableNewSEPAVersion;
if (enableNewSEPAVersion) {
queryMap.put("MANDATEID", this.getOrderId());
if (data['transactionDate']) {
var sequenceType = 'OOFF';
if (data['bic']) {
queryMap.put("BIC", data['bic']);
}
queryMap.put("SIGNDATE", data['transactionDate']);
queryMap.put("SEQUENCETYPE", sequenceType);
}
}
// add SHA Sign
queryMap.put("SHASIGN", this.getSHASignParameterFromQuery(queryMap).toUpperCase());
return getURIParametersFromMap(queryMap);
};
//New Order Query for Credit Card HostedTokenization
this.getNewOrderQueryCreditCardHostedTokenization = function(operation, enable3DS, timeout,locale) {
var query = '';
if (empty(this.getOrderId()) || empty(this.getAmount()) || empty(this.getCurrency())) {
throw Error("No Order ID, Amount and Currency available");
}
// Add parameter alphabetical sorted for sha sign
var queryMap = new dwutil.HashMap();
// required for credit card
queryMap.put("ORDERID", this.getOrderId());
queryMap.put("AMOUNT", this.getAmount());
if (!empty(operation)) {
queryMap.put("OPERATION", operation);
}
queryMap.put("CURRENCY",this.getCurrency());
queryMap.put("LANGUAGE",this.getLanguage());
queryMap.put("EMAIL", this.getEmail());
queryMap.put("OWNERADDRESS", this.getAddress1());
queryMap.put("OWNERCTY", this.getCountry());
queryMap.put("OWNERTELNO", this.getPhoneNo());
queryMap.put("OWNERTOWN", this.getCity());
queryMap.put("ORIG", this.getOrig());
queryMap.put("OWNERZIP", this.getPostalCode());
queryMap.put("PM", this.getPaymentMethod());
//alias
queryMap.put("ALIAS", session.custom.alias);
queryMap.put("ALIASUSAGE",true);
// 3DS
queryMap.put("FLAG3D", enable3DS ? "Y" : "N");
if (enable3DS) {
queryMap.put("ACCEPTURL", this.getAcceptUrl()+"?orderNo="+this.getOrderId()+"&pmID="+this.getPaymentMethod() + "&tn=" + createShaForUrls(this.getOrder()));
queryMap.put("DECLINEURL", this.getDeclineUrl()+"?orderNo="+this.getOrderId()+"&pmID="+this.getPaymentMethod() + "&tn=" + createShaForUrls(this.getOrder()));
queryMap.put("EXCEPTIONURL", this.getExceptionUrl()+"?orderNo="+this.getOrderId()+"&pmID="+this.getPaymentMethod() + "&tn=" + createShaForUrls(this.getOrder()));
queryMap.put("ORIG", this.getOrig());
queryMap.put("CANCELURL", this.getCancelUrl()+"?orderNo="+this.getOrderId()+"&pmID="+this.getPaymentMethod() + "&tn=" + createShaForUrls(this.getOrder()));
queryMap.put("BACKURL", this.getBackUrl()+"?orderNo="+this.getOrderId()+"&pmID="+this.getPaymentMethod() + "&tn=" + createShaForUrls(this.getOrder()));
queryMap.put("COMPLUS", locale);
// necessary for return from redirect
queryMap.put("PARAMPLUS", "dw_is3ds=true&dw_paymentmethodid=" + this.getPaymentMethodId());
}
// Request timeout value in seconds. The value you set here must be smaller than the
// timeout value in DW!
// queryMap.put("RTIMEOUT", (timeout / 1000) - 1);
// add SHA Sign
queryMap.put("SHASIGN", this.getSHASignParameterFromQuery(queryMap));
return getURIParametersFromMap(queryMap);
};
//Direct Query
this.getDirectQuery = function(timeout) {
var query = '';
if (empty(this.getOrderId()) || empty(this.getAmount()) || empty(this.getCurrency())) throw Error("No Order ID, Amount and Currency available");
// Add parameter alphabetical sorted for sha sign
var queryMap = new dwutil.HashMap();
queryMap.put("ORDERID", this.getOrderId());
queryMap.put("PAYID", this.getPayId());
if(this.getPayIdSub() != null){
queryMap.put("PAYIDSUB", this.getPayIdSub());
}
// add SHA Sign
queryMap.put("SHASIGN", this.getSHASignParameterFromQuery(queryMap).toUpperCase());
return getURIParametersFromMap(queryMap);
};
//Maintainance Query
this.getMaintenanceQuery = function(operation, timeout) {
var query = '';
if (empty(this.getOrderId()) && empty(this.getPayId())) throw Error("No Order ID or Pay (transaction) ID available");
// Add parameter alphabetical sorted for sha sign
var queryMap = new dwutil.HashMap();
// required for maintenace request
queryMap.put("ORDERID", this.getOrderId());
queryMap.put("PAYID", this.getPayId());
queryMap.put("AMOUNT", this.getAmount());
queryMap.put("OPERATION", operation);
// Request timeout value in seconds. The value you set here must be smaller than the
// timeout value in DW!
// queryMap.put("RTIMEOUT", (timeout / 1000) - 1);
// add SHA Sign
queryMap.put("SHASIGN", this.getSHASignParameterFromQuery(queryMap));
return getURIParametersFromMap(queryMap);
};
this.getCredentialQuery = function() {
return dwutil.StringUtils.format("PSPID={0}&PSWD={2}&USERID={1}", encodeURIComponent(this.getPspId()), encodeURIComponent(this.getUserId()), encodeURIComponent(this.getUserPwd()));
};
// get SHA Sign Parameter for query parameter
this.getSHASignParameterFromQuery = function(queryMap) {
var paramMap = queryMap.clone();
// put credientials since they are missing in Query
paramMap.put("PSPID", this.getPspId());
paramMap.put("USERID", this.getUserId());
paramMap.put("PSWD", this.getUserPwd());
return getSHASignParameterFromRequest(paramMap, shaIn, digest, this.getOrderId());
};
// Perfrom the HTTP request to server and handle the response
this.sendRequest = function(url, query, requestParameters, serviceName) {
var log = dwsystem.Logger.getLogger("payment");
var service = dwsvc.ServiceRegistry.get(serviceName);
var requestUrl = '';
var logUrl = '';
var start = new Date();
var paramseters = requestParameters.split('&');
requestParameters += !empty(query) ? query : '';
requestUrl = url + "?" + requestParameters;
var callPrams = {
"url" : requestUrl,
"paramseters" : paramseters
}
// mask PWD, PCI and Customer relevant data
logUrl = requestUrl.replace(/([?|&](PSWD|CVC|CARDNO|CN|ED|OWNERADDRESS|OWNERTELNO|OWNERZIP|EMAIL|BIC|)=)[^&]*/g, '$1***');
log.debug("Payment request:" + logUrl);
try {
var client = service.call(callPrams).object;
log.debug("Payment response:" + client.text);
//parse response
if (client.statusCode == 200) {
var resultXML = new XML(client.text);
var succ = false;
var ncError = resultXML.@["NCERROR"];
var ncStatus = resultXML.@["NCSTATUS"];
var status = resultXML.@["STATUS"];
var errorMsg = dwutil.StringUtils.format("ncError: {0}, ncStatus: {1}, status: {2}, ncErrorPlus: {3}", ncError, ncStatus, status, resultXML.@["NCERRORPLUS"]);
// ncError of '0' or '' indicates valid request and response
if (ncError == "0" || ncError == "") {
return resultXML;
} else if(resultXML.@["PM"] == 'PAYPAL' && status == "0"){
// quickfix for paypal status 0
return resultXML;
} else {
var end = new Date();
var difference = (end.getTime() - start.getTime()) * 0.001;
var error = new Error(dwutil.StringUtils.format("Error returned by Payment. Return Code: {0}; Message: {1}; Url: {2}; PaymentError: {3}; Seconds since start: {4}", client.statusCode, client.statusMessage, logUrl, errorMsg, difference));
error.ErrorCode = ncError;
error.ErrorMsg = errorMsg;
error.paymentErrorMsgPlus = resultXML.@["NCERRORPLUS"].toString();
error.status = status;
throw error;
}
} else {
var end = new Date();
var difference = (end.getTime() - start.getTime()) * 0.001;
throw Error(dwutil.StringUtils.format("Error connecting to Payment. Return Code: {0}; Message: {1}; Url: {2}; Seconds since start: {3}", client.statusCode, client.statusMessage, logUrl, difference));
}
} catch (error) {
var x = error;
var end = new Date();
var difference = (end.getTime() - start.getTime()) * 0.001;
log.error("Error in connection to Payment: {0}; Return Code: {1}; Message: {2}; Seconds since start: {3}\n\tStack: {4}\tRequestUrl: {5}", error, client.statusCode, client.statusMessage, difference, error.stack, logUrl);
throw error;
}
};
// New Order Request for Direct Link, Credit Card Hosted Tokenization
this.sendDirectLinkCreditCardHostedTokenizationNewOrderRequest = function(operation, enable3DS, locale, url, timeout) {
var url = url || IngenicoConfiguration.NewOrderEndpoint;
var timeout = timeout || IngenicoConfiguration.paymentCartridgeTimeout;
var query = this.getNewOrderQueryCreditCardHostedTokenization(operation, enable3DS, timeout,locale);
var requestParameters = this.getCredentialQuery();
var responseXML = new XML();
responseXML = this.sendRequest(url, query, requestParameters, "Ingenico.sendDirectLinkCreditCardNewOrderRequest");
var useFraudDetection = IngenicoConfiguration.enableFraudDetection;
var resultObj = {};
if (!empty(useFraudDetection) && useFraudDetection) {
resultObj = {
status : responseXML.@["STATUS"].toString(),
payid : responseXML.@["PAYID"].toString(),
pm : responseXML.@["PM"].toString(),
brand : responseXML.@["BRAND"].toString(),
html : responseXML.HTML_ANSWER.toString(),
cvccheck : responseXML.@["CVCCHECK"].toString(),
aavcheck : responseXML.@["AAVCHECK"].toString(),
ip : responseXML.@["IP"].toString(),
scoring : responseXML.@["SCORING"].toString(),
sco_category : responseXML.@["SCO_CATEGORY"].toString()
};
} else {
resultObj = {
status : responseXML.@["STATUS"].toString(),
payid : responseXML.@["PAYID"].toString(),
pm : responseXML.@["PM"].toString(),
brand : responseXML.@["BRAND"].toString(),
html : responseXML.HTML_ANSWER.toString()
};
}
return resultObj;
};
// New Order Request for Direct Link, Direct Debits
this.sendDirectLinkDirectDebitsNewOrderRequest = function(operation, locale, data, url, timeout) {
var url = url || IngenicoConfiguration.NewOrderEndpoint;
var timeout = timeout || IngenicoConfiguration.paymentCartridgeTimeout;
var query = this.getNewOrderQueryDirectDebits(operation, data, timeout, locale);
var requestParameters = this.getCredentialQuery();
var responseXML = new XML();
responseXML = this.sendRequest(url, query, requestParameters, "Ingenico.sendDirectLinkDirectDebitsNewOrderRequest");
var useFraudDetection = IngenicoConfiguration.enableFraudDetection;
if (!empty(useFraudDetection) && useFraudDetection) {
resultObj = {
status : responseXML.@["STATUS"].toString(),
payid : responseXML.@["PAYID"].toString(),
pm : responseXML.@["PM"].toString(),
brand : responseXML.@["BRAND"].toString(),
html : responseXML.HTML_ANSWER.toString(),
cvccheck : responseXML.@["CVCCHECK"].toString(),
aavcheck : responseXML.@["AAVCHECK"].toString(),
ip : responseXML.@["IP"].toString(),
scoring : responseXML.@["SCORING"].toString(),
sco_category : responseXML.@["SCO_CATEGORY"].toString()
};
} else {
resultObj = {
status : responseXML.@["STATUS"].toString(),
payid : responseXML.@["PAYID"].toString(),
pm : responseXML.@["PM"].toString(),
brand : responseXML.@["BRAND"].toString(),
html : responseXML.HTML_ANSWER.toString()
};
}
return resultObj;
};
//Direct Link Direct Query request
this.sendDirectQuery = function() {
var url = url || IngenicoConfiguration.DirectQueryEndpoint;
var timeout = timeout || IngenicoConfiguration.paymentCartridgeTimeout;
var query = this.getDirectQuery(timeout);
var requestParameters = this.getCredentialQuery();
var responseXML = new XML();
responseXML = this.sendRequest(url, query, requestParameters, "Ingenico.sendDirectQuery");
var useFraudDetection = IngenicoConfiguration.enableFraudDetection;
if (!empty(useFraudDetection) && useFraudDetection) {
resultObj = {
status : responseXML.@["STATUS"].toString(),
payid : responseXML.@["PAYID"].toString(),
pm : responseXML.@["PM"].toString(),
brand : responseXML.@["BRAND"].toString(),
html : responseXML.HTML_ANSWER.toString(),
cvccheck : responseXML.@["CVCCHECK"].toString(),
aavcheck : responseXML.@["AAVCHECK"].toString(),
ip : responseXML.@["IP"].toString(),
scoring : responseXML.@["SCORING"].toString(),
sco_category : responseXML.@["SCO_CATEGORY"].toString()
};
} else {
resultObj = {
status : responseXML.@["STATUS"].toString(),
payid : responseXML.@["PAYID"].toString(),
pm : responseXML.@["PM"].toString(),
brand : responseXML.@["BRAND"].toString(),
html : responseXML.HTML_ANSWER.toString()
};
}
return resultObj;
};
//Direct Link Direct Query request
this.sendDirectLinkPayPal = function() {
var url = IngenicoConfiguration.NewOrderEndpoint;
var timeout = IngenicoConfiguration.paymentCartridgeTimeout;
var query = this.getPayPalOrderQuery(timeout);
var requestParameters = this.getCredentialQuery();
var responseXML = new XML();
responseXML = this.sendRequest(url, query, requestParameters, "Ingenico.sendDirectLinkPayPal");
var useFraudDetection = IngenicoConfiguration.enableFraudDetection;
if (!empty(useFraudDetection) && useFraudDetection) {
resultObj = {
status : responseXML.@["STATUS"].toString(),
payid : responseXML.@["PAYID"].toString(),
pm : responseXML.@["PM"].toString(),
brand : responseXML.@["BRAND"].toString(),
html : responseXML.HTML_ANSWER.toString(),
cvccheck : responseXML.@["CVCCHECK"].toString(),
aavcheck : responseXML.@["AAVCHECK"].toString(),
ip : responseXML.@["IP"].toString(),
scoring : responseXML.@["SCORING"].toString(),
sco_category : responseXML.@["SCO_CATEGORY"].toString()
};
} else {
resultObj = {
status : responseXML.@["STATUS"].toString(),
payid : responseXML.@["PAYID"].toString(),
pm : responseXML.@["PM"].toString(),
brand : responseXML.@["BRAND"].toString(),
html : responseXML.HTML_ANSWER.toString()
};
}
return resultObj;
};
//Maintainance Request
this.sendDirectLinkMaintenanceRequest = function(operation, url, timeout) {
var url = url || IngenicoConfiguration.MaintainanceEndpoint;
var timeout = timeout || IngenicoConfiguration.paymentCartridgeTimeout;
var query = this.getMaintenanceQuery(operation, timeout);
var requestParameters = this.getCredentialQuery();
var responseXML = new XML();
responseXML = this.sendRequest(url, query, requestParameters, "Ingenico.sendDirectLinkMaintenanceRequest");
var resultObj = {
status : responseXML.@["STATUS"].toString(),
payid : responseXML.@["PAYID"].toString(),
pm : responseXML.@["PM"].toString()
};
return resultObj;
};
}
/************* Helper Functions *******/
/**
* Get SHASign used for request
*
* @param {dw.util.HashMap} requestParameters
* @param {String} shaIn
* @param {dw.crypto.MessageDigest} digest
* @param {String} orderID
* @param {Object} comparator
* @returns {dw.crypto.MessageDigest} digest
*/
function getSHASignParameterFromRequest(requestParameters, shaIn, digest, orderID, comparator) {
// Add parameter alphabetical sorted for sha sign
if(comparator) {
var paramSortedMap = new dwutil.SortedMap(comparator);
} else {
var paramSortedMap = new dwutil.SortedMap();
}
paramSortedMap.putAll(requestParameters);
// build sha sign
var paramKeySet = paramSortedMap.keySet();
var paramIterator = paramKeySet.iterator();
var paramValue = '';
var paramName = '';
var shaSign = '';
var shaSignLog = '';
while ( paramIterator.hasNext() ) {
paramName = paramIterator.next().toString();
paramValue = paramSortedMap.get(paramName);
if (!empty(paramValue)) {
//var parambytes=new dwutil.Bytes(paramValue.toString());
//parambytes.toString("windows-1252")
shaSign += paramName.toUpperCase() + '=' + paramValue.toString() + shaIn;
}
}
if (!empty(shaIn) && !empty(shaSign)) {
return digest.digest(shaSign);
}
return '';
}
/**
* Get SHASign used for request
*
* @param {dw.util.HashMap} requestParameters
* @param {String} shaIn
* @param {dw.crypto.MessageDigest} digest
* @param {String} orderID
* @param {Object} comparator
* @returns {dw.crypto.MessageDigest} digest
*/
function getSHASignParameterFromRequestUtf(requestParameters, shaIn, digest, orderID, comparator) {
// Add parameter alphabetical sorted for sha sign
if(comparator) {
var paramSortedMap = new dwutil.SortedMap(comparator);
} else {
var paramSortedMap = new dwutil.SortedMap();
}
paramSortedMap.putAll(requestParameters);
// build sha sign
var paramKeySet = paramSortedMap.keySet();
var paramIterator = paramKeySet.iterator();
var paramValue = '';
var paramName = '';
var shaSign = '';
while ( paramIterator.hasNext() ) {
paramName = paramIterator.next().toString();
paramValue = paramSortedMap.get(paramName);
if (!empty(paramValue)) {
shaSign += paramName.toUpperCase() + '=' + paramValue.toString() + shaIn;
}
}
if (!empty(shaIn) && !empty(shaSign)) {
return digest.digest(shaSign);
}
return '';
}
/**
* format expiry YYMM
*
* @param {Number} month
* @param {number} year
* @returns {String | null}
*/
function formatExpiryNumbers(month, year) {
if (!empty(month) && !empty(year)) {
return dwutil.StringUtils.formatNumber(month, "00") + year.toString().substring(year.toString().length - 2);
}
return null;
}
/**
* get URI Parameter from map
*
* @param {dw.util.HashMap} paramMap
* @returns {String} query
*/
function getURIParametersFromMap(paramMap) {
var paramKeySet = paramMap.keySet();
var paramIterator = paramKeySet.iterator();
var paramValue = '';
var paramName = '';
var query = '';
while ( paramIterator.hasNext() ) {
paramName = paramIterator.next().toString();
paramValue = paramMap.get(paramName);
//paramValue=removeFrenchChar(paramValue.toString());
if (!empty(paramValue)) {
query += "&" + paramName + '=' + encodeURIComponent(paramValue.toString());
}
}
return query;
}
/**
* generate SHA for Ecommerce
*
* @param {dw.order.Order} order
* @param {Number} gender
* @param {String} locale
* @returns {dw.crypto.MessageDigest} shaCode
*/
function generateSHAEcommerce(order, gender, locale){
var paymentRequestParameters = new dwutil.HashMap();
var IngenicoConfiguration = getIngenicoConfiguration();
var cartAmountDec = new dwutil.Decimal(parseFloat(order.totalGrossPrice.value));
cartAmountDec = cartAmountDec.round(2);
cartAmountDec = cartAmountDec.multiply(100);
var cartAmount = cartAmountDec.get().toString();
var civility='';
if(!empty(gender)){
if(gender==1){
civility='M';
}else{
civility='F';
}
}
var cn = order.getBillingAddress().getLastName();
var billtofirstname = order.getBillingAddress().getFirstName();
var billtolastname = order.getBillingAddress().getLastName();
var emailaddress = order.getCustomerEmail();
var currency = order.getCurrencyCode();
//get language from SitePreferences , else get the default one
var lang='';
if (locale=='default') {
lang = 'fr_FR';
} else {
lang = locale + "_" + locale.toUpperCase();
}
var customLanguage = IngenicoConfiguration.language;
if (customLanguage != null) {
lang = customLanguage;
}
var orderid = order.orderNo;
var owneraddress = order.getBillingAddress().getAddress1();
var ownercity = order.getBillingAddress().getCountryCode().value;
var ownertel = order.getBillingAddress().getPhone();
var ownertown = order.getBillingAddress().getCity();
var ownerzip = order.getBillingAddress().getPostalCode();
var pspid = IngenicoConfiguration.PSPID;
var ecommaccepturl = dwweb.URLUtils.https('PAYMENT_ECOMMERCE-EcommAccept','orderNo',order.orderNo,'pmID',order.getPaymentInstruments()[0].paymentMethod, 'tn', createShaForUrls(order));
var ecommdeclineurl = dwweb.URLUtils.https('PAYMENT_ECOMMERCE-EcommDecline','orderNo',order.orderNo,'pmID',order.getPaymentInstruments()[0].paymentMethod, 'tn', createShaForUrls(order));
var ecommdcancel = dwweb.URLUtils.https('PAYMENT_ECOMMERCE-EcommCancel','orderNo',order.orderNo,'pmID',order.getPaymentInstruments()[0].paymentMethod, 'tn', createShaForUrls(order));
var useStaticTemplate = IngenicoConfiguration.enableStaticTemplate;
var useDynamicTemplate = IngenicoConfiguration.enableDynamicTemplate;
var auth2Steps = IngenicoConfiguration.enableTwoStepsAuthorizationEcommerce;
paymentRequestParameters.put('AMOUNT', cartAmount);
if (!empty(gender)) {
paymentRequestParameters.put('CIVILITY', civility);
}
paymentRequestParameters.put('CN',cn);
paymentRequestParameters.put('CURRENCY',currency);
paymentRequestParameters.put('ECOM_BILLTO_POSTAL_NAME_FIRST',billtofirstname);
paymentRequestParameters.put('ECOM_BILLTO_POSTAL_NAME_LAST',billtolastname);
paymentRequestParameters.put('EMAIL',emailaddress);
paymentRequestParameters.put('LANGUAGE',lang);
paymentRequestParameters.put('ORDERID', orderid);
paymentRequestParameters.put('OWNERADDRESS',owneraddress );
paymentRequestParameters.put('OWNERCTY', ownercity);
paymentRequestParameters.put('OWNERTELNO', ownertel);
paymentRequestParameters.put('OWNERTOWN', ownertown);
paymentRequestParameters.put('ORIG', IngenicoConfiguration.transactionTracker);
paymentRequestParameters.put('OWNERZIP', ownerzip);
paymentRequestParameters.put('PSPID',pspid);
paymentRequestParameters.put('ACCEPTURL',ecommaccepturl);
paymentRequestParameters.put('DECLINEURL',ecommdeclineurl);
paymentRequestParameters.put('CANCELURL',ecommdcancel);
paymentRequestParameters.put('COMPLUS',locale);
if (!empty(auth2Steps) && auth2Steps) {
paymentRequestParameters.put('OPERATION',"RES");
}else{
paymentRequestParameters.put('OPERATION',"SAL");
}
//parameters for Static Template
if (!empty(useStaticTemplate) && useStaticTemplate) {
if (!empty(IngenicoConfiguration.paymentTemplateTitle)) {
paymentRequestParameters.put("TITLE",IngenicoConfiguration.paymentTemplateTitle);
}
if (!empty(IngenicoConfiguration.paymentTemplateBGColor)) {
paymentRequestParameters.put("BGCOLOR",IngenicoConfiguration.paymentTemplateBGColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateTxtColor)) {
paymentRequestParameters.put("TXTCOLOR",IngenicoConfiguration.paymentTemplateTxtColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateTblBGColor)) {
paymentRequestParameters.put("TBLBGCOLOR",IngenicoConfiguration.paymentTemplateTblBGColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateTblTxtColor)) {
paymentRequestParameters.put("TBLTXTCOLOR",IngenicoConfiguration.paymentTemplateTblTxtColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateButtonBGColor)) {
paymentRequestParameters.put("BUTTONBGCOLOR",IngenicoConfiguration.paymentTemplateButtonBGColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateButtonTxtColor)) {
paymentRequestParameters.put("BUTTONTXTCOLOR",IngenicoConfiguration.paymentTemplateButtonTxtColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateFontType)) {
paymentRequestParameters.put("FONTTYPE",IngenicoConfiguration.paymentTemplateFontType);
}
if (!empty(IngenicoConfiguration.paymentTemplateLogo)) {
paymentRequestParameters.put("LOGO",IngenicoConfiguration.paymentTemplateLogo);
}
}
// parameter for Dynamic Template
if (!empty(useDynamicTemplate) && useDynamicTemplate) {
paymentRequestParameters.put("TP",IngenicoConfiguration.paymentDynamicTemplateURL);
}
var PM = dworder.PaymentMgr.getPaymentMethod(order.getPaymentInstruments()[0].paymentMethod) ;
//get Payment Method from custom attribute ,else get from Payment Instrument
if (!empty(PM.custom.paymentEcommerceCreditCardPM)) {
paymentRequestParameters.put('PM', PM.custom.paymentEcommerceCreditCardPM);
} else {
paymentRequestParameters.put('PM', order.getPaymentInstruments()[0].paymentMethod);
}
paymentRequestParameters.put('BRAND', order.getPaymentInstruments()[0].paymentMethod);
var hashMethod = IngenicoConfiguration.shaMethod;
var digest = new dwcrypto.MessageDigest(hashMethod);
var shaCode = getSHASignParameterFromRequestUtf(paymentRequestParameters,IngenicoConfiguration.shaPasword,digest,orderid);
return shaCode;
}
/**
* generate SHA for MasterPass Ecommerce
* @param {dw.order.Order} order
* @param {String} locale
* @returns {dw.crypto.MessageDigest} shaCode
*/
function generateSHAMasterPassEcommerce(order, locale) {
var paymentRequestParameters = new dwutil.HashMap();
var IngenicoConfiguration = getIngenicoConfiguration();
var cartAmountDec = new dwutil.Decimal(parseFloat(order.totalGrossPrice.value));
cartAmountDec = cartAmountDec.round(2);
cartAmountDec = cartAmountDec.multiply(100);
var cartAmount = cartAmountDec.get().toString();
var cn = order.getBillingAddress().getLastName();
var emailaddress = order.getCustomerEmail();
var currency = order.getCurrencyCode();
//get language from SitePreferences , else get the default one
var lang='';
if (locale=='default') {
lang = 'fr_FR';
} else {
lang = locale + "_" + locale.toUpperCase();
}
var customLanguage = IngenicoConfiguration.language;
if (customLanguage != null) {
lang = customLanguage;
}
var orderid = order.orderNo;
var owneraddress = order.getBillingAddress().getAddress1();
var ownercity = order.getBillingAddress().getCountryCode().value;
var ownertel = order.getBillingAddress().getPhone();
var ownertown = order.getBillingAddress().getCity();
var ownerzip = order.getBillingAddress().getPostalCode();
var pspid = IngenicoConfiguration.PSPID;
paymentRequestParameters.put('AMOUNT', cartAmount);
paymentRequestParameters.put('CN',cn);
paymentRequestParameters.put('CURRENCY',currency);
paymentRequestParameters.put('EMAIL',emailaddress);
paymentRequestParameters.put('LANGUAGE',lang);
paymentRequestParameters.put('ORDERID', orderid);
paymentRequestParameters.put('OWNERADDRESS',owneraddress );
paymentRequestParameters.put('OWNERCTY', ownercity);
paymentRequestParameters.put('OWNERTELNO', ownertel);
paymentRequestParameters.put('OWNERTOWN', ownertown);
paymentRequestParameters.put('OWNERZIP', ownerzip);
paymentRequestParameters.put('PSPID',pspid);
var ecommaccepturl = dwweb.URLUtils.https('MP_ECM-EcommAccept','orderNo', order.orderNo, 'tn' , createShaForUrls(order));
var ecommdeclineurl = dwweb.URLUtils.https('MP_ECM-EcommDecline','orderNo', order.orderNo, 'tn' , createShaForUrls(order));
var ecommdcancel = dwweb.URLUtils.https('MP_ECM-EcommCancel','orderNo', order.orderNo, 'tn', createShaForUrls(order));
var ecommdexeptionurl = dwweb.URLUtils.https('MP_ECM-EcommException','orderNo', order.orderNo, 'tn' , createShaForUrls(order));
paymentRequestParameters.put('ACCEPTURL',ecommaccepturl);
paymentRequestParameters.put('DECLINEURL',ecommdeclineurl);
paymentRequestParameters.put('CANCELURL',ecommdcancel);
paymentRequestParameters.put('EXCEPTIONURL',ecommdexeptionurl);
var useStaticTemplate = IngenicoConfiguration.enableStaticTemplate;
//parameters for Static Template
if (!empty(useStaticTemplate) && useStaticTemplate) {
if (!empty(IngenicoConfiguration.paymentTemplateTitle)) {
paymentRequestParameters.put("TITLE",IngenicoConfiguration.paymentTemplateTitle);
}
if (!empty(IngenicoConfiguration.paymentTemplateBGColor)) {
paymentRequestParameters.put("BGCOLOR",IngenicoConfiguration.paymentTemplateBGColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateTxtColor)) {
paymentRequestParameters.put("TXTCOLOR",IngenicoConfiguration.paymentTemplateTxtColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateTblBGColor)) {
paymentRequestParameters.put("TBLBGCOLOR",IngenicoConfiguration.paymentTemplateTblBGColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateTblTxtColor)) {
paymentRequestParameters.put("TBLTXTCOLOR",IngenicoConfiguration.paymentTemplateTblTxtColor);
}
if(!empty(IngenicoConfiguration.paymentTemplateButtonBGColor)){
paymentRequestParameters.put("BUTTONBGCOLOR",IngenicoConfiguration.paymentTemplateButtonBGColor);
}
if(!empty(IngenicoConfiguration.paymentTemplateButtonTxtColor)){
paymentRequestParameters.put("BUTTONTXTCOLOR",IngenicoConfiguration.paymentTemplateButtonTxtColor);
}
if(!empty(IngenicoConfiguration.paymentTemplateFontType)){
paymentRequestParameters.put("FONTTYPE",IngenicoConfiguration.paymentTemplateFontType);
}
if(!empty(IngenicoConfiguration.paymentTemplateLogo)){
paymentRequestParameters.put("LOGO",IngenicoConfiguration.paymentTemplateLogo);
}
}
var paymentMethodName = order.getPaymentInstruments()[0].paymentMethod;
var paymentMethodNameArray = paymentMethodName.split(' ');
if (paymentMethodNameArray.length > 1 ) {
paymentMethodName = paymentMethodNameArray[0];
}
paymentRequestParameters.put('PM', paymentMethodName);
paymentRequestParameters.put('BRAND', paymentMethodName);
var hashMethod = IngenicoConfiguration.shaMethod;
var digest = new dwcrypto.MessageDigest(hashMethod);
var shaCode = getSHASignParameterFromRequestUtf(paymentRequestParameters, IngenicoConfiguration.shaPasword, digest, orderid);
return shaCode;
}
/**
* generate SHA for Ecommerce Paypal
*
* @param {dw.order.Order} order
* @param {Number} gender
* @param {String} locale
* @returns {dw.crypto.MessageDigest} shaCode
*/
function generateSHAEcommercePaypal(order, gender, locale) {
var paymentRequestParameters = new dwutil.HashMap();
var IngenicoConfiguration = getIngenicoConfiguration();
var cartAmountDec = new dwutil.Decimal(parseFloat(order.totalGrossPrice.value));
cartAmountDec = cartAmountDec.round(2);
cartAmountDec = cartAmountDec.multiply(100);
var cartAmount = cartAmountDec.get().toString();
var civility='';
if (!empty(gender)) {
if (gender==1) {
civility='M';
} else {
civility='F';
}
}
var cn = order.getBillingAddress().getLastName();
var billtofirstname = order.getBillingAddress().getFirstName();
var billtolastname = order.getBillingAddress().getLastName();
var emailaddress = order.getCustomerEmail();
var currency = order.getCurrencyCode();
//get language from SitePreferences , else get the default one
var lang = '';
if (locale == 'default'){
lang = 'fr_FR';
} else {
lang = locale + "_" + locale.toUpperCase();
}
var customLanguage = IngenicoConfiguration.language;
if (customLanguage != null) {
lang = customLanguage;
}
var orderid = order.orderNo;
var owneraddress = order.getBillingAddress().getAddress1();
var ownercity = order.getBillingAddress().getCountryCode().value;
var ownertel = order.getBillingAddress().getPhone();
var ownertown = order.getBillingAddress().getCity();
var ownerzip = order.getBillingAddress().getPostalCode();
var shiptofirstname = order.getDefaultShipment().getShippingAddress().getFirstName();
var shiptolastname = order.getDefaultShipment().getShippingAddress().getLastName();
var owneraddressShip = order.getDefaultShipment().getShippingAddress().getAddress1();
var ownercityShip = order.getDefaultShipment().getShippingAddress().getCountryCode().value;
var ownertownShip = order.getDefaultShipment().getShippingAddress().getCity();
var ownerzipShip = order.getDefaultShipment().getShippingAddress().getPostalCode();
var pspid = IngenicoConfiguration.PSPID;
var ecommaccepturl = dwweb.URLUtils.https('ECM_PPAL-EcommAccept','orderNo',order.orderNo,'pmID',order.getPaymentInstruments()[0].paymentMethod,'tn',createShaForUrls(order));
var ecommdeclineurl = dwweb.URLUtils.https('ECM_PPAL-EcommDecline','orderNo',order.orderNo,'pmID',order.getPaymentInstruments()[0].paymentMethod,'tn',createShaForUrls(order));
var ecommdcancel = dwweb.URLUtils.https('ECM_PPAL-EcommCancel','orderNo',order.orderNo,'pmID',order.getPaymentInstruments()[0].paymentMethod,'tn',createShaForUrls(order));
var useStaticTemplate = IngenicoConfiguration.enableStaticTemplate;
var auth2Steps = IngenicoConfiguration.enableTwoStepsAuthorizationEcommerce;
paymentRequestParameters.put('AMOUNT',cartAmount);
paymentRequestParameters.put("ALIAS",session.custom.alias);
paymentRequestParameters.put("ALIASUSAGE",' ');
if (!empty(gender)) {
paymentRequestParameters.put('CIVILITY', civility);
}
paymentRequestParameters.put('CN',cn);
paymentRequestParameters.put('CURRENCY',currency);
paymentRequestParameters.put('ECOM_BILLTO_POSTAL_NAME_FIRST',billtofirstname);
paymentRequestParameters.put('ECOM_BILLTO_POSTAL_NAME_LAST',billtolastname);
paymentRequestParameters.put('EMAIL',emailaddress);
paymentRequestParameters.put('LANGUAGE',lang);
paymentRequestParameters.put('ORDERID', orderid);
paymentRequestParameters.put('OWNERADDRESS',owneraddress );
paymentRequestParameters.put('OWNERCTY', ownercity);
paymentRequestParameters.put('OWNERTELNO', ownertel);
paymentRequestParameters.put('OWNERTOWN', ownertown);
paymentRequestParameters.put('ORIG', IngenicoConfiguration.transactionTracker);
paymentRequestParameters.put('OWNERZIP', ownerzip);
paymentRequestParameters.put('ECOM_SHIPTO_POSTAL_NAME_FIRST',shiptofirstname);
paymentRequestParameters.put('ECOM_SHIPTO_POSTAL_NAME_LAST',shiptolastname);
paymentRequestParameters.put('ECOM_SHIPTO_POSTAL_STREET_LINE1',owneraddressShip);
paymentRequestParameters.put('ECOM_SHIPTO_POSTAL_CITY',ownertownShip);
paymentRequestParameters.put('ECOM_SHIPTO_POSTAL_POSTALCODE',ownerzipShip);
paymentRequestParameters.put('ECOM_SHIPTO_POSTAL_COUNTRYCODE',ownercityShip);
paymentRequestParameters.put('PSPID',pspid);
paymentRequestParameters.put('ACCEPTURL',ecommaccepturl);
paymentRequestParameters.put('DECLINEURL',ecommdeclineurl);
paymentRequestParameters.put('CANCELURL',ecommdcancel);
paymentRequestParameters.put('COMPLUS',locale);
paymentRequestParameters.put('TXTOKEN',"INIT");
if (!empty(auth2Steps) && auth2Steps) {
paymentRequestParameters.put('OPERATION',"RES");
}else{
paymentRequestParameters.put('OPERATION',"SAL");
}
if (!empty(order.defaultShipment.shippingAddress.stateCode)) {
paymentRequestParameters.put('ECOM_SHIPTO_POSTAL_STATE',order.defaultShipment.shippingAddress.stateCode);
}
//parameters for Static Template
if (!empty(useStaticTemplate) && useStaticTemplate) {
if (!empty(IngenicoConfiguration.paymentTemplateTitle)) {
paymentRequestParameters.put("TITLE",IngenicoConfiguration.paymentTemplateTitle);
}
if (!empty(IngenicoConfiguration.paymentTemplateBGColor)) {
paymentRequestParameters.put("BGCOLOR",IngenicoConfiguration.paymentTemplateBGColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateTxtColor)) {
paymentRequestParameters.put("TXTCOLOR",IngenicoConfiguration.paymentTemplateTxtColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateTblBGColor)) {
paymentRequestParameters.put("TBLBGCOLOR",IngenicoConfiguration.paymentTemplateTblBGColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateTblTxtColor)) {
paymentRequestParameters.put("TBLTXTCOLOR",IngenicoConfiguration.paymentTemplateTblTxtColor);
}
if(!empty(IngenicoConfiguration.paymentTemplateButtonBGColor)){
paymentRequestParameters.put("BUTTONBGCOLOR",IngenicoConfiguration.paymentTemplateButtonBGColor);
}
if(!empty(IngenicoConfiguration.paymentTemplateButtonTxtColor)){
paymentRequestParameters.put("BUTTONTXTCOLOR",IngenicoConfiguration.paymentTemplateButtonTxtColor);
}
if(!empty(IngenicoConfiguration.paymentTemplateFontType)){
paymentRequestParameters.put("FONTTYPE",IngenicoConfiguration.paymentTemplateFontType);
}
if(!empty(IngenicoConfiguration.paymentTemplateLogo)){
paymentRequestParameters.put("LOGO",IngenicoConfiguration.paymentTemplateLogo);
}
}
paymentRequestParameters.put('PM', order.getPaymentInstruments()[0].paymentMethod);
paymentRequestParameters.put('BRAND', order.getPaymentInstruments()[0].paymentMethod);
var hashMethod = IngenicoConfiguration.shaMethod;
var digest = new dwcrypto.MessageDigest(hashMethod);
var shaCode = getSHASignParameterFromRequestUtf(paymentRequestParameters,IngenicoConfiguration.shaPasword,digest,orderid);
return shaCode;
}
/**
* generate SHA for Ecommerce Klarna
* @param {Object} klData
* @returns {dw.crypto.MessageDigest} shaCode
*/
function generateSHAKlarnaEcommerce(klData) {
var paymentRequestParameters = new dwutil.HashMap();
var IngenicoConfiguration = getIngenicoConfiguration();
// Standard Ogone fields
paymentRequestParameters.put('PSPID', IngenicoConfiguration.PSPID);
paymentRequestParameters.put('ORDERID', klData.orderid);
paymentRequestParameters.put('AMOUNT', klData.cartAmount);
paymentRequestParameters.put('CURRENCY', klData.currency);
paymentRequestParameters.put('LANGUAGE', klData.lang);
paymentRequestParameters.put('OPERATION', klData.operation);
paymentRequestParameters.put('PM', klData.paymentMethodName);
paymentRequestParameters.put('BRAND', klData.paymentMethodName);
// Invoicing and delivery data
paymentRequestParameters.put('ECOM_BILLTO_POSTAL_NAME_FIRST', klData.billtofirstname);
paymentRequestParameters.put('ECOM_BILLTO_POSTAL_NAME_LAST', klData.billtolastname);
paymentRequestParameters.put('OWNERADDRESS', klData.owneraddress);
paymentRequestParameters.put('OWNERZIP', klData.ownerzip);
paymentRequestParameters.put('EMAIL', klData.emailaddress);
paymentRequestParameters.put('OWNERCTY', klData.ownercty);
paymentRequestParameters.put('OWNERTOWN', klData.ownertown);
paymentRequestParameters.put('OWNERTELNO', klData.ownertel);
// Additional invoicing and delivery data
if (!empty(klData.cuid)) {
paymentRequestParameters.put('CUID', klData.cuid);
}
if (!empty(klData.civility)) {
paymentRequestParameters.put('ECOM_CONSUMER_GENDER', klData.civility);
}
if (!empty(klData.dateOfBirth)) {
paymentRequestParameters.put('ECOM_SHIPTO_DOB', klData.dateOfBirth);
}
if (!empty(klData.houseNumber)) {
paymentRequestParameters.put('ECOM_BILLTO_POSTAL_STREET_NUMBER', klData.houseNumber);
}
if (!empty(klData.shipmentMeth)) {
paymentRequestParameters.put('ORDERSHIPMETH', klData.shipmentMeth);
}
paymentRequestParameters.put('ORDERSHIPCOST', klData.ordershipcost);
// URLS
paymentRequestParameters.put('ACCEPTURL', klData.ecommaccepturl);
paymentRequestParameters.put('DECLINEURL', klData.ecommdeclineurl);
paymentRequestParameters.put('CANCELURL', klData.ecommdcancelurl);
// OrderItem
var loopstate = 1;
for each (var item in klData.productLineItems) {
paymentRequestParameters.put('ITEMID' + loopstate, item.get('ITEMID' + loopstate));
paymentRequestParameters.put('ITEMNAME' + loopstate, item.get('ITEMNAME' + loopstate));
paymentRequestParameters.put('ITEMPRICE' + loopstate, item.get('ITEMPRICE' + loopstate));
paymentRequestParameters.put('ITEMQUANT' + loopstate, item.get('ITEMQUANT' + loopstate));
paymentRequestParameters.put('ITEMVATCODE' + loopstate,item.get('ITEMVATCODE' + loopstate));
paymentRequestParameters.put('TAXINCLUDED' + loopstate, item.get('TAXINCLUDED' + loopstate));
loopstate++;
}
// Templating data
var useStaticTemplate = IngenicoConfiguration.enableStaticTemplate;
//parameters for Static Template
if (!empty(useStaticTemplate) && useStaticTemplate) {
if (!empty(IngenicoConfiguration.paymentTemplateTitle)) {
paymentRequestParameters.put("TITLE",IngenicoConfiguration.paymentTemplateTitle);
}
if (!empty(IngenicoConfiguration.paymentTemplateBGColor)) {
paymentRequestParameters.put("BGCOLOR",IngenicoConfiguration.paymentTemplateBGColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateTxtColor)) {
paymentRequestParameters.put("TXTCOLOR",IngenicoConfiguration.paymentTemplateTxtColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateTblBGColor)) {
paymentRequestParameters.put("TBLBGCOLOR",IngenicoConfiguration.paymentTemplateTblBGColor);
}
if (!empty(IngenicoConfiguration.paymentTemplateTblTxtColor)) {
paymentRequestParameters.put("TBLTXTCOLOR",IngenicoConfiguration.paymentTemplateTblTxtColor);
}
if(!empty(IngenicoConfiguration.paymentTemplateButtonBGColor)){
paymentRequestParameters.put("BUTTONBGCOLOR",IngenicoConfiguration.paymentTemplateButtonBGColor);
}
if(!empty(IngenicoConfiguration.paymentTemplateButtonTxtColor)){
paymentRequestParameters.put("BUTTONTXTCOLOR",IngenicoConfiguration.paymentTemplateButtonTxtColor);
}
if(!empty(IngenicoConfiguration.paymentTemplateFontType)){
paymentRequestParameters.put("FONTTYPE",IngenicoConfiguration.paymentTemplateFontType);
}
if(!empty(IngenicoConfiguration.paymentTemplateLogo)){
paymentRequestParameters.put("LOGO",IngenicoConfiguration.paymentTemplateLogo);
}
}
var hashMethod = IngenicoConfiguration.shaMethod;
var digest = new dwcrypto.MessageDigest(hashMethod);
var shaPasword = IngenicoConfiguration.shaPasword;
var comparator = function (a, b) {
var aNumber = a.split(/(\d+)/)[1];
var bNumber = b.split(/(\d+)/)[1];
var aString = a.replace(aNumber,'');
var bString = b.replace(bNumber,'');
if(aNumber && bNumber) {
if (aString < bString) {
return -1;
} else if (aString > bString) {
return 1;
} else {
return aNumber - bNumber;
}
} else {
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
}
};
var shaCode = getSHASignParameterFromRequest(paymentRequestParameters, shaPasword, digest, klData.orderid, comparator);
return shaCode;
}
/**
* convert array elements to string
*
* @param {dw.util.ArrayList} arr
* @returns {dw.util.ArrayList} result_arr
*/
function toArrayOfStrings(arr) {
var result_arr = new dwutil.ArrayList();
for( var i=0; i 24534
var cartAmountDec = new dwutil.Decimal(parseFloat(order.totalGrossPrice.value));
cartAmountDec = cartAmountDec.round(2);
cartAmountDec = cartAmountDec.multiply(100);
result.cartAmount = cartAmountDec.get().toString();
// get the language from custom preference
// if not available there then use the locale
var customLanguage = IngenicoConfiguration.language;
if(customLanguage == null) {
if(locale == 'default'){
result.lang='fr_FR';
}
else{
result.lang = locale + "_" + locale.toUpperCase();
}
}else{
result.lang = customLanguage;
}
result.ecommaccepturl = dwweb.URLUtils.https('MP_ECM-EcommAccept','orderNo', order.orderNo, 'tn' , createShaForUrls(order));
result.ecommdeclineurl = dwweb.URLUtils.https('MP_ECM-EcommDecline','orderNo', order.orderNo, 'tn' , createShaForUrls(order));
result.ecommdexeptionurl = dwweb.URLUtils.https('MP_ECM-EcommException','orderNo', order.orderNo, 'tn' , createShaForUrls(order));
result.ecommdcancelurl = dwweb.URLUtils.https('MP_ECM-EcommCancel','orderNo', order.orderNo, 'tn' , createShaForUrls(order));
result.useStaticTemplate = IngenicoConfiguration.enableStaticTemplate;
result.paymentMethodName = "MasterPass";
// TODO: remove this from here and use the same aproach as in Klarna
if (!empty(customer.profile)) {
result.shaCode = generateSHAMasterPassEcommerce(order, locale);
} else {
result.shaCode = generateSHAMasterPassEcommerce(order, locale);
}
return result;
}
/**
* Returns an object containg all the information required for the request to Klarna, like accept and decline url, cart amount, etc
*
* @param {String} paymentMethod
* @param {dw.order.Order} order
* @param {dw.customer.Customer} customer
* @param {String} locale
* @param {Boolean} useAlias
* @returns {Object} result
*/
function KlarnaEcommerceData(paymentMethod, order, customer, locale, useAlias) {
var result = {};
var IngenicoConfiguration = getIngenicoConfiguration();
result.formAction = IngenicoConfiguration.EcommerceEndpointISO;
result.operation = 'RES';
// get the language from custom preference
// if not available there then use the locale
var customLanguage = IngenicoConfiguration.language;
if(customLanguage == null) {
if(locale == 'default'){
result.lang='en_US';
}
else{
result.lang = locale + "_" + locale.toUpperCase();
}
}else{
result.lang = customLanguage;
}
if (paymentMethod == 'Installment') {
result.ecommaccepturl = dwweb.URLUtils.https('KL_IN_ECM-EcommAccept','orderNo', order.orderNo, 'tn' , createShaForUrls(order));
result.ecommdeclineurl = dwweb.URLUtils.https('KL_IN_ECM-EcommDecline','orderNo', order.orderNo, 'tn' , createShaForUrls(order));
result.ecommdcancelurl = dwweb.URLUtils.https('KL_IN_ECM-EcommCancel','orderNo', order.orderNo, 'tn' , createShaForUrls(order));
} else {
result.ecommaccepturl = dwweb.URLUtils.https('KL_ECM-EcommAccept','orderNo', order.orderNo, 'tn' , createShaForUrls(order));
result.ecommdeclineurl = dwweb.URLUtils.https('KL_ECM-EcommDecline','orderNo', order.orderNo, 'tn' , createShaForUrls(order));
result.ecommdcancelurl = dwweb.URLUtils.https('KL_ECM-EcommCancel','orderNo', order.orderNo, 'tn' , createShaForUrls(order));
}
if (order.getBillingAddress().custom.gender == 1) {
result.civility = 'M';
} else {
result.civility = 'F';
}
result.billtofirstname = order.getBillingAddress().getFirstName();
result.billtolastname = order.getBillingAddress().getLastName();
result.emailaddress = order.getCustomerEmail();
result.orderid = order.orderNo;
result.currency = order.getCurrencyCode();
result.owneraddress = order.getBillingAddress().getAddress1();
result.ownercty = order.getBillingAddress().getCountryCode().value.toString().toUpperCase();
result.ownertel = order.getBillingAddress().getPhone();
result.ownertown = order.getBillingAddress().getCity();
result.ownerzip = order.getBillingAddress().getPostalCode();
result.paymentMethodName = paymentMethod+ " " + result.ownercty;
var ordershipcost = new dwutil.Decimal(parseFloat(order.getAdjustedShippingTotalGrossPrice().value));
ordershipcost = ordershipcost.round(2);
ordershipcost = ordershipcost.multiply(100);
result.ordershipcost = ordershipcost.get().toString();
var shipmentMeth = null;
var shipments = order.shipments;
if(!empty(shipments) && shipments.length>0 && !empty(shipments[0].shippingMethod)) {
shipmentMeth = shipments[0].shippingMethod.displayName;
}
result.shipmentMeth = shipmentMeth;
var dob = order.getBillingAddress().custom.dateOfBirth;
if(!empty(dob)) {
var monthOfBirth = "0" + (dob.getMonth() + 1);
var dayOfBirth = "0" + dob.getDate();
result.dateOfBirth = dayOfBirth.slice(-2) + '/' + monthOfBirth.slice(-2) + '/' + dob.getFullYear();
} else {
result.dateOfBirth = null;
}
result.cuid = order.getBillingAddress().custom.cuid;
result.houseNumber = order.getBillingAddress().custom.houseNumber;
var productLineItems = order.getAllProductLineItems();
var giftCertificateLineItems = order.getGiftCertificateLineItems();
result.productLineItems = new dwutil.ArrayList();
var loopstate = 1;
var itemsAmout = 0;
for each (var item in productLineItems) {
if (empty(item.getProductID())) {
continue;
}
var productItem = new dwutil.HashMap();
productItem.put('ITEMID' + loopstate, item.getProductID().substring(0,15));
productItem.put('ITEMNAME' + loopstate, item.getProductName().substring(0,35) + ","+item.getQuantity().getValue().toString());
productItem.put('ITEMPRICE' + loopstate, item.getAdjustedGrossPrice().value.toFixed(2).toString());
productItem.put('ITEMQUANT' + loopstate, "1");
productItem.put('ITEMVATCODE' + loopstate, item.getTaxRate()*100 + '%');
productItem.put('TAXINCLUDED' + loopstate, "1");
result.productLineItems.add1(productItem);
//calculate product items cost, according to calculated price
itemsAmout = itemsAmout + item.getAdjustedGrossPrice().value;
loopstate++;
}
for each (var item in giftCertificateLineItems) {
var productItem = new dwutil.HashMap();
productItem.put('ITEMID' + loopstate, item.lineItemText.substring(0,15));
productItem.put('ITEMNAME' + loopstate, (item.lineItemText + item.price.toString()).substring(0,40));
productItem.put('ITEMPRICE' + loopstate, item.grossPrice.value.toFixed(2).toString());
productItem.put('ITEMQUANT' + loopstate, "1");
productItem.put('ITEMVATCODE' + loopstate, item.getTaxRate()*100 + '%');
productItem.put('TAXINCLUDED' + loopstate, "1");
result.productLineItems.add1(productItem);
//calculate product items cost, according to calculated price
itemsAmout = itemsAmout + item.grossPrice.value;
loopstate++;
}
// Set order discount line items
itemsAmout = addPriceAdjustments(order.getPriceAdjustments(), loopstate, order.orderNo, result, itemsAmout);
var itemsAmoutDec = new dwutil.Decimal(parseFloat(itemsAmout));
itemsAmoutDec = itemsAmoutDec.round(2);
itemsAmoutDec = itemsAmoutDec.multiply(100);
itemsAmoutDec = itemsAmoutDec.add(ordershipcost);
//var itemsAmoutDec = new Decimal(parseFloat(itemsAmout * 100 + ordershipcost)).round(2);
result.cartAmount = itemsAmoutDec.get().toString();
result.shaCode = generateSHAKlarnaEcommerce(result);
return result;
}
/**
* add Price adjustments to Klarna object
*
* @param {dw.util.Collection} adjustments Collection of adjustment objects
* @param {Number} loopstate Next item index
* @param {String} oid String with the option product ID associated with the discount
* @param {Object} result Object with Klarna data
* @param {Number} itemsAmout calculated product items cost
*/
function addPriceAdjustments (adjustments, loopstate, oid, result, itemsAmout) {
if (!empty(adjustments) && adjustments.length > 0) {
for each (var adjustment in adjustments) {
var adjustment_unit_price = (adjustment.grossPrice.available ? adjustment.grossPrice.value : adjustment.netPrice.value);
var adjustment_vat_code = parseInt(adjustment.taxRate*100) + "%";
var promoName = !empty(adjustment.promotion) && !empty(adjustment.promotion.name) ? adjustment.promotion.name : "discount";
var promoId = adjustment.promotionID;
// Include option ID with promotion ID if available
if (!empty(oid)) {
promoId = promoId + "_" + oid;
}
var productItem = new dwutil.HashMap();
productItem.put('ITEMID' + loopstate, promoId.substring(0,15));
productItem.put('ITEMNAME' + loopstate, promoName);
productItem.put('ITEMPRICE' + loopstate, adjustment_unit_price.toFixed(2).toString());
productItem.put('ITEMQUANT' + loopstate, "1");
productItem.put('ITEMVATCODE' + loopstate, adjustment_vat_code);
productItem.put('TAXINCLUDED' + loopstate, "1");
result.productLineItems.add1(productItem);
//calculate product items cost, according to calculated price
itemsAmout = itemsAmout + adjustment_unit_price;
loopstate++;
}
}
return itemsAmout;
}
/**
* Creates the SHA token used to verify the authenticity of the request in the return urls.
* This token is calculated and added to the return urls and then it is read and compared with a different token calculated internally from the same parameters.
* Because Ingenico has a limitation of max 200 characters in the return urls, we take only the first 10 digits from the sha token
* (also for this reason, the pipeline names and payment method names were shortened)
*
* @param {dw.order.Order} order
* @returns {String} shaCode
*/
function createShaForUrls(order) {
var IngenicoConfiguration = getIngenicoConfiguration();
if (empty(order)) {
throw Error("No Order created");
}
// Add parameter alphabetical sorted for sha sign
var queryMap = new dwutil.HashMap();
queryMap.put("POSTAL", order.getBillingAddress().getPostalCode());
queryMap.put("PHONE", order.getBillingAddress().getPhone());
queryMap.put("EMAIL", order.getCustomerEmail());
var hashMethod = IngenicoConfiguration.shaMethod;
var shaPasword = IngenicoConfiguration.shaPasword;
var digest = new dwcrypto.MessageDigest(hashMethod);
var shaCode = getSHASignParameterFromRequest(queryMap, shaPasword, digest, order.orderNo);
return shaCode.substring(0,10);
}
/**
* Get the configuration information from Ingenico custom object
* @returns {Object} IngenicoConfiguration
*/
function getIngenicoConfiguration(){
var co = dwobject.CustomObjectMgr.getCustomObject('IngenicoConfiguration','IngenicoConfiguration');
var IngenicoConfiguration = {};
/*
* transactionTracker will be updated with every change to the cartridge (release)
* by the cartridge developer
* format is IGDW folowed by the date in the format YYMMDD
*/
IngenicoConfiguration['transactionTracker'] = 'IGDW161123';
IngenicoConfiguration['enableIngenico'] = !!co.custom.enableIngenico.getValue();
IngenicoConfiguration['PSPID'] = co.custom.PSPID;
IngenicoConfiguration['apiUserID'] = co.custom.apiUserID;
IngenicoConfiguration['apiUserPassword'] = co.custom.apiUserPassword;
IngenicoConfiguration['shaMethod'] = co.custom.shaMethod.getValue();
IngenicoConfiguration['shaPasword'] = co.custom.shaPasword;
IngenicoConfiguration['shaOutPassword'] = co.custom.shaOutPassword;
IngenicoConfiguration['paymentCartridgeTimeout'] = co.custom.paymentCartridgeTimeout;
IngenicoConfiguration['MaintainanceEndpoint'] = co.custom.MaintainanceEndpoint.getValue();
IngenicoConfiguration['NewOrderEndpoint'] = co.custom.NewOrderEndpoint.getValue();
IngenicoConfiguration['DirectQueryEndpoint'] = co.custom.DirectQueryEndpoint.getValue();
IngenicoConfiguration['EcommerceEndpoint'] = co.custom.EcommerceEndpoint.getValue();
IngenicoConfiguration['EcommerceEndpointISO'] = co.custom.EcommerceEndpointISO.getValue();
IngenicoConfiguration['HostedTokenizationPageEndpoint'] = co.custom.HostedTokenizationPageEndpoint.getValue();
IngenicoConfiguration['enable3ds'] = !!co.custom.enable3ds.getValue();
IngenicoConfiguration['creditCardType'] = co.custom.creditCardType;
IngenicoConfiguration['enableNewSEPAVersion'] = !!co.custom.enableNewSEPAVersion.getValue();
IngenicoConfiguration['HostedTokenizationAllowSaveAlias'] = !!co.custom.HostedTokenizationAllowSaveAlias.getValue();
IngenicoConfiguration['enableFraudDetection'] = !!co.custom.enableFraudDetection.getValue();
IngenicoConfiguration['enableTwoStepsAuthorizationDirectLink'] = !!co.custom.enableTwoStepsAuthorizationDirectLink.getValue();
IngenicoConfiguration['enableTwoStepsAuthorizationEcommerce'] = !!co.custom.enableTwoStepsAuthorizationEcommerce.getValue();
IngenicoConfiguration['refundPaymentMethodsDirectLink'] = co.custom.refundPaymentMethodsDirectLink;
IngenicoConfiguration['refundPaymentMethodsEcommerce'] = co.custom.refundPaymentMethodsEcommerce;
IngenicoConfiguration['maxCaptureAttempts'] = co.custom.maxCaptureAttempts;
IngenicoConfiguration['daysForCapture'] = co.custom.daysForCapture;
IngenicoConfiguration['language'] = co.custom.language.getValue();
IngenicoConfiguration['enableDynamicTemplate'] = co.custom.enableDynamicTemplate.getValue();
IngenicoConfiguration['paymentDynamicTemplateURL'] = co.custom.paymentDynamicTemplateURL;
IngenicoConfiguration['enableStaticTemplate'] = co.custom.enableStaticTemplate.getValue();
IngenicoConfiguration['paymentTemplateBGColor'] = co.custom.paymentTemplateBGColor;
IngenicoConfiguration['paymentTemplateButtonTxtColor'] = co.custom.paymentTemplateButtonTxtColor;
IngenicoConfiguration['paymentTemplateTitle'] = co.custom.paymentTemplateTitle;
IngenicoConfiguration['paymentTemplateFontType'] = co.custom.paymentTemplateFontType;
IngenicoConfiguration['paymentTemplateTblBGColor'] = co.custom.paymentTemplateTblBGColor;
IngenicoConfiguration['paymentTemplateTblTxtColor'] = co.custom.paymentTemplateTblTxtColor;
IngenicoConfiguration['paymentTemplateLogo'] = co.custom.paymentTemplateLogo;
IngenicoConfiguration['paymentTemplateTxtColor'] = co.custom.paymentTemplateTxtColor;
IngenicoConfiguration['paymentTemplateButtonBGColor'] = co.custom.paymentTemplateButtonBGColor;
return IngenicoConfiguration;
}
/**
* Get Payment Processor for Payment Method
* @param {String} paymentMethodID
* @returns {String}
*/
function checkEcommercePaymentMethods(paymentMethodID) {
var paymentMethod = dworder.PaymentMgr.getPaymentMethod(paymentMethodID) ;
var paymentProcessor = paymentMethod.getPaymentProcessor() ;
return paymentProcessor.ID ;
}
/**
* Decline order call
* @param {dw.order.Order} Order
*/
function ecommDecline(Order) {
var service = dwsvc.ServiceRegistry.get('Ingenico.ecommDecline');
var url = dwweb.URLUtils.https('PAYMENT_ECOMMERCE-MarkOrdersFailed','orderNo',Order.orderNo,'pc',Order.getBillingAddress().getPostalCode(),'pn',Order.getBillingAddress().getPhone(),'ce',Order.getCustomerEmail());
var callPrams = {
"url" : requestUrl
}
service.call(callPrams).object;
}
/**
* Creates a payment instrument specific for the given payment type (payment method)
* for the given basket. If any error occurs the pipelet returns PIPELET_ERROR with
* no payment instrument being created. If the creation succeeded the script returns
* the newly created payment instrument.
*
* If only one payment instrument is allowed, any existing payment instrument may be
* removed by using the RemoveExisting input parameter and passing a Boolean true.
*
* @param {dw.order.LineItemCtnr} lineItemCtnr
* @param {String} paymentType
* @returns {dw.order.PaymentInstrument}
*/
function EcommerceCreatePaymentInstrument(lineItemCtnr, paymentType){
// remove existing payment instruments from the basket
lineItemCtnr.removeAllPaymentInstruments() ;
// calculate the amount to be reflected by this payment instrument
var amount = calculateNonGiftCertificateAmount(lineItemCtnr);
// create a payment instrument
var paymentInstr = lineItemCtnr.createPaymentInstrument(paymentType, amount);
if(session.forms.billing.paymentMethods.saveAlias.value){
session.custom.saveAlias = true;
} else {
session.custom.saveAlias = false;
}
if(!empty(request.httpParameterMap.savedAliases.stringValue)){
session.custom.alias = request.httpParameterMap.savedAliases.stringValue;
} else {
session.custom.alias = dwutil.UUIDUtils.createUUID().toUpperCase();
}
session.custom.paymentMethode = 'PAYPAL';
return paymentInstr;
}
/**
* Verify status for Order
*
* @param {dw.order.Order} order
* @returns {String} status
*/
function EcommerceVerifyStatus(order) {
var log = dwsystem.Logger.getLogger("payment");
var resultObj = null;
var status = '';
var start = new Date();
if (empty(order)) {
log.error('EcommerceVerifyStatus function in libPayment.ds: Missing required input parameter(s) Order.');
return '';
}
var paymentInstruments = order.getPaymentInstruments();
if (!paymentInstruments.empty) {
var paymentInstrument = paymentInstruments[0];
if (!empty(paymentInstrument)) {
var brand = paymentInstrument.getPaymentMethod();
}
}
try {
var paymentCtnr = new PaymentCtnr(order, order.orderNo, null, null, null, null);
resultObj = paymentCtnr.sendDirectQuery();
} catch (error) {
var end = new Date();
var diff = (end.getTime() - start.getTime()) * 0.001;
if(error.status == "0" ){
log.error("EcommerceVerifyStatus function in libPayment.ds: Payment Direct Link Authorization Request invalid or incomplete; OrderNo: {1}", order.orderNo);
} else if ( error.status == "2" ) {
log.error("EcommerceVerifyStatus function in libPayment.ds: Payment Direct Link Authorization Request Authorisation refused; OrderNo: {1}", order.orderNo);
} else if ( error.status == "51" ) {
log.error("EcommerceVerifyStatus function in libPayment.ds: Payment Direct Link Authorisation Request Authorisation waiting; OrderNo: {1}", order.orderNo);
} else if ( error.status == "52" ) {
log.error("EcommerceVerifyStatus function in libPayment.ds: Payment Direct Link Authorisation Request Authorisation not known; OrderNo: {1}", order.orderNo);
}
return '';
}
if (!empty(resultObj)) {
status = resultObj.hasOwnProperty("status") ? resultObj.status : status;
}
if(status == "95" || status == "9"){
order.setPaymentStatus(dworder.Order.PAYMENT_STATUS_PAID);
paymentInstrument.paymentTransaction.custom.paymentStatus = status;
paymentInstrument.paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentInstrument.paymentTransaction.custom.paymentStatus);
}
return status;
}
/**
* Get Hosted Tokenization URL
*
* @returns {String} url
*/
function GetHostedTokenizationURL() {
var IngenicoConfiguration = getIngenicoConfiguration();
var callURL = IngenicoConfiguration.HostedTokenizationPageEndpoint;
var pspid = IngenicoConfiguration.PSPID;
var shaIn = IngenicoConfiguration.shaPasword;
var hashMethod = IngenicoConfiguration.shaMethod;
var digest = new dwcrypto.MessageDigest(hashMethod);
var requestParameters = new dwutil.HashMap();
var sortedRequestParameters = new dwutil.SortedMap();
var hashString = '';
var url = '';
var httpParameterMap = request.httpParameterMap;
var locale = request.locale;
session.custom.hostedTokenizationSucces = false;
if(httpParameterMap.failed.booleanValue){
var paymentMethode = session.custom.paymentMethode;
var saveAlias = session.custom.saveAlias;
var useAlias = session.custom.alias;
} else {
var paymentMethode = httpParameterMap.paymentMethode.value;
var saveAlias = httpParameterMap.saveAlias.booleanValue;
var useAlias = httpParameterMap.useAlias.value;
}
requestParameters.put('Account.PSPID', pspid);
if(!empty(paymentMethode) && paymentMethode == 'CreditCard'){
requestParameters.put('Card.PaymentMethod','CreditCard');
session.custom.paymentMethode = 'CreditCard';
} else if (!empty(paymentMethode)){
requestParameters.put('Card.Brand', paymentMethode.replace(/_/g,''));
session.custom.paymentMethode = paymentMethode;
} else {
session.custom.hostedTokenizationSucces = true;
return '';
}
session.custom.paymentMethode = paymentMethode;
if(!empty(locale) && locale !='default'){
requestParameters.put('Layout.Language', locale);
}
if(saveAlias){
session.custom.saveAlias = true;
requestParameters.put('Alias.StorePermanently', 'Y');
} else {
session.custom.saveAlias = false;
requestParameters.put('Alias.StorePermanently', 'N');
}
if(!empty(useAlias)){
session.custom.alias = useAlias;
requestParameters.put('Alias.AliasId',useAlias);
} else {
var alias = dwutil.UUIDUtils.createUUID().toUpperCase();
session.custom.alias = alias;
requestParameters.put('Alias.AliasId',alias);
}
requestParameters.put('Parameters.AcceptUrl', dwweb.URLUtils.https('Ingenico-HostedTokenizationPage').toString());
requestParameters.put('Parameters.ExceptionUrl', dwweb.URLUtils.https('Ingenico-HostedTokenizationPage', 'failed', 'true').toString());
sortedRequestParameters.putAll(requestParameters);
var paramKeySet : Set = sortedRequestParameters.keySet();
var paramIterator : Iterator = paramKeySet.iterator();
var paramValue = '';
var paramName : String = '';
url += callURL + "?";
while ( paramIterator.hasNext() ) {
paramName = paramIterator.next().toString();
paramValue = sortedRequestParameters.get(paramName);
if (!empty(paramValue)) {
hashString += paramName.toUpperCase() + '=' + paramValue.toString() + shaIn;
url += paramName + '=' + paramValue.toString() + '&';
}
}
if(!empty(shaIn) && !empty(hashString)){
url += 'ShaSignature.ShaSign=' + digest.digest(hashString);
} else {
url = url.substring(0,url.lastIndexOf('&'));
}
return url;
}
/**
* Sends Payment Direct Link Authorization.
* @param {dw.order.Order} order
* @param {String} locale
* @param {String} payMethID
* @returns {object} ret
* @returns {String} ret.Status
* @returns {String} ret.PaymentMethodID
* @returns {String} ret.ErrorStatus
* @returns {String} ret.PaymentStatus
* @returns {String} ret.ResultStatusCheck
* @returns {Boolean} ret.success
*/
function GetPaymentDirectLinkOrderData(order, locale, payMethID) {
var log = dwsystem.Logger.getLogger("payment");
var ret = {
'Status' : null,
'PaymentMethodID' : null,
'ErrorStatus' : null,
'PaymentStatus' : null,
'ResultStatusCheck' : null,
'success' : false
}
if (empty(order)) {
log.error('GetPaymentDirectLinkOrderData function in libPayment.ds: Missing required input parameter(s) Order.');
return ret;
}
var resultObj = null;
var status = "";
var PaymentMethod = "";
var brand = payMethID;
var payID = "";
var start = new Date();
var paymentInstruments = order.getPaymentInstruments();
var amount = calculateNonGiftCertificateAmount(order);
if( paymentInstruments == null || paymentInstruments.isEmpty() ) {
var paymentInstr = order.createPaymentInstrument(payMethID, amount);
} else {
var paymentInstr = paymentInstruments[0];
}
var paymentprocc = dworder.PaymentMgr.getPaymentMethod(payMethID).getPaymentProcessor();
paymentInstr.paymentTransaction.setPaymentProcessor(paymentprocc);
try {
var paymentCtnr = new PaymentCtnr(order, order.orderNo, null, null, null, locale);
status = paymentCtnr.getStatus();
resultObj = paymentCtnr.sendDirectQuery();
} catch (error) {
dwsystem.Logger.error(error.toString());
var end = new Date();
var diff = (end.getTime() - start.getTime()) * 0.001;
paymentInstr.paymentTransaction.custom.paymentStatus = error.status;
paymentInstr.paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentInstr.paymentTransaction.custom.paymentStatus);
ret.ResultStatusCheck = paymentCtnr.checkStatus(status, error.ErrorCode);
ret.ErrorStatus=error.status.toString();
return ret;
}
if (!empty(resultObj)) {
status = resultObj.hasOwnProperty("status") ? resultObj.status : status;
PaymentMethod = resultObj.hasOwnProperty("pm") ? resultObj.pm : '';
payID = resultObj.hasOwnProperty("payID") ? resultObj.payID : '';
brand = resultObj.hasOwnProperty("brand") ? resultObj.brand : '';
order.custom.payment_PAYID = payID;
if (!empty(brand)) {
PaymentMethod += " - " + brand;
}
// set used payment method to ensure used payment method ID could be returned
if (!empty(PaymentMethod)) paymentCtnr.setPaymentMethod(PaymentMethod);
}
ret.Status = status;
ret.PaymentMethodID = paymentCtnr.getPaymentMethodId();
paymentInstr.paymentTransaction.setTransactionID(payID.toString());
paymentInstr.paymentTransaction.custom.paymentStatus=status;
paymentInstr.paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentInstr.paymentTransaction.custom.paymentStatus);
paymentInstr.custom.paymentMethod=PaymentMethod;
// check payment status
ret.ResultStatusCheck = paymentCtnr.checkStatus(status, 0);
ret.ErrorStatus = status;
if (status == "41") {
order.custom.payment_pending = true;
} else if (status == "9") {
order.custom.payment_needCapture = false;
order.custom.payment_authorizationStatus = 'REQUESTED';
paymentInstr.paymentTransaction.custom.paymentStatus = status;
paymentInstr.paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentInstr.paymentTransaction.custom.paymentStatus);
order.setPaymentStatus(dworder.Order.PAYMENT_STATUS_PAID);
}
ret.PaymentStatus = status ;
if(!(ret.ResultStatusCheck == "FAIL")) {
ret.success = true;
}
return ret;
}
/**
* Sends Payment Ecommerce Authorization.
*
* @param {dw.order.Order} order
* @param {String} locale
* @param {String} payMethID
* @returns {object} ret
* @returns {String} ret.Status
* @returns {String} ret.PaymentMethodID
* @returns {String} ret.ErrorStatus
* @returns {String} ret.PaymentStatus
* @returns {String} ret.ResultStatusCheck
* @returns {Boolean} ret.success
*/
function GetPaymentEcommOrderData(order, locale, payMethID) {
var log = dwsystem.Logger.getLogger("payment");
var ret = {
'Status' : null,
'PaymentMethodID' : null,
'ErrorStatus' : null,
'PaymentStatus' : null,
'ResultStatusCheck' : null,
'success' : false
}
var IngenicoConfiguration = getIngenicoConfiguration();
if (empty(order)) {
log.error('GetPaymentEcommOrderData function in libPayment.ds: Missing required input parameter(s) Order.');
return ret;
}
var resultObj = null;
var status = "";
var PaymentMethod = "";
var brand = payMethID;
var payID = "";
var ip = "";
var start = new Date();
try {
var paymentCtnr = new PaymentCtnr(order, order.orderNo, null, null, null, locale);
status = paymentCtnr.getStatus();
resultObj = paymentCtnr.sendDirectQuery();
}
catch (error) {
var x = error;
var end = new Date();
var diff = (end.getTime() - start.getTime()) * 0.001;
ret.ResultStatusCheck = paymentCtnr.checkStatus(error.status, error.ErrorCode);
ret.ErrorStatus=error.status.toString();
return ret;
}
var useFraudDetection = IngenicoConfiguration.enableFraudDetection;
if (!empty(resultObj)) {
status = resultObj.hasOwnProperty("status") ? resultObj.status : status;
PaymentMethod = resultObj.hasOwnProperty("pm") ? resultObj.pm : '';
payID = resultObj.hasOwnProperty("payid") ? resultObj.payid : '';
brand = resultObj.hasOwnProperty("brand") ? resultObj.brand : '';
if (!empty(useFraudDetection) && useFraudDetection) {
order.custom.payment_ip = resultObj.hasOwnProperty("ip") ? resultObj.ip : '';
order.custom.payment_aavCheck = resultObj.hasOwnProperty("aavcheck") ? resultObj.aavcheck : '';
order.custom.payment_cvcCheck = resultObj.hasOwnProperty("cvccheck") ? resultObj.cvccheck : '';
order.custom.payment_scoring = resultObj.hasOwnProperty("scoring") ? resultObj.scoring : '';
order.custom.payment_scoCategory = resultObj.hasOwnProperty("sco_category") ? resultObj.sco_category : '';
}
order.custom.payment_PAYID = payID;
if(!empty(brand)){
PaymentMethod+=" - "+brand;
}
// set used payment method to ensure used payment method ID could be returned
if (!empty(PaymentMethod)) paymentCtnr.setPaymentMethod(PaymentMethod);
}
//set paymentinstrument data
var ECOMM_PAYMENT = payMethID;
if( order == null){
return ret;
}
ret.Status = status;
ret.PaymentMethodID = paymentCtnr.getPaymentMethodId();
var paymentInstruments = order.getPaymentInstruments();
var amount = calculateNonGiftCertificateAmount(order);
if(paymentInstruments == null || paymentInstruments.isEmpty()) {
var paymentInstr = order.createPaymentInstrument(payMethID, amount);
}
else{
var paymentInstr = paymentInstruments[0];
}
var paymentprocc = dworder.PaymentMgr.getPaymentMethod(ret.PaymentMethodID).getPaymentProcessor();
paymentInstr.getPaymentTransaction().setPaymentProcessor(paymentprocc);
paymentInstr.getPaymentTransaction().setTransactionID(payID.toString());
paymentInstr.paymentTransaction.custom.paymentStatus = status;
paymentInstr.paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentInstr.paymentTransaction.custom.paymentStatus);
paymentInstr.custom.paymentMethod=PaymentMethod;
if (status == "5") {
// Update the order for background step 2 reservation request
order.custom.payment_isAuthorized = true;
order.custom.payment_needCapture = true;
order.custom.payment_captureAttempts = 0;
order.custom.payment_authorizationStatus = 'AUTHORISED';
order.custom.payment_data = JSON.stringify({
paymentMethodID: ret.PaymentMethodID,
locale: locale
});
}else{
order.custom.payment_isAuthorized = false;
order.custom.payment_needCapture = false;
order.custom.payment_captureAttempts = 0;
//# Result Status Check - possible values: FAIL, RETRY, SUCCESS
ret.ResultStatusCheck = paymentCtnr.checkStatus(status, 0);
if(ret.ResultStatusCheck == "FAIL") {
return ret;
}
if(status != "9" && status != "41"){
ret.ErrorStatus = status;
}else{
if(status == "41"){
order.custom.payment_pending = true ;
}
}
}
ret.PaymentStatus = status;
ret.success = true;
return ret;
}
/**
* Sends PayPal Ecommerce Informations.
*
* @param {dw.order.Order} order
* @param {String} locale
* @param {dw.web.HttpParameterMap} paramMap
* @returns {object} ret
* @returns {String} ret.ErrorStatus
* @returns {Boolean} ret.success
*/
function SendPayPalInfo(order, locale, paramMap) {
var log = dwsystem.Logger.getLogger("payment");
var IngenicoConfiguration = getIngenicoConfiguration();
var ret = {
'ErrorStatus' : null,
'success' : false
}
var paymentCtnr = null;
if (empty(order)) {
log.error('SendPayPalInfo function in libPayment.ds: Missing required input parameter(s) Order.');
return ret;
}
var paymentInstruments = order.getPaymentInstruments();
var amount = calculateNonGiftCertificateAmount(order);
if( paymentInstruments == null || paymentInstruments.isEmpty() ) {
var paymentInstr = order.createPaymentInstrument("PAYPAL", amount);
}
else{
var paymentInstr = paymentInstruments[0];
}
var paymentprocc = dworder.PaymentMgr.getPaymentMethod("PAYPAL").getPaymentProcessor();
paymentInstr.getPaymentTransaction().setPaymentProcessor(paymentprocc);
paymentInstr.custom.paypalToken = paramMap.TXTOKEN.value;
paymentInstr.custom.paypalPayerID = paramMap.PAYID.value;
paymentInstr.custom.paypalpayeremail = paramMap.PayerEmail.value;
var start = new Date();
try {
paymentCtnr = new PaymentCtnr(order, order.orderNo, null, "PAYPAL", null , locale);
var status = paymentCtnr.getStatus();
resultObj = paymentCtnr.sendDirectLinkPayPal();
}
catch (error) {
var end = new Date();
var diff = (end.getTime() - start.getTime()) * 0.001;
ret.ErrorStatus = error.status.toString();
if(error.status == "0" ){
log.error("SendPayPalInfo function in libPayment.ds: PayPal Authorization Request invalid or incomplete; OrderNo: {1}", order.orderNo);
} else if ( error.status == "2" ) {
log.error("SendPayPalInfo function in libPayment.ds: PayPal Authorization Request Authorisation refused; OrderNo: {1}", order.orderNo);
} else if ( error.status == "52" ) {
log.error("SendPayPalInfo function in libPayment.ds: PayPal Authorisation Request Authorisation not known; OrderNo: {1}", order.orderNo);
}
return ret;
}
var useFraudDetection = IngenicoConfiguration.enableFraudDetection;
if ( !empty(resultObj) ) {
status = resultObj.hasOwnProperty("status") ? resultObj.status : status;
PaymentMethod = resultObj.hasOwnProperty("pm") ? resultObj.pm : '';
payID = resultObj.hasOwnProperty("payid") ? resultObj.payid : '';
brand = resultObj.hasOwnProperty("brand") ? resultObj.brand : '';
html = resultObj.hasOwnProperty("html") ? resultObj.html : '';
if (!empty(useFraudDetection) && useFraudDetection) {
order.custom.payment_ip = resultObj.hasOwnProperty("ip") ? resultObj.ip : '';
order.custom.payment_aavCheck = resultObj.hasOwnProperty("aavcheck") ? resultObj.aavcheck : '';
order.custom.payment_cvcCheck = resultObj.hasOwnProperty("cvccheck") ? resultObj.cvccheck : '';
order.custom.payment_scoring = resultObj.hasOwnProperty("scoring") ? resultObj.scoring : '';
order.custom.payment_scoCategory = resultObj.hasOwnProperty("sco_category") ? resultObj.sco_category : '';
}
if(!empty(brand)){
PaymentMethod+=" - "+brand;
}
// set used payment method to ensure used payment method ID could be returned
if (!empty(PaymentMethod)) paymentCtnr.setPaymentMethod(PaymentMethod);
}
order.custom.payment_PAYID = payID;
paymentInstr.getPaymentTransaction().setTransactionID(payID.toString());
paymentInstr.paymentTransaction.custom.paymentStatus = status;
paymentInstr.paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentInstr.paymentTransaction.custom.paymentStatus);
paymentInstr.custom.paymentMethod = PaymentMethod;
var paymentInstrument : OrderPaymentInstrument = order.getPaymentInstruments()[0];
var paymentMethodID = paymentInstrument.getPaymentMethod();
if (status == "5") {
// Update the order for background step 2 reservation request
order.custom.payment_isAuthorized = true;
order.custom.payment_needCapture = true;
order.custom.payment_captureAttempts = 0;
order.custom.payment_authorizationStatus = 'AUTHORISED';
order.custom.payment_data = JSON.stringify({
paymentMethodID: paymentMethodID,
locale: locale
});
}else{
order.custom.payment_isAuthorized = false;
order.custom.payment_needCapture = false;
order.custom.payment_captureAttempts = 0;
if(status != "9"){
ret.ErrorStatus = status.toString();
if(status == "0" ){
// quickfix paypal status 0
order.custom.payment_authorizationStatus = 'NO_AUTHORISED';
order.custom.payment_data = JSON.stringify({
paymentMethodID: paymentMethodID,
locale: locale
});
ret.success = true;
return ret;
/* temporarily disabled error on status 0
log.error("SendPayPalInfo function in libPayment.ds: PayPal Authorization Request invalid or incomplete; OrderNo: {1}", order.orderNo);
return ret;
*/
} else if ( status == "46" ) {
log.error("SendPayPalInfo function in libPayment.ds: PayPal Authorization Request returned with enrolled and empty HTML. Status: {0}; OrderNo: {1}", status, order.orderNo);
return ret;
} else if ( status == "2" ) {
log.error("SendPayPalInfo function in libPayment.ds: PayPal Authorization Request Authorisation refused; OrderNo: {1}", order.orderNo);
return ret;
} else if ( status == "52" ) {
log.error("SendPayPalInfo function in libPayment.ds: PayPal Authorisation Request Authorisation not known; OrderNo: {1}", order.orderNo);
return ret;
} else if ( status == "51" ) {
log.error("SendPayPalInfo function in libPayment.ds: PayPal Authorisation Request Authorisation waiting; OrderNo: {1}", order.orderNo);
return ret;
} else {
log.error("SendPayPalInfo function in libPayment.ds: PayPal Authorization Request Authorisation refused; OrderNo: {1}", order.orderNo);
return ret;
}
}
}
ret.success = true;
return ret;
}
/**
* Save Paypal alias information
*/
function savePaypalAlias() {
if(session.custom.saveAlias){
var savedAliases = session.customer.profile.custom.hostedTokenizationPaymentMethods;
var newPaypalAlias = true;
var savedAliasesObj = JSON.parse(savedAliases);
if(empty(savedAliasesObj)){
savedAliasesObj = [];
}
for each(var alias in savedAliasesObj){
if(alias[0]=='PAYPAL'){
alias[1] = session.custom.alias;
newPaypalAlias = false;
}
}
if(newPaypalAlias){
savedAliasesObj.push(['PAYPAL',session.custom.alias]);
}
session.customer.profile.custom.hostedTokenizationPaymentMethods = JSON.stringify(savedAliasesObj);
session.custom.paymentMethode = null;
session.custom.saveAlias = null;
session.custom.alias = null;
}
}
/**
* Set Klarna addition fiels
*
* @param {String} PaymentMethod
* @param {String} Country
* @param {dw.customer.Customer} CurrentCustomer
* @param {dw.order.Basket} Basket
*/
function setKlarnaFields(PaymentMethod, Country, CurrentCustomer, Basket) {
var templateName = 'klarnaecommerce' + Country;
var CurrentForms = session.forms;
var CurrentHttpParameterMap = request.httpParameterMap;
if (PaymentMethod == "Klarna Installment E-commerce") {
templateName = 'klarnaecommerceinstallment' + Country;
}
if (!empty(CurrentForms.billing.paymentMethods[templateName].dateOfBirth) && CurrentHttpParameterMap[CurrentForms.billing.paymentMethods[templateName].dateOfBirth.htmlName].stringValue) {
Basket.billingAddress.custom.dateOfBirth = new Date(CurrentHttpParameterMap[CurrentForms.billing.paymentMethods[templateName].dateOfBirth.htmlName].stringValue.replace(/-/g,'/'));
}
if (!empty(CurrentForms.billing.paymentMethods[templateName].cuid)) {
Basket.billingAddress.custom.cuid = CurrentHttpParameterMap[CurrentForms.billing.paymentMethods[templateName].cuid.htmlName].stringValue;
}
if (!empty(CurrentForms.billing.paymentMethods[templateName].houseNumber)) {
Basket.billingAddress.custom.houseNumber = CurrentHttpParameterMap[CurrentForms.billing.paymentMethods[templateName].houseNumber.htmlName].stringValue;
}
if (!empty(CurrentForms.billing.paymentMethods[templateName].gender)) {
Basket.billingAddress.custom.gender = parseInt(CurrentHttpParameterMap[CurrentForms.billing.paymentMethods[templateName].gender.htmlName].value);
}
}
/**
* Validate the Direct Debits forms data fields.
* The script get the PaymentForms object at input, containing all forms data (Direct Debits DE, AT and NL)
* , validate current form and add output results: - the status of the validation, - the paymentType and - the data of the current form validated.
*
* @param {dw.web.FormGroup} form
* @param {dw.customer.Customer} customer
* @returns {Object} ret
* @returns {dw.system.Status} ret.DirectDebitsStatus
* @returns {String} ret.PaymentType
* @returns {dw.web.FormGroup} ret.DirectDebitsForm
* @returns {Boolean} ret.success
*/
function VerifyPaymentDirectDebits(form, customer) {
var IngenicoConfiguration = getIngenicoConfiguration();
var ret = {
'DirectDebitsStatus' : null,
'PaymentType' : null,
'DirectDebitsForm' : null,
'success' : false
}
var paymentType : String = forms.selectedPaymentMethodID.htmlValue;
var newSEPA = IngenicoConfiguration.enableNewSEPAVersion;
if (empty(paymentType)) {
Logger.error('VerifyPaymentDirectDebits function in libPayment.ds : Empty paymentType');
return ret;
}
var mapForms = {
'DIRECT_DEBITS_DE' : forms.directdebitsde,
'DIRECT_DEBITS_NL' : forms.directdebitsnl,
'DIRECT_DEBITS_AT' : forms.directdebitsat
};
var form = mapForms[paymentType];
var status = new dwsystem.Status();
// Validate Direct Debits DE form:
if (paymentType == 'DIRECT_DEBITS_DE') {
// Check to be completed the Konto and Blz fields, if Iban is empty (CARDNO = Konto + Blz) or Iban completed (CARDNO = Iban).
// Not allowed IBAN with Konto or Blz empty, or all three empty.
var ibanRequired = newSEPA && empty(form.iban.htmlValue);
var ibanNullOrRequired = !newSEPA || ibanRequired;
if (ibanRequired && empty(form.konto.htmlValue) && empty(form.blz.htmlValue)) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'IBAN-MISSING',
Resource.msg('forms.directdebitsde.iban.missing', 'forms', null),
{});
status.addItem(statusItem);
} else if (ibanNullOrRequired && empty(form.konto.htmlValue)) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'KONTO-MISSING',
Resource.msg('forms.directdebitsde.konto.missing', 'forms', null),
{});
status.addItem(statusItem);
} else if (ibanNullOrRequired && empty(form.blz.htmlValue)) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'BLZ-MISSING',
Resource.msg('forms.directdebitsde.blz.missing', 'forms', null),
{});
status.addItem(statusItem);
} else {
// Check the fields data lengths: iban=22 digits, konto=up to 10, blz=8 digits
if (newSEPA && !empty(form.iban.htmlValue)) {
if (form.iban.htmlValue.replace(/\s/g, '').length != 22) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'IBAN-INVALID',
Resource.msg('forms.directdebitsde.iban.invalid', 'forms', null),
{});
status.addItem(statusItem);
}
}
if (!empty(form.konto.htmlValue)) {
if (form.konto.htmlValue.replace(/\s/g, '').length > 10) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'KONTO-INVALID',
Resource.msg('forms.directdebitsde.konto.invalid', 'forms', null),
{});
status.addItem(statusItem);
}
}
if (!empty(form.blz.htmlValue)) {
if (form.blz.htmlValue.replace(/\s/g, '').length != 8) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'BLZ-INVALID',
Resource.msg('forms.directdebitsde.blz.invalid', 'forms', null),
{});
status.addItem(statusItem);
}
}
}
// - Expiration Date fields
if (empty(form.month.htmlValue) || empty(form.year.htmlValue)) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'ED-MISSING',
Resource.msg('forms.directdebitsnl.ed.missing', 'forms', null),
{});
status.addItem(statusItem);
} else {
var ccExpYear = new Number(form.year.selectedOption.value);
var ccExpMonth = new Number(form.month.selectedOption.value) - 1; // January should be 0
var today = new Date();
var expDate = new Date(ccExpYear, ccExpMonth, 1);
if (expDate < today) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'ED-INVALID',
Resource.msg('forms.directdebitsnl.ed.invalid', 'forms', null),
{});
status.addItem(statusItem);
}
}
// Validate Direct Debits AT form:
} else if (paymentType == 'DIRECT_DEBITS_AT') {
// - konto field (lengths for Austria: konto=up to 11 digits, blz=5 digits)
if (empty(form.konto.htmlValue)) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'KONTO-MISSING',
Resource.msg('forms.directdebitsat.konto.missing', 'forms', null),
{});
status.addItem(statusItem);
} else if (form.konto.htmlValue.replace(/\s/g, '').length > 11) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'KONTO-INVALID',
Resource.msg('forms.directdebitsat.konto.invalid', 'forms', null),
{});
status.addItem(statusItem);
}
// - blz field
if (empty(form.blz.htmlValue)) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'BLZ-MISSING',
Resource.msg('forms.directdebitsat.blz.missing', 'forms', null),
{});
status.addItem(statusItem);
} else if (form.blz.htmlValue.replace(/\s/g, '').length != 5) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'BLZ-INVALID',
Resource.msg('forms.directdebitsat.blz.invalid', 'forms', null),
{});
status.addItem(statusItem);
}
// - Expiration Date fields
if (empty(form.month.htmlValue) || empty(form.year.htmlValue)) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'ED-MISSING',
Resource.msg('forms.directdebitsnl.ed.missing', 'forms', null),
{});
status.addItem(statusItem);
} else {
var ccExpYear = new Number(form.year.selectedOption.value);
var ccExpMonth = new Number(form.month.selectedOption.value) - 1; // January should be 0
var today = new Date();
var expDate = new Date(ccExpYear, ccExpMonth, 1);
if (expDate < today) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'ED-INVALID',
Resource.msg('forms.directdebitsnl.ed.invalid', 'forms', null),
{});
status.addItem(statusItem);
}
}
// Validate Direct Debits NL form:
} else if (paymentType == 'DIRECT_DEBITS_NL') {
// - IBAN field (lengths for Netherland: Iban=18 digits, bic=up to 11 digits)
if (empty(form.iban.htmlValue)) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'IBAN-MISSING',
Resource.msg('forms.directdebitsnl.iban.missing', 'forms', null),
{});
status.addItem(statusItem);
}
// - BIC field if SEPA enabled
if (newSEPA && !empty(form.bic.htmlValue)) {
if (form.bic.htmlValue.replace(/^\s+|\s+$/gm,'').length > 11) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'BIC-INVALID',
Resource.msg('forms.directdebitsnl.bic.invalid', 'forms', null),
{});
status.addItem(statusItem);
}
}
}
// For all Direct Debits forms
// - Cardholder Name field
if (empty(form.cn.htmlValue)) {
var statusItem = new dwsystem.StatusItem(
Status.ERROR,
'CN-MISSING',
Resource.msg('forms.directdebitsnl.cn.missing', 'forms', null),
{});
status.addItem(statusItem);
}
ret.DirectDebitsStatus = status;
ret.DirectDebitsForm = form;
ret.PaymentType = paymentType;
if (status.error) {
return ret;
}
var checkValues = form.cn.htmlValue;
if (paymentType != 'DIRECT_DEBITS_NL') {
checkValues += "," + form.month.selectedOption.value + "," + form.year.selectedOption.value;
}
ret.success = true;
return ret;
}
/**
* Invalidates the Direct Debits form element in case specified status is ERROR.
* If status is undefined or form is invalid the pipelet returns PIPELET_ERROR.
*
* @param {dw.system.Status} status
* @param {dw.web.FormGroup} directDebitsForm
* @returns {Boolean}
*/
function InvalidatePaymentDirectDebitsFormElements(status, directDebitsForm) {
// verify that we have a status object and a valid credit card form
if (status == null || !directDebitsForm.valid) {
return false;
}
// we are fine, if status is OK
if (status.status == dwsystem.Status.OK) {
return true;
}
// invalidate the payment card form elements
var items = status.items.iterator();
while (items.hasNext()) {
var item = items.next();
switch (item.code) {
case 'IBAN-MISSING':
directDebitsForm.iban.invalidateFormElement(item.message);
continue;
case 'IBAN-INVALID':
directDebitsForm.iban.invalidateFormElement(item.message);
continue;
case 'KONTO-MISSING':
directDebitsForm.konto.invalidateFormElement(item.message);
continue;
case 'KONTO-INVALID':
directDebitsForm.konto.invalidateFormElement(item.message);
continue;
case 'BLZ-MISSING':
directDebitsForm.blz.invalidateFormElement(item.message);
continue;
case 'BLZ-INVALID':
directDebitsForm.blz.invalidateFormElement(item.message);
continue;
case 'BIC-MISSING':
directDebitsForm.bic.invalidateFormElement(item.message);
continue;
case 'BIC-INVALID':
directDebitsForm.bic.invalidateFormElement(item.message);
continue;
case 'CN-MISSING':
directDebitsForm.cn.invalidateFormElement(item.message);
continue;
case 'ED-MISSING':
directDebitsForm.month.invalidateFormElement(item.message);
continue;
case 'ED-INVALID':
directDebitsForm.month.invalidateFormElement(item.message);
continue;
}
}
return true;
}
/**
* Sends Authorization to payment through DirectLink for Direct Debits AT, DE and NL
*
* @param {dw.web.FormGroup} forms
* @param {dw.order.Order} order
* @param {String} locale
* @returns {String} ret.Status
* @returns {String} ret.StatusDescription
* @returns {String} ret.PaymentMethod
* @returns {String} ret.PayID
* @returns {String} ret.Brand
* @returns {String} ret.PaymentMethodIDOut
* @returns {String} ret.ErrorString
* @returns {String} ret.ResultStatusCheck
* @returns {Boolean} ret.succes
*/
function SendDirectDebitsAuthorization(forms, order, locale) {
var log : Logger = dwsystem.Logger.getLogger("payment");
var IngenicoConfiguration = getIngenicoConfiguration();
var ret = {
'Status' : null,
'StatusDescription' : null,
'PaymentMethod' : null,
'PayID' : null,
'Brand' : null,
'PaymentMethodIDOut' : null,
'ErrorString' : null,
'ResultStatusCheck' : null,
'success' : false,
}
var paymentType = forms.selectedPaymentMethodID.htmlValue;
var mapForms = {
'DIRECT_DEBITS_DE' : forms.directdebitsde,
'DIRECT_DEBITS_NL' : forms.directdebitsnl,
'DIRECT_DEBITS_AT' : forms.directdebitsat
};
var form = mapForms[paymentType];
var paymentMethodId = paymentType;
var paymentMgr = null;
if (empty(order)) {
log.error('SendDirectDebitsAuthorization function in libPayment.ds: Missing required input parameter(s) Order.');
return ret;
}
var resultObj = null;
var status = "";
var PaymentMethod = "";
var payID = "";
var brand = "";
var start = new Date();
var enableTwoSteps = IngenicoConfiguration.enableTwoStepsAuthorizationDirectLink;
var enableNewSEPAVersion = IngenicoConfiguration.enableNewSEPAVersion;
var operation = (paymentType == 'DIRECT_DEBITS_NL') ? 'VEN' : enableTwoSteps ? 'RES' : 'VEN';
try {
paymentObj = new PaymentCtnr(order, order.orderNo, null, paymentMethodId, null, locale);
status = paymentObj.getStatus();
var data = {};
if (paymentType == 'DIRECT_DEBITS_DE') {
data = {
iban: form.iban.htmlValue,
konto: form.konto.htmlValue,
blz: form.blz.htmlValue
};
} else if (paymentType == 'DIRECT_DEBITS_NL') {
data = {
iban: form.iban.htmlValue
};
// if SEPA enabled, display BIC optional field for NL
if (enableNewSEPAVersion) {
var transactionDate = order.creationDate;
var getTDYear = transactionDate.getFullYear().toString();
var getTDMonth = (transactionDate.getMonth() + 1) < 10 ? '0' + (transactionDate.getMonth() + 1).toString() : (transactionDate.getMonth() + 1).toString();
var getTDDate = transactionDate.getDate() < 10 ? '0' + transactionDate.getDate().toString() : transactionDate.getDate().toString();
if (form.bic.htmlValue) {
data.bic = form.bic.htmlValue;
}
data.transactionDate = getTDYear + getTDMonth + getTDDate;
}
} else if (paymentType == 'DIRECT_DEBITS_AT') {
data = {
konto: form.konto.htmlValue,
blz: form.blz.htmlValue
};
}
// make the payment request and save the response to 'resultObj'
resultObj = paymentObj.sendDirectLinkDirectDebitsNewOrderRequest(operation, locale, data);
} catch (error) {
var end = new Date();
var diff = (end.getTime() - start.getTime()) * 0.001;
if(!empty(error.status) && !empty(error.ErrorCode)){
ret.ResultStatusCheck = paymentObj.checkStatus(error.status, error.ErrorCode);
} else {
ret.ResultStatusCheck = '';
}
return ret;
}
var useFraudDetection = IngenicoConfiguration.enableFraudDetection;
if ( !empty(resultObj) ) {
// get resultObj data, store them to output
status = resultObj.hasOwnProperty("status") ? resultObj.status : status;
PaymentMethod = resultObj.hasOwnProperty("pm") ? resultObj.pm : '';
payID = resultObj.hasOwnProperty("payid") ? resultObj.payid : '';
brand = resultObj.hasOwnProperty("brand") ? resultObj.brand : '';
if (!empty(useFraudDetection) && useFraudDetection) {
order.custom.payment_ip = resultObj.hasOwnProperty("ip") ? resultObj.ip : '';
order.custom.payment_aavCheck = resultObj.hasOwnProperty("aavcheck") ? resultObj.aavcheck : '';
order.custom.payment_cvcCheck = resultObj.hasOwnProperty("cvccheck") ? resultObj.cvccheck : '';
order.custom.payment_scoring = resultObj.hasOwnProperty("scoring") ? resultObj.scoring : '';
order.custom.payment_scoCategory = resultObj.hasOwnProperty("sco_category") ? resultObj.sco_category : '';
}
if(!empty(brand)){
PaymentMethod+=" - "+brand;
}
// set used payment method to ensure used payment method ID could be returned
if (!empty(PaymentMethod)) paymentObj.setPaymentMethod(PaymentMethod);
}
order.custom.payment_PAYID = payID;
ret.Status = status;
ret.StatusDescription = getPaymentStatusDescription(status);
ret.PaymentMethod = PaymentMethod;
ret.PayID = payID;
ret.Brand = brand;
ret.PaymentMethodIDOut = paymentMethodId;
// status=5, the authorisation has been accepted
if (status == "5") {
// Update the order for background step 2 reservation request
order.custom.payment_isAuthorized = true;
order.custom.payment_needCapture = true;
order.custom.payment_authorizationStatus = 'AUTHORISED';
order.custom.payment_captureAttempts = 0;
order.custom.payment_data = JSON.stringify({
paymentMethodID: paymentMethodId,
locale: locale
});
} else {
order.custom.payment_isAuthorized = false;
order.custom.payment_needCapture = false;
order.custom.payment_captureAttempts = 0;
ret.ResultStatusCheck = paymentObj.checkStatus(status, 0);
if(status != "9"){
// status=46, waiting for identification.
if ( status == "46" ) {
if (enableTwoSteps) {
order.custom.payment_data = JSON.stringify({
paymentMethodID: PaymentMethodId,
locale: locale
});
}
// status=51, the authorisation will be processed offline.
} else if ( status == "51" ) {
order.getCustom()["payment_authWaiting"] = true;
log.error("SendDirectDebitsAuthorization function in libPayment.ds: Direct Link Authorisation Request Authorisation waiting; OrderNo: {0}", order.orderNo);
ret.ErrorString = Resource.msg('billing.paymentstatus51', locale + '/checkout', null);
}
}
// if status=9, the payment has been accepted.
if (status != "51") {
order.setPaymentStatus(dworder.Order.PAYMENT_STATUS_PAID);
}
}
if(ret.ResultStatusCheck == "FAIL") {
return ret;
}
ret.success = true;
return ret;
}
/**
* Checks wether 3DS is necessary. When payment_last3DSauthorization on OrderPaymentInstrument exists and is before now
* 3DS check isn't necessary anymore. Only one 3DS Check per Customer and Credit Card is required.
* @param {dw.order.Order} order
* @return {Boolean}
*/
function Is3DSEnabled(order) {
var log = dwsystem.Logger.getLogger("payment");
var IngenicoConfiguration = getIngenicoConfiguration();
var secureCards = IngenicoConfiguration.creditCardType
.toLocaleString()
.split(',');//array of objects(LIST)
secureCards = toArrayOfStrings(secureCards);//array of strings
// if 'enable3ds' attribute is enabled, first get data for the current order
if (IngenicoConfiguration.enable3ds) {
var orderPaymentInstrument = order.currentOrder.getPaymentInstruments()[0];
// if current card type is one from the list in secureCards, check if exists payment_last3DSauthorization
var cardType = orderPaymentInstrument.creditCardType;
if(empty(cardType)){
cardType = session.custom.paymentMethode;
}
if(!empty(cardType) && secureCards.contains(cardType.toUpperCase())){
if ( !empty(orderPaymentInstrument.custom.payment_last3DSauthorization) ) {
var last3DSauthorization = new dwutils.Calendar(orderPaymentInstrument.custom.payment_last3DSauthorization);
if ( last3DSauthorization.before(new dwutils.Calendar()) ) {
return true;
}
}else{
// if not, create payment_last3DSauthorization = current date, enable 3DS
var last3DSauthorization = new Date();
orderPaymentInstrument.custom.payment_last3DSauthorization=last3DSauthorization;
return true;
}
}
}
return false;
}
/**
* Get Payment request Parameters
*
* @param {dw.order.Order} Order
* @param {dw.system.Request} Request
* @param {String} PaymentMethodID
* @returns {Object} ret
* @returns {dw.util.HashMap} ret.PaymentRequestParameters
* @returns {Boolean} ret.success
*/
function GetPaymentRequestParameters(Order, Request, PaymentMethodID) {
var log = dwsystem.Logger.getLogger("payment");
var ret = {
'PaymentRequestParameters' : null,
'success' : false
}
try {
if (empty(Order)) throw Error("No Order provided");
if (empty(Request)) throw Error("No CurrentRequest provided");
if (empty(Order.orderNo)) throw Error("No OrderNo provided");
var paymentCtnr = new PaymentCtnr(Order, Order.orderNo, null, PaymentMethodID, Request, Request.locale);
ret.PaymentRequestParameters = paymentCtnr.getRequestParameters();
ret.success = true;
}
catch (error) {
log.error("GetPaymentRequestParameters function in libPayment.ds: An error occured during Payment Request Parameters build: " + error);
return ret;
}
return ret;
}
/**
* Change payment status
*
* @param {dw.order.Order} order
* @param {dw.web.HttpParameterMap} paramMap
* @param {String} locale
* @returns {Object} ret
* @returns {String} ret.ResultStatusCheck
* @returns {Boolean} ret.success
*/
function PaymentChangeStatus(order, paramMap, locale) {
var ret = {
'ResultStatusCheck' : null,
'success' : false
}
var IngenicoConfiguration = getIngenicoConfiguration();
var status = paramMap.STATUS.value;
var paymentInstrument = order.getPaymentInstruments()[0];
var paymentMethodID = paymentInstrument.getPaymentMethod();
var resultObj = null;
var status = "";
var PaymentMethod = "";
var payID="";
var ip = "";
var start : Date = new Date();
try {
var paymentCtnr = new PaymentCtnr(order, order.orderNo, null, null, null, locale);
status = paymentCtnr.getStatus();
resultObj = paymentCtnr.sendDirectQuery();
}
catch (error) {
var end = new Date();
var diff = (end.getTime() - start.getTime()) * 0.001;
ret.ResultStatusCheck = paymentCtnr.checkStatus(error.status, error.ErrorCode);
return ret;
}
var useFraudDetection = IngenicoConfiguration.enableFraudDetection;
if ( !empty(resultObj) ) {
status = resultObj.hasOwnProperty("status") ? resultObj.status : status;
PaymentMethod = resultObj.hasOwnProperty("pm") ? resultObj.pm : '';
payID = resultObj.hasOwnProperty("payid") ? resultObj.payid : '';
brand = resultObj.hasOwnProperty("brand") ? resultObj.brand : '';
if (!empty(useFraudDetection) && useFraudDetection) {
order.custom.payment_ip = resultObj.hasOwnProperty("ip") ? resultObj.ip : '';
order.custom.payment_aavCheck = resultObj.hasOwnProperty("aavcheck") ? resultObj.aavcheck : '';
order.custom.payment_cvcCheck = resultObj.hasOwnProperty("cvccheck") ? resultObj.cvccheck : '';
order.custom.payment_scoring = resultObj.hasOwnProperty("scoring") ? resultObj.scoring : '';
order.custom.payment_scoCategory = resultObj.hasOwnProperty("sco_category") ? resultObj.sco_category : '';
}
order.custom.payment_PAYID = payID;
if(!empty(brand)){
PaymentMethod+=" - "+brand;
}
// set used payment method to ensure used payment method ID could be returned
if (!empty(PaymentMethod)) paymentCtnr.setPaymentMethod(PaymentMethod);
}
if( order == null){
return ret;
}
var paymentInstruments = order.getPaymentInstruments();
var amount = calculateNonGiftCertificateAmount(order);
if( paymentInstruments == null || paymentInstruments.isEmpty() ) {
var paymentInstr = order.createPaymentInstrument(PaymentMethod, amount);
}
else{
var paymentInstr = paymentInstruments[0];
}
var paymentprocc : dworder.PaymentProcessor = dworder.PaymentMgr.getPaymentMethod(paymentMethodID).getPaymentProcessor();
paymentInstr.getPaymentTransaction().setPaymentProcessor(paymentprocc);
paymentInstr.getPaymentTransaction().setTransactionID(payID.toString());
paymentInstr.paymentTransaction.custom.paymentStatus = status;
paymentInstr.paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentInstr.paymentTransaction.custom.paymentStatus);
paymentInstr.custom.paymentMethod=PaymentMethod;
if (status == "5") {
// Update the order for background step 2 reservation request
order.custom.payment_isAuthorized = true;
order.custom.payment_needCapture = true;
order.custom.payment_captureAttempts = 0;
order.custom.payment_authorizationStatus = 'AUTHORISED';
order.custom.payment_data = JSON.stringify({
paymentMethodID: paymentMethodID,
locale: locale
});
} else {
order.custom.payment_isAuthorized = false;
order.custom.payment_needCapture = false;
order.custom.payment_captureAttempts = 0;
if (status == '8') {
order.custom.payment_refundStatus = 'REFUNDED';
} else if (status == '82') {
order.custom.payment_refundStatus = 'UNCERTAIN';
} else if (status == '83') {
order.custom.payment_refundStatus = 'REFUSED';
} else if (status == '84') {
order.custom.payment_refundStatus = 'DECLINED_BY_ACQUIRER';
} else if (status == '85') {
order.custom.payment_refundStatus = 'HANDLED_BY_MERCHANT';
}
var paymentInstrument : OrderPaymentInstrument = order.getPaymentInstruments()[0];
var paymentTransaction = paymentInstrument.paymentTransaction;
if (status == '9') {
order.custom.payment_needCapture = false;
order.custom.payment_captureAttempts += 1;
order.custom.payment_authorizationStatus = 'REQUESTED';
paymentTransaction.custom.paymentStatus=status;
paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentTransaction.custom.paymentStatus);
order.setPaymentStatus(dworder.Order.PAYMENT_STATUS_PAID);
} else if (status == '91') {
order.custom.payment_authorizationStatus = 'PENDING';
paymentTransaction.custom.paymentStatus=status;
paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentTransaction.custom.paymentStatus);
} else if (status == '92') {
order.custom.payment_authorizationStatus = 'UNCERTAIN';
paymentTransaction.custom.paymentStatus=status;
paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentTransaction.custom.paymentStatus);
} else if (status == '93') {
order.custom.payment_authorizationStatus = 'REFUSED';
paymentTransaction.custom.paymentStatus=status;
paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentTransaction.custom.paymentStatus);
} else if (status == '94') {
order.custom.payment_authorizationStatus = 'DECLINED_BY_ACQUIRER';
paymentTransaction.custom.paymentStatus=status;
paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentTransaction.custom.paymentStatus);
} else if (status == '95') {
order.custom.payment_authorizationStatus = 'HANDLED_BY_MERCHANT';
paymentTransaction.custom.paymentStatus=status;
paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentTransaction.custom.paymentStatus);
} else if (status == '6') {
order.custom.payment_authorizationStatus = 'CANCELLED';
paymentTransaction.custom.paymentStatus=status;
paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentTransaction.custom.paymentStatus);
} else if (status == '62') {
order.custom.payment_authorizationStatus = 'UNCERTAIN';
paymentTransaction.custom.paymentStatus=status;
paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentTransaction.custom.paymentStatus);
} else if (status == '63') {
order.custom.payment_authorizationStatus = 'REFUSED';
paymentTransaction.custom.paymentStatus=status;
paymentTransaction.custom.paymentStatusDescription = getPaymentStatusDescription(paymentTransaction.custom.paymentStatus);
}
}
// add check status method
// output the result and do fail/success/retry
ret.ResultStatusCheck = paymentCtnr.checkStatus(status, 0);
ret.success = true;
return ret;
}
/**
* Sets two custom attributes for orders, when TwoStep is enabled
*
* @param {dw.web.HttpParameterMap} params
* @returns {Boolean}
*/
function SetAuthorizedPayment(params) {
var log = dwsystem.Logger.getLogger("payment");
var IngenicoConfiguration = getIngenicoConfiguration();
var orderNo = params['orderNo'].stringValue;
var enableTwoSteps = IngenicoConfiguration.enableTwoStepsAuthorizationDirectLink;
var order = dworder.OrderMgr.getOrder(orderNo);
var shaCode = createShaForUrls(order);
if(shaCode != params.tn.toString()){
log.error('Order change not allowed, missing parameters');
return false;
}
try {
if (enableTwoSteps) {
// Update the order for background step 2 reservation request
order.custom.payment_isAuthorized = true;
order.custom.payment_needCapture = true;
order.custom.payment_captureAttempts = 0;
order.custom.payment_authorizationStatus = 'AUTHORISED';
} else {
order.setPaymentStatus(dworder.Order.PAYMENT_STATUS_PAID);
}
} catch(error) {
log.error("SetAuthorizedPayment function in libPayment.ds: {1}", error);
}
return true;
}
/**
* Validates Payment response and checks if SHAOut and parameters are valid
*
* @param {dw.web.HttpParameterMap} paramMap
* @returns {Boolean}
*/
function paymentSHAValidation(paramMap) {
var log = dwsystem.Logger.getLogger("payment");
var IngenicoConfiguration = getIngenicoConfiguration();
var SHAOut = IngenicoConfiguration.shaOutPassword;
if (empty(SHAOut)) {
return false;
}
if (empty(paramMap)) {
log.error('paymentSHAValidation function in libPayment.ds: Missing required input parameter(s).');
return false;
}
if (paramMap.getParameterCount() <= 0) {
log.error('paymentSHAValidation function in libPayment.ds: Missing Payment HTTP parameter(s).');
return false;
}
var shaSignFromRequest;
var hashMethod = IngenicoConfiguration.shaMethod;
var digest = new dwcrypto.MessageDigest(hashMethod);
var paramSortedMap = new dwutil.SortedMap();
var paramIterator = paramMap.getParameterNames().iterator();
while (paramIterator.hasNext()) {
var paramName = paramIterator.next().toString();
// exclude parameters sent from DW
if (paramName.indexOf('dw_') == 0 || paramName == 'tn' || paramName == 'orderNo' || paramName == 'pmID') {
continue;
}
if (paramName == 'SHASIGN') {
shaSignFromRequest = paramMap[paramName].value;
continue;
}
// paramters without value are not included in sha calculation
if (empty(paramMap[paramName].value)){
continue;
}
paramSortedMap.put(paramName.toUpperCase(), paramMap[paramName].value);
}
if (empty(shaSignFromRequest)) {
return false;
}
var paramKeySet = paramSortedMap.keySet();
var paramIterator = paramKeySet.iterator();
var paramString = '';
while (paramIterator.hasNext()) {
var paramName = paramIterator.next().toString();
var paramValue = paramSortedMap.get(paramName);
paramString += paramName + '=' + paramValue.toString() + SHAOut;
}
var shaSignCalculated = digest.digest(paramString).toUpperCase();
if (shaSignCalculated !== shaSignFromRequest) {
log.error('paymentSHAValidation function in libPayment.ds: Payment returned parameters do not match the returned hash.');
return false;
}
return true;
}
/**
* Sends Authorization to payment through DirectLink for Credit Cards.
*
* @param {dw.order.Order} order
* @param {Boolean} enable3DS
* @param {String} PaymentMethodID
* @param {String} locale
* @param {dw.customer.Customer} Customer
* @returns {String} ret.Status
* @returns {String} ret.PaymentMethod
* @returns {String} ret.PayID
* @returns {String} ret.Brand
* @returns {Boolean} ret.Enrolled
* @returns {String} ret.HTML
* @returns {String} ret.PaymentMethodIDOut
* @returns {String} ret.ErrorString
* @returns {String} ret.ErrorString
* @returns {Boolean} ret.succes
*/
function SendHostedTokenizationCreditCardAuthorization(order, enable3DS, PaymentMethodID, locale, Customer) {
var log = dwsystem.Logger.getLogger("payment");
var IngenicoConfiguration = getIngenicoConfiguration();
var ret = {
'Status' : null,
'PaymentMethod' : null,
'PayID' : null,
'Brand' : null,
'Enrolled' : null,
'HTML' : null,
'PaymentMethodIDOut' : null,
'ErrorString' : null,
'ResultStatusCheck' : null,
'succes' : false
}
var paymentMgr = null;
var enable3DS = !empty(enable3DS) ? enable3DS : true;
if (empty(order)) {
log.error('SendHostedTokenizationCreditCardAuthorization function in libPayment.ds: Missing required input parameter(s) Order.');
return ret;
}
var resultObj = null;
var status = "";
var PaymentMethod = "";
var payID = "";
var brand = "";
var html = "";
var ip = "";
var start : Date = new Date();
var enableTwoSteps = IngenicoConfiguration.enableTwoStepsAuthorizationDirectLink;
var operation = enableTwoSteps ? 'RES' : 'SAL';
try {
var paymentObj = new PaymentCtnr(order, order.orderNo, null, PaymentMethodID,null,locale);
status = paymentObj.getStatus();
resultObj = paymentObj.sendDirectLinkCreditCardHostedTokenizationNewOrderRequest(operation, enable3DS, locale, null, null);
}
catch (error)
{
var x = error;
var end = new Date();
var diff = (end.getTime() - start.getTime()) * 0.001;
if(!empty(error.status) && !empty(error.ErrorCode)){
ret.ResultStatusCheck = paymentObj.checkStatus(error.status, error.ErrorCode);
ret.ErrorString=error.status.toString();
} else {
ret.ResultStatusCheck = '';
ret.ErrorString = '';
}
return ret;
}
var useFraudDetection = IngenicoConfiguration.enableFraudDetection;
if ( !empty(resultObj) ) {
status = resultObj.hasOwnProperty("status") ? resultObj.status : status;
PaymentMethod = resultObj.hasOwnProperty("pm") ? resultObj.pm : '';
payID = resultObj.hasOwnProperty("payid") ? resultObj.payid : '';
brand = resultObj.hasOwnProperty("brand") ? resultObj.brand : '';
html = resultObj.hasOwnProperty("html") ? resultObj.html : '';
if (!empty(useFraudDetection) && useFraudDetection) {
order.custom.payment_ip = resultObj.hasOwnProperty("ip") ? resultObj.ip : '';
order.custom.payment_aavCheck = resultObj.hasOwnProperty("aavcheck") ? resultObj.aavcheck : '';
order.custom.payment_cvcCheck = resultObj.hasOwnProperty("cvccheck") ? resultObj.cvccheck : '';
order.custom.payment_scoring = resultObj.hasOwnProperty("scoring") ? resultObj.scoring : '';
order.custom.payment_scoCategory = resultObj.hasOwnProperty("sco_category") ? resultObj.sco_category : '';
}
if (!empty(brand)) {
PaymentMethod += " - " + brand;
}
// set used payment method to ensure used payment method ID could be returned
if (!empty(PaymentMethod)) paymentObj.setPaymentMethod(PaymentMethod);
}
order.custom.payment_PAYID = payID;
ret.Status = status;
ret.PaymentMethod = PaymentMethod;
ret.PayID = payID;
ret.Brand = brand;
ret.Enrolled = false;
ret.HTML = html;
ret.PaymentMethodIDOut = PaymentMethodID;
// status=5, the authorisation has been accepted
if (status == "5") {
// Update the order for background step 2 reservation request
order.custom.payment_isAuthorized = true;
order.custom.payment_needCapture = true;
order.custom.payment_captureAttempts = 0;
order.custom.payment_authorizationStatus = 'AUTHORISED';
order.custom.payment_data = JSON.stringify({
paymentMethodID: PaymentMethodID,
locale: locale
});
if(session.custom.saveAlias){
var savedAliases = Customer.profile.custom.hostedTokenizationPaymentMethods;
var savedAliasesObj = JSON.parse(savedAliases);
if(empty(savedAliasesObj)){
savedAliasesObj = [];
}
savedAliasesObj.push([brand,session.custom.alias]);
Customer.profile.custom.hostedTokenizationPaymentMethods = JSON.stringify(savedAliasesObj);
}
session.custom.paymentMethode = null;
session.custom.saveAlias = null;
session.custom.alias = null;
} else {
order.custom.payment_isAuthorized = false;
order.custom.payment_needCapture = false;
order.custom.payment_captureAttempts = 0;
if(status != "9"){
// status=46, waiting for identification.
if ( status == "46" ) {
if (enableTwoSteps) {
order.custom.payment_data = JSON.stringify({
paymentMethodID: PaymentMethodID,
locale: locale
});
}
ret.Enrolled = true;
// status=51, the authorisation will be processed offline.
} else if ( status == "51" ) {
ret.Enrolled = true;
order.getCustom()["payment_authWaiting"] = true;
log.error("SendHostedTokenizationCreditCardAuthorization function in libPayment.ds: Direct Link Authorisation Request Authorisation waiting; OrderNo: {0}", order.orderNo);
ret.ErrorString = Resource.msg('billing.paymentstatus51', locale + '/checkout', null);
}
}
ret.ResultStatusCheck = paymentObj.checkStatus(status, 0);
if(ret.ResultStatusCheck == "FAIL") {
return ret;
}
// status=9, the payment has been accepted
// set order status as paid
if(!ret.Enrolled ){
order.setPaymentStatus(dworder.Order.PAYMENT_STATUS_PAID);
}
}
ret.success = true;
return ret;
}
module.exports = {
PaymentCtnr: PaymentCtnr,
getSHASignParameterFromRequest: getSHASignParameterFromRequest,
getSHASignParameterFromRequestUtf: getSHASignParameterFromRequestUtf,
formatExpiryNumbers: formatExpiryNumbers,
getURIParametersFromMap: getURIParametersFromMap,
generateSHAEcommerce: generateSHAEcommerce,
generateSHAMasterPassEcommerce: generateSHAMasterPassEcommerce,
generateSHAEcommercePaypal: generateSHAEcommercePaypal,
generateSHAKlarnaEcommerce: generateSHAKlarnaEcommerce,
toArrayOfStrings: toArrayOfStrings,
createDeviceFingerprintSessionID: createDeviceFingerprintSessionID,
getPaymentStatusDescription: getPaymentStatusDescription,
calculateNonGiftCertificateAmount: calculateNonGiftCertificateAmount,
addPriceAdjustments: addPriceAdjustments,
createShaForUrls: createShaForUrls,
getIngenicoConfiguration: getIngenicoConfiguration,
checkEcommercePaymentMethods: checkEcommercePaymentMethods,
ecommDecline: ecommDecline,
EcommerceCreatePaymentInstrument: EcommerceCreatePaymentInstrument,
EcommerceVerifyStatus: EcommerceVerifyStatus,
GetHostedTokenizationURL: GetHostedTokenizationURL,
GetPaymentDirectLinkOrderData: GetPaymentDirectLinkOrderData,
GetPaymentEcommOrderData: GetPaymentEcommOrderData,
SendPayPalInfo: SendPayPalInfo,
savePaypalAlias: savePaypalAlias,
setKlarnaFields: setKlarnaFields,
KlarnaEcommerceData: KlarnaEcommerceData,
MasterpassEcommerceData: MasterpassEcommerceData,
VerifyPaymentDirectDebits: VerifyPaymentDirectDebits,
InvalidatePaymentDirectDebitsFormElements: InvalidatePaymentDirectDebitsFormElements,
SendDirectDebitsAuthorization: SendDirectDebitsAuthorization,
Is3DSEnabled: Is3DSEnabled,
GetPaymentRequestParameters: GetPaymentRequestParameters,
PaymentChangeStatus: PaymentChangeStatus,
SetAuthorizedPayment: SetAuthorizedPayment,
paymentSHAValidation: paymentSHAValidation,
SendHostedTokenizationCreditCardAuthorization: SendHostedTokenizationCreditCardAuthorization
};