public ActionResult IPN(string orderGuid)
        {
            Request.InputStream.Position = 0;
            var content = new StreamReader(Request.InputStream).ReadToEnd();

            var state = repository.GetPurchaseState(orderGuid);

            if (state != null)
            {
                var api = new PaysonApi(state.UserId, state.UserKey, ApplicationId, true);
                var response = api.MakeValidateIpnContentRequest(content);
                if (response.Success)
                {
                    var status = response.ProcessedIpnMessage.PaymentStatus.HasValue
                                     ? response.ProcessedIpnMessage.PaymentStatus.ToString()
                                     : "N/A";
                    state.Updates[DateTime.Now] = "IPN: " + status;
                    state.LatestStatus = status;
                }
                else
                {
                    state.Updates[DateTime.Now] = "IPN: IPN Failure";
                    state.LatestStatus = "Failure";

                }
            }

            return new EmptyResult();
        }
        public ActionResult Pay(PayViewModel payViewModel)
        {
            var orderGuid = Guid.NewGuid().ToString();

            // We remove port info to help when the site is behind a load balancer/firewall that does port rewrites.
            var scheme = Request.Url.Scheme;
            var host = Request.Url.Host;
            var oldPort = Request.Url.Port.ToString();
            var returnUrl = Url.Action("Returned", "Checkout", new RouteValueDictionary(), scheme, host).Replace(oldPort, "") + "?orderGuid=" + orderGuid;

            var cancelUrl = Url.Action("Cancelled", "Checkout", new RouteValueDictionary(), scheme, host).Replace(oldPort, "");

            // When the shop is hosted by Payson the IPN scheme must be http and not https
            var ipnNotificationUrl = Url.Action("IPN", "Checkout", new RouteValueDictionary(), "http", host).Replace(oldPort, "") + "?orderGuid=" + orderGuid;

            var sender = new PaysonIntegration.Utils.Sender(payViewModel.Sender.Email);
            sender.SetFirstName(payViewModel.Sender.FirstName);
            sender.SetLastName(payViewModel.Sender.LastName);

            var totalAmount = payViewModel.OrderItems.Sum(o => o.UnitPrice * o.Quantity * (1 + o.TaxPercentage));

            var receiver = new PaysonIntegration.Utils.Receiver(payViewModel.Receiver.Email, totalAmount);
            receiver.SetFirstName(payViewModel.Receiver.FirstName);
            receiver.SetLastName(payViewModel.Receiver.LastName);
            receiver.SetPrimaryReceiver(true);

            var payData = new PayData(returnUrl, cancelUrl, payViewModel.Memo, sender,
                                      new List<PaysonIntegration.Utils.Receiver> { receiver });

            switch (payViewModel.GuaranteeOffered)
            {
                case GuaranteeOffered.NO:
                    payData.GuaranteeOffered = PaysonIntegration.Utils.GuaranteeOffered.No;
                    break;
                case GuaranteeOffered.OPTIONAL:
                    payData.GuaranteeOffered = PaysonIntegration.Utils.GuaranteeOffered.Optional;
                    break;
                case GuaranteeOffered.REQUIRED:
                    payData.GuaranteeOffered = PaysonIntegration.Utils.GuaranteeOffered.Required;
                    break;
                default:
                    payData.GuaranteeOffered = null;
                    break;
            }

            payData.SetCurrencyCode(payViewModel.CurrencyCode);
            var fundingConstraints = new List<FundingConstraint>();
            if (payViewModel.PaymentMethod == PaymentMethod.PaysonInvoice)
            {
                fundingConstraints.Add(FundingConstraint.Invoice);
            }
            else
            {
                fundingConstraints.Add(FundingConstraint.Bank);
                fundingConstraints.Add(FundingConstraint.CreditCard);
            }

            payData.SetFundingConstraints(fundingConstraints);

            payData.SetInvoiceFee(payViewModel.InvoiceFee);
            payData.SetIpnNotificationUrl(ipnNotificationUrl);
            payData.SetLocaleCode(payViewModel.LocaleCode);
            var orderItems = new List<PaysonIntegration.Utils.OrderItem>();
            foreach (var orderModel in payViewModel.OrderItems)
            {
                var oi = new PaysonIntegration.Utils.OrderItem(orderModel.Description);
                oi.SetOptionalParameters(orderModel.Sku, orderModel.Quantity, orderModel.UnitPrice, orderModel.TaxPercentage);
                orderItems.Add(oi);
            }
            payData.SetOrderItems(orderItems);
            payData.SetTrackingId(orderGuid);

            var api = new PaysonApi(payViewModel.UserId, payViewModel.UserKey, ApplicationId, true);

            var response = api.MakePayRequest(payData);

            if (response.Success)
            {
                var state = new PurchaseState
                                {
                                    UserId = payViewModel.UserId,
                                    UserKey = payViewModel.UserKey,
                                    Token = response.Token,
                                    Updates = new Dictionary<DateTime, string> {{DateTime.Now, "Created"}},
                                    OrderGuid = orderGuid,
                                    LatestStatus = PaymentStatus.Created.ToString(),
                                    ReceiverEmail = receiver.Email,
                                };

                repository.SavePurchaseState(state);

                string forwardUrl =
                    string.IsNullOrWhiteSpace(payViewModel.ForwardUrl)
                        ? api.GetForwardPayUrl(response.Token)
                        : payViewModel.ForwardUrl + response.Token;

                return Redirect(forwardUrl);
            }
            ViewBag.Errors = response.ErrorMessages;

            return View("Index", GetDefaultPayViewModel());
        }
        public ActionResult Returned(string orderGuid)
        {
            var state = repository.GetPurchaseState(orderGuid);

            if (state != null)
            {
                var api = new PaysonApi(state.UserId, state.UserKey, ApplicationId, true);
                var response = api.MakePaymentDetailsRequest(new PaymentDetailsData(state.Token));

                if (response.Success)
                {
                    var status = response.PaymentDetails.PaymentStatus.HasValue
                                     ? response.PaymentDetails.PaymentStatus.ToString()
                                     : "N/A";
                    state.Updates[DateTime.Now] = "ReturnUrl: " + status;
                    state.LatestStatus = status;
                }
                else
                {
                    ViewBag.Errors = response.ErrorMessages;
                    return View("Index", GetDefaultPayViewModel());
                }
            }

            return View("Result", state);
        }
        public ActionResult Returned(string regId)
        {
            int registrationId = -1;

            log.Debug("Returned");

            if (!string.IsNullOrEmpty(regId) && !int.TryParse(regId, out registrationId))
            {
                ShowError("regId not in querystring at checkout returned.");
            }

            var registration = db.Registreringar.FirstOrDefault(regg => regg.ID == registrationId);

            if (registration == null)
            {
                ShowError("No registration found in db with id: " + registrationId + " in checkout returned.");
            }

            log.Debug("Returned. Lagnamn: " + registration.Lagnamn);

            // If no payment message has been sent (IPN)
            if (!registration.HarBetalt)
            {
                var api = new PaysonApi(CheckoutModel.PaysonUserId, CheckoutModel.PaysonUserKey);
            #if DEBUG
                api = new PaysonApi("4", "2acab30d-fe50-426f-90d7-8c60a7eb31d4", ApplicationId, true);
            #endif
                var response = api.MakePaymentDetailsRequest(new PaymentDetailsData(registration.PaysonToken));

                if (response.Success && (response.PaymentDetails.PaymentStatus == PaymentStatus.Completed ||
                                        response.PaymentDetails.PaymentStatus == PaymentStatus.Pending))
                {
                    if (!registration.HarBetalt)
                    {
                        SetAsPaid(registration);
                    }
                }
                else
                {
                    log.Warn("Deleting temp-registration with id: " + registrationId);
                    // Remove the temporary registration
                    DeleteRegistrering(registrationId);

                    return ShowPaymentError("Error when payment returned.", response.NvpContent, registration);
                }
            }

            return RedirectToAction("Redirect", "Home");
        }
        public ActionResult Pay()
        {
            try
            {
                var checkout = (CheckoutModel)Session["checkout"];

                if (checkout == null || checkout.Registrering == null)
                {
                    return ShowError("Missing data, checkout or checkout.Registrering is null at Pay()");
                }

                log.Debug("Checkout, pay. Lagnamn: " + checkout.Registrering.Lagnamn);

                SaveNewRegistration(checkout.Registrering);
                FillRegistrering(checkout.Registrering);

                checkout.RegId = checkout.Registrering.ID;

                // We remove port info to help when the site is behind a load balancer/firewall that does port rewrites.
                var scheme = Request.Url.Scheme;
                var host = Request.Url.Host;
                //var oldPort = Request.Url.Port.ToString();
                var returnUrl = Url.Action("Returned", "Checkout", new RouteValueDictionary(), scheme, host)/*.Replace(oldPort, "")*/ + "?regId=" + checkout.RegId;

                var cancelUrl = Url.Action("Cancelled", "Checkout", new RouteValueDictionary(), scheme, host)/*.Replace(oldPort, "")*/;

                var sender = new Sender(checkout.SenderEmail);
                sender.FirstName = checkout.SenderFirstName;
                sender.LastName = checkout.SenderLastName;

                var totalAmount = Avgift.Kalk(checkout.Registrering);

                var receiver = new Receiver(CheckoutModel.PaysonRecieverEmail, totalAmount);
                receiver.FirstName = CheckoutModel.PaysonRecieverFirstName;
                receiver.LastName = CheckoutModel.PaysonRecieverLastName;
                receiver.SetPrimaryReceiver(true);

                var payData = new PayData(returnUrl, cancelUrl, "Utmaningen 2014 - " + checkout.Registrering.Lagnamn, sender, new List<Receiver> { receiver });

                // Set IPN callback URL
                // When the shop is hosted by Payson the IPN scheme must be http and not https
                var ipnNotificationUrl = Url.Action("IPN", "Checkout", new RouteValueDictionary(), scheme, host)/*.Replace(oldPort, "")*/ + "?regId=" + checkout.RegId;
                payData.SetIpnNotificationUrl(ipnNotificationUrl);

                payData.SetFundingConstraints(new List<FundingConstraint> { FundingConstraint.Bank, FundingConstraint.CreditCard });
                payData.SetTrackingId(checkout.Registrering.ID.ToString());

                var orderItems = new List<PaysonIntegration.Utils.OrderItem>();
                var reg = checkout.Registrering;
                // Lägg in värden på kvitto
                var oi1 = new PaysonIntegration.Utils.OrderItem("Utmaningen " + DateTime.Now.Year + ", bana " + reg.Banor.Namn);
                oi1.SetOptionalParameters("st", 1, reg.Banor.Avgift, 0);
                orderItems.Add(oi1);
                if (reg.Kanoter.Avgift != 0)
                {
                    var oi2 = new PaysonIntegration.Utils.OrderItem("Kanot, " + reg.Kanoter.Namn);
                    oi2.SetOptionalParameters("st", 1, (decimal)reg.Kanoter.Avgift, 0);
                    orderItems.Add(oi2);
                }
                if (reg.Forseningsavgift != 0)
                {
                    var oi3 = new PaysonIntegration.Utils.OrderItem("Avgift för sen anmälan");
                    oi3.SetOptionalParameters("st", 1, (decimal)reg.Forseningsavgift, 0);
                    orderItems.Add(oi3);
                }
                if (reg.Rabatt != 0)
                {
                    var oi4 = new PaysonIntegration.Utils.OrderItem("Rabatt");
                    oi4.SetOptionalParameters("st", 1, -(decimal)reg.Rabatt, 0);
                    orderItems.Add(oi4);
                }
                payData.SetOrderItems(orderItems);

                var api = new PaysonApi(CheckoutModel.PaysonUserId, CheckoutModel.PaysonUserKey, ApplicationId, false);
            #if DEBUG
                api = new PaysonApi("4", "2acab30d-fe50-426f-90d7-8c60a7eb31d4", ApplicationId, true);
            #endif

                var response = api.MakePayRequest(payData);

                if (response.Success)
                {
                    checkout.Token = response.Token;
                    checkout.Registrering.PaysonToken = response.Token;
                    SaveChanges(checkout.Registrering);

                    var forwardUrl = api.GetForwardPayUrl(response.Token);

                    Session["checkout"] = checkout;

                    return Redirect(forwardUrl);
                }

                return ShowPaymentError("Error when sending payment to payson.", response.NvpContent, checkout.Registrering);
            }
            catch (Exception exception)
            {
                log.Error("Exception in pay.", exception);
                return ShowError("Error in Pay().", exception);
            }
        }
        public ActionResult IPN(string regId)
        {
            log.Debug("IPN regId: " + regId);

            int regIdInt = -1;
            int.TryParse(regId, out regIdInt);

            var registration = db.Registreringar.FirstOrDefault(regg => regg.ID == regIdInt);

            if (registration != null)
            {
                Request.InputStream.Position = 0;
                var content = new StreamReader(Request.InputStream).ReadToEnd();

                var api = new PaysonApi(CheckoutModel.PaysonUserId, CheckoutModel.PaysonUserKey, ApplicationId, true);
                var response = api.MakeValidateIpnContentRequest(content);
                var statusText = response.ProcessedIpnMessage.PaymentStatus.HasValue
                                    ? response.ProcessedIpnMessage.PaymentStatus.ToString()
                                    : "N/A";
                var status = response.ProcessedIpnMessage.PaymentStatus;

                log.Debug("IPN message content: " + response.Content);
                log.Debug("IPN raw response: " + content);

                if (status == PaymentStatus.Completed || status == PaymentStatus.Completed)
                {
                    log.Debug("IPN message, status: " + statusText + ". regId: " + regId + " success: " + response.Success);

                    if (!registration.HarBetalt)
                    {
                        SetAsPaid(registration);
                    }
                }
                else
                {
                    log.Debug("IPN message for non complete transaction. regId: " + regId + ". Status: " + statusText);
                }
            }
            else
            {
                log.Error("Got IPN with wrong regId as query parameter: " + regId);
                SendMail.SendErrorMessage("Got IPN with wrong regId as query parameter: " + regId);
            }

            return new EmptyResult();
        }
        public JsonResult Validate(ValidateViewModel validateViewModel)
        {
            var api = new PaysonApi(validateViewModel.UserId, validateViewModel.UserKey, ApplicationId, true);
            var response = api.MakeAccountDetailsRequest();

            if (response.Success)
            {
                return Json(new { success = true, accountEmail = response.AccountDetails.AccountEmail, enabledForInvoice = response.AccountDetails.EnabledForInvoice, enabledForPaymentPlan = response.AccountDetails.EnabledForPaymentPlan}, JsonRequestBehavior.AllowGet);
            }
            return Json(new { success = false, error="Wrong credentials" }, JsonRequestBehavior.AllowGet);
        }