/// <summary>
 /// Gets a value indicating whether payment workflow is required
 /// </summary>
 /// <param name="cart">Shopping cart</param>
 /// <param name="useRewardPoints">A value indicating reward points should be used; null to detect current choice of the customer</param>
 /// <returns>true - OK; false - minimum order total amount is not reached</returns>
 public bool IsPaymentWorkflowRequired(IList <ShoppingCartItem> cart, bool?useRewardPoints = null)
 {
     return(_orderProcessingService.IsPaymentWorkflowRequired(cart, useRewardPoints));
 }
        /// <summary>
        /// Prepare payment method model
        /// </summary>
        /// <param name="cart">Cart</param>
        /// <param name="filterByCountryId">Filter by country identifier</param>
        /// <returns>Payment method model</returns>
        public virtual CheckoutPaymentMethodModel PreparePaymentMethodModel(IList <ShoppingCartItem> cart, int filterByCountryId)
        {
            var model = new CheckoutPaymentMethodModel();

            //reward points
            if (_rewardPointsSettings.Enabled && !cart.IsRecurring())
            {
                int     rewardPointsBalance    = _rewardPointService.GetRewardPointsBalance(_workContext.CurrentCustomer.Id, _storeContext.CurrentStore.Id);
                decimal rewardPointsAmountBase = _orderTotalCalculationService.ConvertRewardPointsToAmount(rewardPointsBalance);
                decimal rewardPointsAmount     = _currencyService.ConvertFromPrimaryStoreCurrency(rewardPointsAmountBase, _workContext.WorkingCurrency);
                if (rewardPointsAmount > decimal.Zero &&
                    _orderTotalCalculationService.CheckMinimumRewardPointsToUseRequirement(rewardPointsBalance))
                {
                    model.DisplayRewardPoints = true;
                    model.RewardPointsAmount  = _priceFormatter.FormatPrice(rewardPointsAmount, true, false);
                    model.RewardPointsBalance = rewardPointsBalance;

                    //are points enough to pay for entire order? like if this option (to use them) was selected
                    model.RewardPointsEnoughToPayForOrder = !_orderProcessingService.IsPaymentWorkflowRequired(cart, true);
                }
            }

            //filter by country
            var paymentMethods = _paymentService
                                 .LoadActivePaymentMethods(_workContext.CurrentCustomer, _storeContext.CurrentStore.Id, filterByCountryId)
                                 .Where(pm => pm.PaymentMethodType == PaymentMethodType.Standard || pm.PaymentMethodType == PaymentMethodType.Redirection)
                                 .Where(pm => !pm.HidePaymentMethod(cart))
                                 .ToList();

            foreach (var pm in paymentMethods)
            {
                if (cart.IsRecurring() && pm.RecurringPaymentType == RecurringPaymentType.NotSupported)
                {
                    continue;
                }

                var pmModel = new CheckoutPaymentMethodModel.PaymentMethodModel
                {
                    Name                    = pm.GetLocalizedFriendlyName(_localizationService, _workContext.WorkingLanguage.Id),
                    Description             = _paymentSettings.ShowPaymentMethodDescriptions ? pm.PaymentMethodDescription : string.Empty,
                    PaymentMethodSystemName = pm.PluginDescriptor.SystemName,
                    LogoUrl                 = pm.PluginDescriptor.GetLogoUrl(_webHelper)
                };
                //payment method additional fee
                decimal paymentMethodAdditionalFee = _paymentService.GetAdditionalHandlingFee(cart, pm.PluginDescriptor.SystemName);
                decimal rateBase = _taxService.GetPaymentMethodAdditionalFee(paymentMethodAdditionalFee, _workContext.CurrentCustomer);
                decimal rate     = _currencyService.ConvertFromPrimaryStoreCurrency(rateBase, _workContext.WorkingCurrency);
                if (rate > decimal.Zero)
                {
                    pmModel.Fee = _priceFormatter.FormatPaymentMethodAdditionalFee(rate, true);
                }

                model.PaymentMethods.Add(pmModel);
            }

            //find a selected (previously) payment method
            var selectedPaymentMethodSystemName = _workContext.CurrentCustomer.GetAttribute <string>(
                SystemCustomerAttributeNames.SelectedPaymentMethod,
                _genericAttributeService, _storeContext.CurrentStore.Id);

            if (!String.IsNullOrEmpty(selectedPaymentMethodSystemName))
            {
                var paymentMethodToSelect = model.PaymentMethods.ToList()
                                            .Find(pm => pm.PaymentMethodSystemName.Equals(selectedPaymentMethodSystemName, StringComparison.InvariantCultureIgnoreCase));
                if (paymentMethodToSelect != null)
                {
                    paymentMethodToSelect.Selected = true;
                }
            }
            //if no option has been selected, let's do it for the first one
            if (model.PaymentMethods.FirstOrDefault(so => so.Selected) == null)
            {
                var paymentMethodToSelect = model.PaymentMethods.FirstOrDefault();
                if (paymentMethodToSelect != null)
                {
                    paymentMethodToSelect.Selected = true;
                }
            }

            return(model);
        }
        public IActionResult ParatikaPaymentInfo(PaymentInfoModel model)
        {
            Dictionary <String, String> requestParameters = new Dictionary <String, String>();
            var processPaymentRequest = new ProcessPaymentRequest();
            var processGuid           = Guid.NewGuid().ToString();

            if (_orderSettings.CheckoutDisabled)
            {
                return(RedirectToRoute("ShoppingCart"));
            }

            var cart = _workContext.CurrentCustomer.ShoppingCartItems
                       .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
                       .LimitPerStore(_storeContext.CurrentStore.Id)
                       .ToList();

            if (!cart.Any())
            {
                return(RedirectToRoute("ShoppingCart"));
            }

            if (_orderSettings.OnePageCheckoutEnabled)
            {
                return(RedirectToRoute("CheckoutOnePage"));
            }

            if (_workContext.CurrentCustomer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed)
            {
                return(Challenge());
            }

            //Check whether payment workflow is required
            var isPaymentWorkflowRequired = _orderProcessingService.IsPaymentWorkflowRequired(cart);

            if (!isPaymentWorkflowRequired)
            {
                return(RedirectToRoute("CheckoutConfirm"));
            }

            //load payment method
            var paymentMethodSystemName = _genericAttributeService.GetAttribute <string>(_workContext.CurrentCustomer,
                                                                                         NopCustomerDefaults.SelectedPaymentMethodAttribute, _storeContext.CurrentStore.Id);
            var paymentMethod = _paymentService.LoadPaymentMethodBySystemName(paymentMethodSystemName);

            if (paymentMethod == null)
            {
                return(RedirectToRoute("CheckoutPaymentMethod"));
            }

            string sessionTokenValue = _session.Get <string>("SESSIONTOKEN_" + _workContext.CurrentCustomer.Id);

            //if prataka is not active, you get payment with HP Interface.
            if (_paratikaOrderPaymentSettings.PaymentHPMethod)
            {
                //used main url set value only with hp method
                var orderGuid = _session.Get <string>("MERCHANTPAYMENTID_" + _workContext.CurrentCustomer.Id);
                processPaymentRequest.OrderGuid = Guid.Parse(orderGuid);
                HttpContext.Session.Set <ProcessPaymentRequest>("OrderPaymentInfo", processPaymentRequest);
                model.PaymentHPMethodURL = _paratikaOrderPaymentSettings.PaymentHPMethodURL + sessionTokenValue;
                return(Json(model));
            }

            if (!string.IsNullOrWhiteSpace(sessionTokenValue))
            {
                model.SessionToken = sessionTokenValue;
                return(View("~/Plugins/Payments.Paratika/Views/PaymentInfo.cshtml", model));
            }
            else
            {
                _logger.Information(" > SESSIONTOKEN operation is FAILED, please check the error codes.");
                model.Error = _localizationService.GetResource("Plugins.Payments.Paratika.Fields.Error");
                return(View("~/Plugins/Payments.Paratika/Views/PaymentInfo.cshtml", model));
            }
        }