Source: PAYMENT_ECOMMERCE.js

'use strict';

/**
 * Controller for PAYMENT_ECOMMERCE.
 *
 * @module controllers/PAYMENT_ECOMMERCE
 */

var app = require('sitegenesis_controllers/cartridge/scripts/app');
var guard = require('sitegenesis_controllers/cartridge/scripts/guard');

/* API Includes */
var PaymentMgr = require('dw/order/PaymentMgr');
var OrderMgr = require('dw/order/OrderMgr');
var Transaction = require('dw/system/Transaction');
var URLUtils = require('dw/web/URLUtils');

var libPayment = require('int_payment_core/cartridge/scripts/lib/libPayment.ds')
var parameterMap = request.httpParameterMap;
var SubmitImpl = app.getModel('Order').submit;


/**
 * Handle Asyncronious Ecommerce Payment
 */
 
function CheckEcommercePayment(args) {
	var ret = {};
	var result = {};

	if(!empty(parameterMap.orderNo.stringValue)){
		var OrderNo = parameterMap.orderNo.stringValue;
		var PM = parameterMap.pmID.value;
	} else {
		var OrderNo = parameterMap.orderID.stringValue;
		var PM = parameterMap.PM.value;
	}
	
	var order = OrderMgr.getOrder(OrderNo);
	var ShaCode = libPayment.createShaForUrls(order);
	
	if((!empty(args) && args.isS2S == true) || ShaCode  ==  parameterMap.tn.toString()) {
		Transaction.wrap(function () {
			order.custom.ecommerceResponseCount = 1;
			session.forms.billing.fulfilled.value = true;
		});
		
		ret.Order = order;
		
		if(order.status == dw.order.Order.ORDER_STATUS_CREATED) {
			if(libPayment.paymentSHAValidation(parameterMap)){
			    Transaction.wrap(function () {
					result = libPayment.GetPaymentEcommOrderData(order, request.locale, PM);
				});
					ret.Status = result.Status;
					ret.PaymentMethodID = result.PaymentMethodID;
					ret.ErrorStatus = result.ErrorStatus;
					ret.PaymentStatus = result.PaymentStatus;
					ret.ResultStatusCheck = result.ResultStatusCheck;
			} else {
				ret.EndNode = 'error';
			}
		} else if(order.status != dw.order.Order.ORDER_STATUS_FAILED) {			
			response.redirect(URLUtils.https('Ingenico-AcceptEcommerce'));
			return;
		} else {
			ret.EndNode = 'declined';
		}
		
	} else {
		ret.Order = null;
	}
	
	if(result.success || result.ResultStatusCheck == "RETRY") {
		ret.EndNode = 'success';
	} else if(result.ErrorStatus == "2") {
		ret.EndNode = 'declined';
	} else if(result.ErrorStatus == "1") {
		ret.EndNode = 'error';
	} else {
		ret.EndNode = 'canceled';
	}
	
	return ret;
}

/**
 * Create Order Number
 */
function CreateOrderNo(args) {

	var OrderNo = OrderMgr.createOrderNo();

	return OrderNo;
}

/**
 * Reset the forms of all Ecommerce payment methods, except the one of the current selected payment
 */
 
function ResetPaymentMethodsEcommerce(args) {
	var paymentProcessorID = libPayment.checkEcommercePaymentMethods(session.forms.billing.paymentMethods.selectedPaymentMethodID.value);
	var cart = app.getModel('Cart').get();
	
	if(paymentProcessorID == 'PAYMENT_ECOMMERCE' || paymentProcessorID == 'ECM_PPAL') {
		require('int_payment_controllers/cartridge/controllers/PAYMENT_DIRECT_DEBITS').ResetAllPaymentForms();
		Transaction.wrap(function () {
			session.forms.billing.paymentMethods.creditCard.clearFormElement();
			session.forms.billing.paymentMethods.bml.clearFormElement();
			cart.removePaymentInstruments(cart.getPaymentInstruments(dw.order.PaymentInstrument.METHOD_CREDIT_CARD));
			cart.removePaymentInstruments(cart.getPaymentInstruments(dw.order.PaymentInstrument.METHOD_BML));
		});
	}	
}

/**
 * Reset the forms of all Ecommerce payment methods
 */
function ResetAllPaymentForms(args) {
	var cart = app.getModel('Cart').get();
	var paymentInstruments = cart.getPaymentInstruments();
	
	for each(var paymentInstrument in paymentInstruments){
		var paymentProcessorID = libPayment.checkEcommercePaymentMethods(paymentInstrument.paymentMethod);
		if(paymentProcessorID == 'PAYMENT_ECOMMERCE' || paymentProcessorID == 'ECM_PPAL') {
			Transaction.wrap(function () {
				cart.removePaymentInstruments(cart.getPaymentInstruments(paymentInstrument.paymentMethod));
			});
		}
	}
}

