Authorize.net
1. Full ForterOrder.ds file using Authorize.net
Below is the full ForterOrder.ds file including the mapped authorization response for a merchant using the Authorize.net Gateway.
** Note that the majority of the mapping takes place in the ForterCreditCard(auth, cc) function. This specific function can be found in the next section, ForterCreditCard(auth, cc)
ForterOrder.ds file
/* ForterOrder.ds
var ForterLogger = require("int_forter/cartridge/scripts/lib/forter/ForterLogger.ds");
/**
* ForterOrder class is the DTO object for request.
*
* To include this script use:
* var ForterOrder = require("int_forter/cartridge/scripts/lib/forter/dto/ForterOrder.ds");
*/
function ForterOrder(args) {
var log = new ForterLogger("ForterOrder.ds"),
order = args.Order,
site = dw.system.Site.getCurrent(),
paymentInstruments = order.getPaymentInstruments(),
payment = null,
authResponse = null,
shipment = null;
for each (var paymentInstrument in paymentInstruments) {
if (paymentInstrument.paymentMethod == 'CREDIT_CARD') { //TODO: adjust to the existing payment instruments
payment = paymentInstrument;
authResponse = new XML(paymentInstrument.custom.authorize_net_authorization);
} else if (paymentInstrument.paymentMethod == 'PayPal' || paymentInstrument.paymentMethod == 'BML') { //TODO: adjust to the existing payment instruments
payment = paymentInstrument;
authResponse = paymentInstrument.custom.paypal_transaction_details_response;
}
}
// General parameters
this.orderId = order.originalOrderNo; // Required
this.orderType = "WEB"; // Required
this.timeSentToForter = (new Date()).getTime(); // Required
this.checkoutTime = new Number((order.creationDate.getTime()/1000).toFixed()); // Required //must be seconds, not milliseconds
this.connectionInformation = new ForterConnectionInformation(order); // Required
// Calculate totals
this.totalAmount = {}; // Required
this.totalAmount.amountLocalCurrency = order.totalGrossPrice.value.toFixed(2);
this.totalAmount.currency = order.totalGrossPrice.currencyCode;
//Calculate totals for discounts
var orderTotal = order.getMerchandizeTotalPrice(),
adjOrderTotal = order.getAdjustedMerchandizeTotalPrice(),
shipTotal = order.getShippingTotalPrice(),
adjShipTotal = order.getAdjustedShippingTotalPrice(),
total = orderTotal.add(shipTotal),
adjTotal = adjOrderTotal.add(adjShipTotal);
// Discounts
var discountPrice = 0;
var couponName = '';
var couponType = '';
if (!order.getCouponLineItems().isEmpty()) {
var coupons = order.getCouponLineItems();
var couponNames = [];
for each (let coup in coupons) {
couponNames.push(coup.getCouponCode());
if (!coup.getPriceAdjustments().isEmpty()) {
var coupAdjustments = coup.getPriceAdjustments();
for each (let coupAdj in coupAdjustments) {
discountPrice += coupAdj.priceValue;
}
}
}
couponName = couponNames.join(",");
discountPrice = discountPrice*(-1);
if (discountPrice > 0) {
this.totalDiscount = {}; // Optional
this.totalDiscount.couponCodeUsed = couponName.substring(0,20); // Required
this.totalDiscount.couponDiscountAmount = {}; // Required
this.totalDiscount.couponDiscountAmount.amountLocalCurrency = discountPrice.toFixed(2);
this.totalDiscount.couponDiscountAmount.currency = order.currencyCode;
this.totalDiscount.discountType = "COUPON"; // Required
}
}
// Customer's details
this.accountOwner = new ForterCustomer(order);
// Cart items (regular product)
this.cartItems = []; // Required
for each (var pli in order.productLineItems) {
this.cartItems.push(new ForterCartItem(pli));
}
// Cart items (gift certificate)
for each (var gcli in order.giftCertificateLineItems) {
this.cartItems.push(new ForterCartItem(gcli));
}
// Payments
this.payment = []; // Required
this.payment.push(new ForterPayment(order, authResponse, payment, log));
// Delivery and Recipient (shipping information)
if (order.shipments.length > 0) {
shipment = order.shipments[0];
this.primaryDeliveryDetails = {};
this.primaryDeliveryDetails.deliveryPrice = {};
this.primaryDeliveryDetails.deliveryMethod = (!empty(shipment.getShippingMethod()) && !empty(shipment.getShippingMethod().getDisplayName())) ? shipment.getShippingMethod().getDisplayName() : ""; //"BY AIR";
var deliveryType = "PHYSICAL"; //default value
if (order.productLineItems.size() > 0 && order.giftCertificateLineItems.size() == 0) {
deliveryType = "PHYSICAL"; //if real products only
} else if (order.productLineItems.size() == 0 && order.giftCertificateLineItems.size() > 0) {
deliveryType = "DIGITAL"; //if gift certificates only
this.primaryDeliveryDetails.deliveryMethod = "email";
} else if (order.productLineItems.size() > 0 && order.giftCertificateLineItems.size() > 0) {
deliveryType = "HYBRID"; //if gift certificates and real products
}
this.primaryDeliveryDetails.deliveryType = deliveryType;
this.primaryDeliveryDetails.deliveryPrice.amountLocalCurrency = shipment.adjustedShippingTotalPrice.value.toFixed(2);
this.primaryDeliveryDetails.deliveryPrice.currency = shipment.adjustedShippingTotalPrice.currencyCode.toString();
if (shipment.productLineItems.size() > 0) {
this.primaryRecipient = {}; // Optional
this.primaryRecipient.personalDetails = {};
this.primaryRecipient.personalDetails.firstName = shipment.shippingAddress.firstName; //from the shipping address
this.primaryRecipient.personalDetails.lastName = shipment.shippingAddress.lastName; //from the shipping address
this.primaryRecipient.address = {};
this.primaryRecipient.address.address1 = shipment.shippingAddress.address1;
this.primaryRecipient.address.address2 = !empty(shipment.shippingAddress.address2) ? shipment.shippingAddress.address2 : "";
this.primaryRecipient.address.zip = shipment.shippingAddress.postalCode;
this.primaryRecipient.address.city = shipment.shippingAddress.city;
this.primaryRecipient.address.region = shipment.shippingAddress.stateCode;
this.primaryRecipient.address.country = shipment.shippingAddress.countryCode.displayValue.toUpperCase();
this.primaryRecipient.phone = [];
if (!empty(shipment.shippingAddress.phone)){
this.primaryRecipient.phone.push(new ForterPhone(shipment.shippingAddress.phone));
}
} else if (shipment.giftCertificateLineItems.size() > 0) {
this.primaryRecipient = {}; // Optional
this.primaryRecipient.personalDetails = {};
this.primaryRecipient.personalDetails.fullName = shipment.giftCertificateLineItems[0].recipientName; //from the gift form
this.primaryRecipient.personalDetails.email = shipment.giftCertificateLineItems[0].recipientEmail; //from the gift form
}
if (shipment.gift == true) {
this.primaryRecipient.comments = {};
this.primaryRecipient.comments.messageToBeneficiary = shipment.giftMessage ? shipment.giftMessage : "";
}
}
function ForterConnectionInformation(order) {
this.customerIP = request.httpRemoteAddress; // Required
this.userAgent = request.httpUserAgent;
for (var i = 0; i < request.httpCookies.cookieCount; i++) {
if (request.httpCookies[i].name == "forterToken") {
this.forterTokenCookie = request.httpCookies[i].value; // Required
}
}
this.userAgent = request.httpUserAgent; // Required
this.forterTokenCookie = ""; // Conditional
for (var i = 0; i < request.httpCookies.cookieCount; i++) {
if (request.httpCookies[i].name == "forterToken") {
this.forterTokenCookie = request.httpCookies[i].value;
}
}
}
}
function ForterCustomer(order) {
if (order.customer.profile != null) {
this.firstName = order.customer.profile.firstName;
this.lastName = order.customer.profile.lastName;
this.email = order.customer.profile.email;
this.accountId = order.customer.ID;
this.created = new Number((order.customer.profile.getCreationDate().getTime()/1000).toFixed());
var query = "customerNo = {0} AND paymentStatus = {1}";
var allOrders : SeekableIterator = dw.order.OrderMgr.searchOrders(query, "creationDate desc", order.customer.profile.customerNo, 2);
this.pastOrdersCount = new Number(allOrders.count);
} else {
this.firstName = order.billingAddress.firstName;
this.lastName = order.billingAddress.lastName;
this.email = order.customerEmail;
}
}
function ForterPayment(order, authResponse, payment, log) {
var billingAddress = order.billingAddress;
this.billingDetails = {};
this.billingDetails.personalDetails = {};
this.billingDetails.personalDetails.firstName = billingAddress.firstName;
this.billingDetails.personalDetails.lastName = billingAddress.lastName;
this.billingDetails.personalDetails.email = order.customerEmail;
this.billingDetails.address = {};
this.billingDetails.address.address1 = billingAddress.address1;
this.billingDetails.address.address2 = !empty(billingAddress.address2) ? billingAddress.address2 : "";
this.billingDetails.address.zip = billingAddress.postalCode;
this.billingDetails.address.city = billingAddress.city;
this.billingDetails.address.region = billingAddress.stateCode;
this.billingDetails.address.country = billingAddress.countryCode.displayValue.toUpperCase();
if (!empty(billingAddress.phone)) {
this.billingDetails.phone = [];
this.billingDetails.phone.push(new ForterPhone(billingAddress.phone));
}
this.amount = {};
this.amount.amountLocalCurrency = order.totalGrossPrice.value.toFixed(2);
this.amount.currency = order.totalGrossPrice.currencyCode;
if (!empty(payment)) {
if (payment.paymentMethod == 'PayPal' || payment.paymentMethod == 'BML') {
this.paypal = new ForterPayPal(authResponse);
} else if (payment.paymentMethod == 'CREDIT_CARD') {
this.creditCard = new ForterCreditCard(authResponse, payment);
}
} else {
log.error('No payment method information for order: ' + order.originalOrderNo);
}
}
function ForterPhone(phone) {
this.phone = phone;
}
function ForterPayPal(authResponse) {
var transactionDetails = JSON.parse(authResponse);
this.payerId = transactionDetails.payerid; //"FD000A45P";
this.payerEmail = transactionDetails.email;
this.payerStatus = transactionDetails.payerstatus.toUpperCase(); //"VERIFIED";
this.payerAddressStatus = transactionDetails.addressstatus.toUpperCase();//"CONFIRMED";
this.paymentMethod = "";
this.paymentStatus = transactionDetails.paymentstatus.toUpperCase(); //"PENDING"
this.payerAccountCountry = transactionDetails.countrycode.toUpperCase(); //"US";
this.protectionEligibility = transactionDetails.protectioneligibility.toUpperCase(); //"ELIGIBLE";
this.correlationId = transactionDetails.correlationid; //"fdshkj2390sdf";
this.paymentId = "";
this.authorizationId = transactionDetails.transactionid; //"2WC75407LV7300439";
this.fullPaypalResponsePayload = {};
this.fullPaypalResponsePayload = transactionDetails;
}
function ForterCreditCard(auth, cc) {
var processorResponseCode = '',
processorResponseText = '';
// format the expiration month. from 1 to 01, etc.
if (cc.creditCardExpirationMonth.toString().length == 1) {
var creditCardExpMonth = "0" + cc.creditCardExpirationMonth.toString();
} else {
var creditCardExpMonth = cc.creditCardExpirationMonth.toString();
}
this.nameOnCard = cc.creditCardHolder;
this.cardBrand = cc.creditCardType;
if (cc.creditCardNumber.substring(0,6).indexOf('*') > -1) {
this.bin = session.forms.billing.paymentMethods.creditCard.number.value.substring(0,6);
} else {
this.bin = cc.creditCardNumber.substring(0,6);
}
this.lastFourDigits = cc.creditCardNumberLastDigits;
this.expirationMonth = creditCardExpMonth;
this.expirationYear = cc.creditCardExpirationYear.toString();
this.verificationResults = {};
this.verificationResults.avsStreetResult = ""; //TODO: must be adjusted according to the payment gateway used
this.verificationResults.avsZipResult = ""; //TODO: must be adjusted according to the payment gateway used
this.verificationResults.avsFullResult = auth.avsResultCode.toString(); //TODO: must be adjusted according to the payment gateway used
this.verificationResults.cvvResult = auth.cvvResultCode.toString(); //TODO: must be adjusted according to the payment gateway used
this.verificationResults.authorizationCode = auth.authCode.toString(); //TODO: must be adjusted according to the payment gateway used
this.paymentGatewayData = {};
this.paymentGatewayData.gatewayName = "AUTHORIZE.NET"; //TODO: must be adjusted according to the payment gateway used
this.paymentGatewayData.gatewayTransactionId = auth.transId.toString(); //TODO: must be adjusted according to the payment gateway used
if (auth.descendants('errors').length() > 0) { //TODO: must be adjusted according to the payment gateway used
processorResponseCode = auth.descendants('errors').descendants('errorCode').toString(); //TODO: must be adjusted according to the payment gateway used
processorResponseText = auth.descendants('errors').descendants('errorText').toString(); //TODO: must be adjusted according to the payment gateway used
} else if (auth.descendants('messages').length() > 0) { //TODO: must be adjusted according to the payment gateway used
processorResponseCode = auth.descendants('messages').descendants('code').toString(); //TODO: must be adjusted according to the payment gateway used
processorResponseText = auth.descendants('messages').descendants('description').toString(); //TODO: must be adjusted according to the payment gateway used
}
this.verificationResults.processorResponseCode = processorResponseCode;
this.verificationResults.processorResponseText = processorResponseText;
}
function ForterCartItem(item) {
this.basicItemData = {};
if (item instanceof dw.order.ProductLineItem) {
this.basicItemData.productId = item.productID; //Optional
this.basicItemData.name = item.productName; //Required
this.basicItemData.quantity = item.quantityValue; //Required
var product = item.getProduct();
if (product.getCategories().isEmpty() && !empty(product.getVariationModel())) {
product = product.getVariationModel().getMaster();
}
this.basicItemData.category = empty(product) ? "" : product.getCategories()[0].getDisplayName();
this.basicItemData.type = "TANGIBLE"; // Add if type is available. Change according to the actual item type
//if any adjustements
this.basicItemData.price = {};
this.basicItemData.price.amountLocalCurrency = item.adjustedPrice.value.toFixed(2);
this.basicItemData.price.currency = item.adjustedPrice.currencyCode.toString();
}
if (item instanceof dw.order.GiftCertificateLineItem) {
this.basicItemData.name = item.lineItemText; //Required
this.basicItemData.quantity = 1; //Required (set 1 by default for a gift cert?)
this.basicItemData.type = "NON_TANGIBLE"; // Add if type is available. Change according to the actual item type
this.deliveryDetails = {};
this.deliveryDetails.deliveryType = "DIGITAL";
this.deliveryDetails.deliveryMethod = "email";
this.basicItemData.price = {};
this.basicItemData.price.amountLocalCurrency = item.price.value.toFixed(2);
this.basicItemData.price.currency = item.price.currencyCode.toString();
this.beneficiaries = [];
this.beneficiaries.push(new ForterBeneficiaryDetailsFromGiftCard(item));
}
}
function ForterBeneficiaryDetailsFromGiftCard(item) {
this.personalDetails = {};
this.comments = {};
this.personalDetails.fullName = item.recipientName;
this.personalDetails.email = item.recipientEmail;
this.comments.messageToBeneficiary = item.message ? item.message : "";
}
module.exports = ForterOrder;2. ForterCreditCard(auth, cc) function
The code featured below features the mapped Authorize.net authorization response payment details (bin, last 4, expiration) for a credit Card transaction in the SalesForce CommerceCloud Cartridge. The same file can be found in the full Forter cartridge .zip file by going to: Cartridges>int_forter>cartridge>scripts>lib>forter>dto>ForterOrder.ds
Please note the verificationResults Object** which should contain the authorization results from Authorize.net
** Non-Credit Card transactions such as PayPal or Gift Cards should be mapped to their associated functions in the code, ForterPayPal (order, a ), and ForterGiftCard (auth, gc) respectively.
ForterCreditCard(auth, cc) Function
function ForterCreditCard(auth, cc) {
var processorResponseCode = "",
processorResponseText = "";
// format the expiration month. from 1 to 01, etc.
if (cc.creditCardExpirationMonth.toString().length == 1) {
var creditCardExpMonth = "0" + cc.creditCardExpirationMonth.toString();
} else {
var creditCardExpMonth = cc.creditCardExpirationMonth.toString();
}
this.nameOnCard = cc.creditCardHolder;
this.cardBrand = cc.creditCardType;
if (cc.creditCardNumber.substring(0, 6).indexOf("*") > -1) {
this.bin = session.forms.billing.paymentMethods.creditCard.number.value.substring(
0,
6
);
} else {
this.bin = cc.creditCardNumber.substring(0, 6);
}
this.lastFourDigits = cc.creditCardNumberLastDigits;
this.expirationMonth = creditCardExpMonth;
this.expirationYear = cc.creditCardExpirationYear.toString();
this.verificationResults = {};
this.verificationResults.avsStreetResult = ""; //TODO: must be adjusted according to the payment gateway used
this.verificationResults.avsZipResult = ""; //TODO: must be adjusted according to the payment gateway used
this.verificationResults.avsFullResult = auth.avsResultCode.toString(); //TODO: must be adjusted according to the payment gateway used
this.verificationResults.cvvResult = auth.cvvResultCode.toString(); //TODO: must be adjusted according to the payment gateway used
this.verificationResults.authorizationCode = auth.authCode.toString(); //TODO: must be adjusted according to the payment gateway used
this.paymentGatewayData = {};
this.paymentGatewayData.gatewayName = "AUTHORIZE.NET"; //TODO: must be adjusted according to the payment gateway used
this.paymentGatewayData.gatewayTransactionId = auth.transId.toString(); //TODO: must be adjusted according to the payment gateway used
if (auth.descendants("errors").length() > 0) {
//TODO: must be adjusted according to the payment gateway used
processorResponseCode = auth
.descendants("errors")
.descendants("errorCode")
.toString(); //TODO: must be adjusted according to the payment gateway used
processorResponseText = auth
.descendants("errors")
.descendants("errorText")
.toString(); //TODO: must be adjusted according to the payment gateway used
} else if (auth.descendants("messages").length() > 0) {
//TODO: must be adjusted according to the payment gateway used
processorResponseCode = auth
.descendants("messages")
.descendants("code")
.toString(); //TODO: must be adjusted according to the payment gateway used
processorResponseText = auth
.descendants("messages")
.descendants("description")
.toString(); //TODO: must be adjusted according to the payment gateway used
}
this.verificationResults.processorResponseCode = processorResponseCode;
this.verificationResults.processorResponseText = processorResponseText;
}