public ActionResult IPNHandler()
        {
            byte[] param      = Request.BinaryRead(Request.ContentLength);
            string strRequest = Encoding.ASCII.GetString(param);
            Dictionary <string, string> values;

            var processor = _paymentService.LoadPaymentMethodBySystemName("Payments.GTpay") as GTpayPaymentProcessor;

            if (processor == null ||
                !processor.IsPaymentMethodActive(_paymentSettings) || !processor.PluginDescriptor.Installed)
            {
                throw new NopException("GTPAY Standard module cannot be loaded");
            }

            if (processor.VerifyIpn(strRequest, out values))
            {
                #region values
                decimal mc_gross = decimal.Zero;
                try
                {
                    mc_gross = decimal.Parse(values["mc_gross"], new CultureInfo("en-US"));
                }
                catch { }

                string payer_status = string.Empty;
                values.TryGetValue("payer_status", out payer_status);
                string payment_status = string.Empty;
                values.TryGetValue("payment_status", out payment_status);
                string pending_reason = string.Empty;
                values.TryGetValue("pending_reason", out pending_reason);
                string mc_currency = string.Empty;
                values.TryGetValue("mc_currency", out mc_currency);
                string txn_id = string.Empty;
                values.TryGetValue("txn_id", out txn_id);
                string txn_type = string.Empty;
                values.TryGetValue("txn_type", out txn_type);
                string rp_invoice_id = string.Empty;
                values.TryGetValue("rp_invoice_id", out rp_invoice_id);
                string payment_type = string.Empty;
                values.TryGetValue("payment_type", out payment_type);
                string payer_id = string.Empty;
                values.TryGetValue("payer_id", out payer_id);
                string receiver_id = string.Empty;
                values.TryGetValue("receiver_id", out receiver_id);
                string invoice = string.Empty;
                values.TryGetValue("invoice", out invoice);
                string payment_fee = string.Empty;
                values.TryGetValue("payment_fee", out payment_fee);

                #endregion

                var sb = new StringBuilder();
                sb.AppendLine("GTPay IPN:");
                foreach (KeyValuePair <string, string> kvp in values)
                {
                    sb.AppendLine(kvp.Key + ": " + kvp.Value);
                }

                var newPaymentStatus = GTpayHelper.GetPaymentStatus(payment_status, pending_reason);
                sb.AppendLine("New payment status: " + newPaymentStatus);

                switch (txn_type)
                {
                case "recurring_payment_profile_created":
                    //do nothing here
                    break;

                case "recurring_payment":
                    #region Recurring payment
                {
                    Guid orderNumberGuid = Guid.Empty;
                    try
                    {
                        orderNumberGuid = new Guid(rp_invoice_id);
                    }
                    catch
                    {
                    }

                    var initialOrder = _orderService.GetOrderByGuid(orderNumberGuid);
                    if (initialOrder != null)
                    {
                        var recurringPayments = _orderService.SearchRecurringPayments(initialOrderId: initialOrder.Id);
                        foreach (var rp in recurringPayments)
                        {
                            switch (newPaymentStatus)
                            {
                            case PaymentStatus.Authorized:
                            case PaymentStatus.Paid:
                            {
                                var recurringPaymentHistory = rp.RecurringPaymentHistory;
                                if (recurringPaymentHistory.Count == 0)
                                {
                                    //first payment
                                    var rph = new RecurringPaymentHistory
                                    {
                                        RecurringPaymentId = rp.Id,
                                        OrderId            = initialOrder.Id,
                                        CreatedOnUtc       = DateTime.UtcNow
                                    };
                                    rp.RecurringPaymentHistory.Add(rph);
                                    _orderService.UpdateRecurringPayment(rp);
                                }
                                else
                                {
                                    //next payments
                                    _orderProcessingService.ProcessNextRecurringPayment(rp);
                                }
                            }
                            break;
                            }
                        }

                        //this.OrderService.InsertOrderNote(newOrder.OrderId, sb.ToString(), DateTime.UtcNow);
                        _logger.Information("GTPAY IPN. Recurring info", new NopException(sb.ToString()));
                    }
                    else
                    {
                        _logger.Error("GTPAY IPN. Order is not found", new NopException(sb.ToString()));
                    }
                }
                    #endregion
                    break;

                default:
                    #region Standard payment
                {
                    string orderNumber = string.Empty;
                    values.TryGetValue("custom", out orderNumber);
                    Guid orderNumberGuid = Guid.Empty;
                    try
                    {
                        orderNumberGuid = new Guid(orderNumber);
                    }
                    catch
                    {
                    }

                    var order = _orderService.GetOrderByGuid(orderNumberGuid);
                    if (order != null)
                    {
                        //order note
                        order.OrderNotes.Add(new OrderNote
                            {
                                Note = sb.ToString(),
                                DisplayToCustomer = false,
                                CreatedOnUtc      = DateTime.UtcNow
                            });
                        _orderService.UpdateOrder(order);

                        switch (newPaymentStatus)
                        {
                        case PaymentStatus.Pending:
                        {
                        }
                        break;

                        case PaymentStatus.Authorized:
                        {
                            if (_orderProcessingService.CanMarkOrderAsAuthorized(order))
                            {
                                _orderProcessingService.MarkAsAuthorized(order);
                            }
                        }
                        break;

                        case PaymentStatus.Paid:
                        {
                            if (_orderProcessingService.CanMarkOrderAsPaid(order))
                            {
                                order.AuthorizationTransactionId = txn_id;
                                _orderService.UpdateOrder(order);

                                _orderProcessingService.MarkOrderAsPaid(order);
                            }
                        }
                        break;

                        case PaymentStatus.Refunded:
                        {
                            var totalToRefund = Math.Abs(mc_gross);
                            if (totalToRefund > 0 && Math.Round(totalToRefund, 2).Equals(Math.Round(order.OrderTotal, 2)))
                            {
                                //refund
                                if (_orderProcessingService.CanRefundOffline(order))
                                {
                                    _orderProcessingService.RefundOffline(order);
                                }
                            }
                            else
                            {
                                //partial refund
                                if (_orderProcessingService.CanPartiallyRefundOffline(order, totalToRefund))
                                {
                                    _orderProcessingService.PartiallyRefundOffline(order, totalToRefund);
                                }
                            }
                        }
                        break;

                        case PaymentStatus.Voided:
                        {
                            if (_orderProcessingService.CanVoidOffline(order))
                            {
                                _orderProcessingService.VoidOffline(order);
                            }
                        }
                        break;

                        default:
                            break;
                        }
                    }
                    else
                    {
                        _logger.Error("GTPAY IPN. Order is not found", new NopException(sb.ToString()));
                    }
                }
                    #endregion
                    break;
                }
            }
            else
            {
                _logger.Error("GTPAY IPN failed.", new NopException(strRequest));
            }

            //nothing should be rendered to visitor
            return(Content(""));
        }
        public ActionResult PDTHandler(FormCollection form)
        {
            var tx = _webHelper.QueryString <string>("txid");
            Dictionary <string, string> values;
            //string response;

            var processor = _paymentService.LoadPaymentMethodBySystemName("Payments.GTpay") as GTpayPaymentProcessor;

            if (processor == null ||
                !processor.IsPaymentMethodActive(_paymentSettings) || !processor.PluginDescriptor.Installed)
            {
                throw new NopException("Gtpay module cannot be loaded");
            }



            var orderNref = tx.Split('|');

            string orderGuid = orderNref[0].Trim();
            string orderid   = orderNref[1];

            Guid orderNumberGuid = System.Guid.Empty;

            try
            {
                orderNumberGuid = new Guid(orderGuid);
            }
            catch { }
            Order order = _orderService.GetOrderByGuid(orderNumberGuid);

            if (order != null)
            {
                var actualTotal = order.OrderTotal;
                //actualTotal = actualTotal + SiteConfiguration.BookingFee;
                var amt          = actualTotal.ToString("0.00");
                var final        = amt.Split('.');
                var postedAmount = final[0] + final[1];

                var hash = _GTpayPaymentSettings.MerchantID + tx + _GTpayPaymentSettings.HashCode;
                hash = Hash.GetHashMini(hash, Hash.HashType.SHA512);            // GetSHA512(hash);

                var response = processor.InterSwitchResponse(tx, postedAmount, hash);


                if (response.ResponseCode == "00")
                {
                    decimal mc_gross = decimal.Zero;
                    try
                    {
                        mc_gross = decimal.Parse(response.Amount, new CultureInfo("en-US"));
                        mc_gross = mc_gross / 100;
                    }
                    catch (Exception exc)
                    {
                        _logger.Error("GTpay. Error getting Ammount paid", exc);
                    }

                    string payer_status = processor.ErrorCodeToString(response.ResponseCode);
                    //values.TryGetValue("payer_status", out payer_status);
                    string payment_status = response.ResponseCode;
                    //values.TryGetValue("payment_status", out payment_status);
                    string pending_reason = response.ResponseDescription;
                    //values.TryGetValue("pending_reason", out pending_reason);
                    //string mc_currency = string.Empty;
                    ///values.TryGetValue("mc_currency", out mc_currency);
                    string txn_id = tx;
                    //values.TryGetValue("txn_id", out txn_id);
                    string payment_type = response.MerchantReference;
                    //values.TryGetValue("payment_type", out payment_type);
                    string payer_id = response.MertID;
                    //values.TryGetValue("payer_id", out payer_id);
                    //string receiver_id = string.Empty;
                    //values.TryGetValue("receiver_id", out receiver_id);
                    //string invoice = string.Empty;
                    //values.TryGetValue("invoice", out invoice);
                    string payment_fee = response.Amount;
                    //values.TryGetValue("payment_fee", out payment_fee);

                    var sb = new StringBuilder();
                    sb.AppendLine("GTpay PDT:");
                    sb.AppendLine("amount: " + mc_gross);
                    sb.AppendLine("Payer status: " + payer_status);
                    sb.AppendLine("Payment status: " + payment_status);
                    sb.AppendLine("Pending reason: " + pending_reason);
                    //sb.AppendLine("mc_currency: " + mc_currency);
                    sb.AppendLine("txn_id: " + txn_id);
                    sb.AppendLine("MerchantReference: " + payment_type);
                    sb.AppendLine("payer_id: " + payer_id);
                    //sb.AppendLine("receiver_id: " + receiver_id);
                    //sb.AppendLine("invoice: " + invoice);
                    sb.AppendLine("returned_ammount: " + payment_fee);

                    var newPaymentStatus = GTpayHelper.GetPaymentStatus(payment_status, pending_reason);
                    sb.AppendLine("New payment status: " + newPaymentStatus);

                    //order note
                    order.OrderNotes.Add(new OrderNote
                    {
                        Note = sb.ToString(),
                        DisplayToCustomer = false,
                        CreatedOnUtc      = DateTime.UtcNow
                    });
                    _orderService.UpdateOrder(order);

                    //load settings for a chosen store scope
                    var storeScope           = this.GetActiveStoreScopeConfiguration(_storeService, _workContext);
                    var GTpayPaymentSettings = _settingService.LoadSetting <GTpayPaymentSettings>(storeScope);

                    //validate order total
                    if (GTpayPaymentSettings.PdtValidateOrderTotal && !Math.Round(mc_gross, 2).Equals(Math.Round(order.OrderTotal, 2)))
                    {
                        string errorStr = string.Format("Returned order total {0} doesn't equal order total {1}", mc_gross, order.OrderTotal);
                        _logger.Error(errorStr);

                        return(RedirectToAction("Index", "Home", new { area = "" }));
                    }

                    //mark order as paid
                    if (newPaymentStatus == PaymentStatus.Paid)
                    {
                        if (_orderProcessingService.CanMarkOrderAsPaid(order))
                        {
                            order.AuthorizationTransactionId = response.MerchantReference;
                            _orderService.UpdateOrder(order);

                            _orderProcessingService.MarkOrderAsPaid(order);
                        }
                    }

                    return(RedirectToRoute("CheckoutCompleted", new { orderId = order.Id }));
                }
                else
                {
                    if (order != null)
                    {
                        //order note
                        order.OrderNotes.Add(new OrderNote
                        {
                            Note = "Gtpay PDT failed.",
                            DisplayToCustomer = false,
                            CreatedOnUtc      = DateTime.UtcNow
                        });
                        _orderService.UpdateOrder(order);
                    }
                    return(RedirectToAction("Index", "Home", new { area = "" }));
                }
            }
            else
            {
                return(RedirectToAction("Index", "Home", new { area = "" }));
            }
        }