/**
 * Mark orders failed , if ServerToServer request is used .
 */
function MarkOrdersFailed() {
	var order = OrderMgr.getOrder(parameterMap.orderNo.stringValue);
	var ShaCode = libPayment.createShaForUrls(order);
	
	if(ShaCode == parameterMap.tn.toString()){
		Transaction.wrap(function () {
			order.custom.failOrder = true;
		});
	}
    app.getView({}).render('markOrdersFailed');
}

/**
 * Accept Ecommerce Return Url
 */

function EcommAccept() {
	var res = CheckEcommercePayment();
	if(res.EndNode == 'success') {
		if(res.PaymentStatus != "41" && res.PaymentStatus != "5" && res.ResultStatusCheck != "RETRY"){
			Transaction.wrap(function () {
				res.Order.paymentStatus = dw.order.Order.PAYMENT_STATUS_PAID;
			});
		}
		SubmitImpl(res.Order, true);
	} else if(res.EndNode == 'error') {
		Transaction.wrap(function () {
			OrderMgr.failOrder(res.Order);
		});
	    app.getView({
	        Order: res.Order
		    }).render('ecommerceRedirectDecline');
	}
}

/**
 * Decline , Cancel Ecommerce Return Url
 */
function EcommDecline() {
	var res = CheckEcommercePayment();
	if(res.EndNode == 'success') {
		if(res.PaymentStatus != "41" && res.PaymentStatus != "5" && res.ResultStatusCheck != "RETRY"){
			Transaction.wrap(function () {
				res.Order.paymentStatus = dw.order.Order.PAYMENT_STATUS_PAID;
			});
		}
		SubmitImpl(res.Order, true);
	} else if(res.EndNode == 'error') {
		Transaction.wrap(function () {
			OrderMgr.failOrder(res.Order);
		});
	    app.getView({
	        Order: res.Order
	    }).render('ecommerceRedirectDecline');
	} else if(res.EndNode == 'canceled') {
		app.getView({
			Order: res.Order
		}).render('ecommerceRedirectCancel');
	} else if(res.EndNode == 'decline') {
		Transaction.wrap(function () {
			libPayment.ecommDecline(res.Order);
		});
	    app.getView({
	        Order: res.Order
	    }).render('ecommerceRedirectDecline');
	}
}

/**
 * Ecommerce ServerToServer
 */
function EcommServerToServer() {
	var res = CheckEcommercePayment({isS2S : true});
	if(res.EndNode == 'success') {
		if(res.PaymentStatus != "41" && res.PaymentStatus != "5" && res.ResultStatusCheck != "RETRY"){
			Transaction.wrap(function () {
				res.Order.paymentStatus = dw.order.Order.PAYMENT_STATUS_PAID;
			});
			SubmitImpl(res.Order, true);
		}
	} else if(res.EndNode == 'error') {
		Transaction.wrap(function () {
			OrderMgr.failOrder(res.Order);
		});
	    app.getView({
	        Order: res.Order
	    }).render('ecommerceRedirectDecline');
	} else if(res.EndNode == 'canceled') {
		app.getView({
			Order: res.Order
		}).render('ecommerceRedirectCancel');
	} else if(res.EndNode == 'decline') {
		Transaction.wrap(function () {
			libPayment.ecommDecline(res.Order);
		});
	    app.getView({
	        Order: res.Order
	    }).render('ecommerceRedirectDecline');
	}
}
 
/*
 * Export the private controller methods
 */

exports.CheckEcommercePayment = CheckEcommercePayment;
exports.CreateOrderNo = CreateOrderNo;
exports.ResetPaymentMethodsEcommerce = ResetPaymentMethodsEcommerce;
exports.ResetAllPaymentForms = ResetAllPaymentForms;

/*
 * Export the publicly available controller methods
 */

/** Mark orders failed , if ServerToServer request is used .
 * @see module:controllers/PAYMENT_ECOMMERCE~MarkOrdersFailed */
exports.MarkOrdersFailed = guard.ensure(['get'], MarkOrdersFailed);
/** Accept Ecommerce Return Url
 * @see module:controllers/PAYMENT_ECOMMERCE~EcommAccept */
exports.EcommAccept = guard.ensure(['https'], EcommAccept);
/** Decline Ecommerce Return Url
 * @see module:controllers/PAYMENT_ECOMMERCE~EcommDecline */
exports.EcommDecline = guard.ensure(['https'], EcommDecline);
/** Cancel Ecommerce Return Url
 * @see module:controllers/PAYMENT_ECOMMERCE~EcommCancel */
exports.EcommCancel = guard.ensure(['https'], EcommDecline);
/** Ecommerce ServerToServer
 * @see module:controllers/PAYMENT_ECOMMERCE~EcommServerToServer */
exports.EcommServerToServer = guard.ensure(['https'], EcommServerToServer);