public async Task<ActionResult> ExternalPaymentCallback()
        {
            var parameters = new List<KeyValuePair<string, string>>();

            foreach (var key in HttpContext.Request.QueryString.AllKeys)
            {
                parameters.Add(new KeyValuePair<string, string>(key, HttpContext.Request.QueryString[key]));
            }

            var postPaymentResult = await Service.PostPaymentProcessAsync(parameters);

            if (postPaymentResult != null)
            {
                if (postPaymentResult.IsSuccess)
                {
                    string orderId = HttpContext.Request.QueryString["orderId"];

                    var order = await CustomerService.GetOrderAsync(Context.StoreId, Context.CustomerId, orderId);

                    if (order != null)
                    {
                        var productsIds = order.Items.Select(i => i.ProductId);
                        var catalogItems = await Service.GetCatalogItemsByIdsAsync(productsIds, "ItemAssets");

                        var nonShippingProducts = catalogItems.Where(ci => ci.ProductType == "Digital");
                        if (nonShippingProducts.Count() > 0)
                        {
                            var downloadLinks = new List<ProductDownloadLinks>();

                            foreach (var nonShippingProduct in nonShippingProducts)
                            {
                                var productLinks = new ProductDownloadLinks
                                {
                                    ProductName = nonShippingProduct.Name
                                };

                                int linkCount = 1;
                                foreach (var asset in nonShippingProduct.Assets)
                                {
                                    var url = Url.Action("Index", "Download", new { @file = asset.Name, @oid = order.Id, @pid = nonShippingProduct.Id }, Request.Url.Scheme);
                                    productLinks.Links.Add(new DownloadLink
                                    {
                                        Filename = asset.Name,
                                        Text = nonShippingProduct.Assets.Count() > 1 ? String.Format("Download link {0}", linkCount) : "Download link",
                                        Url = url
                                    });

                                    linkCount++;
                                }

                                downloadLinks.Add(productLinks);
                            }

                            Context.Set("download_links", downloadLinks);
                        }

                        Context.Order = order.AsWebModel();
                        return View("thanks_page");
                    }
                }
                else
                {
                    Context.ErrorMessage = postPaymentResult.Error;
                    return View("error");
                }
            }

            return View("error");
        }
        public async Task<ActionResult> Step2(CheckoutSecondStepFormModel formModel)
        {
            var form = GetForm(formModel.form_type);

            if (form != null)
            {
                var formErrors = GetFormErrors(ModelState);

                if (formErrors == null)
                {
                    var checkout = await Service.GetCheckoutAsync();

                    if (!checkout.RequiresShipping)
                    {
                        checkout.Email = formModel.Email;
                    }

                    var billingAddress = new CustomerAddress
                    {
                        Address1 = formModel.Address1,
                        Address2 = !string.IsNullOrEmpty(formModel.Address2) ? formModel.Address2 : null,
                        City = formModel.City,
                        Company = !string.IsNullOrEmpty(formModel.Company) ? formModel.Company : null,
                        Country = formModel.Country,
                        CountryCode = "US", //TODO Set country code by selected country name
                        FirstName = formModel.FirstName,
                        LastName = formModel.LastName,
                        Phone = !string.IsNullOrEmpty(formModel.Phone) ? formModel.Phone : null,
                        Province = formModel.Province,
                        ProvinceCode = "CA", //TODO Set province code by selected province name
                        Zip = formModel.Zip
                    };

                    checkout.BillingAddress = billingAddress;

                    checkout.ShippingMethods = await Service.GetShippingMethodsAsync(checkout.Id);
                    checkout.PaymentMethods = await Service.GetCartPaymentMethodsAsync(checkout.Id);

                    if (checkout.RequiresShipping)
                    {
                        checkout.ShippingMethod = checkout.ShippingMethods.FirstOrDefault(sm => sm.Handle == formModel.ShippingMethodId);
                    }

                    checkout.PaymentMethod = checkout.PaymentMethods.FirstOrDefault(pm => pm.Code == formModel.PaymentMethodId);
                    if (checkout.PaymentMethod.Type.Equals("Standard", StringComparison.OrdinalIgnoreCase))
                    {
                        checkout.PaymentMethod.CardNumber = formModel.CardNumber;
                        checkout.PaymentMethod.CardExpirationMonth = formModel.CardExpirationMonth;
                        checkout.PaymentMethod.CardExpirationYear = formModel.CardExpirationYear;
                        checkout.PaymentMethod.CardCvv = formModel.CardCvv;
                    }

                    if (User.Identity.IsAuthenticated)
                    {
                        var customer = await CustomerService.GetCustomerAsync(checkout.Email, Context.Shop.StoreId);
                        if (customer != null)
                        {
                            customer.Addresses.Add(billingAddress);
                            await this.CustomerService.UpdateCustomerAsync(customer);
                        }
                    }

                    await Service.UpdateCheckoutAsync(checkout);

                    var dtoOrder = await Service.CreateOrderAsync();

                    checkout.Order = dtoOrder.AsWebModel();
                    Context.Checkout = checkout;

                    var inPayment = dtoOrder.InPayments.FirstOrDefault(); // For test

                    if (inPayment != null)
                    {
                        VirtoCommerce.ApiClient.DataContracts.ProcessPaymentResult paymentResult = null;

                        if (checkout.PaymentMethod.Type.Equals("Standard"))
                        {
                            string cardType = GetCreditCardType(formModel.CardNumber);

                            if (!String.IsNullOrEmpty(cardType))
                            {
                                var cardInfo = new ApiClient.DataContracts.BankCardInfo
                                {
                                    BankCardCVV2 = formModel.CardCvv,
                                    BankCardMonth = int.Parse(formModel.CardExpirationMonth),
                                    BankCardNumber = formModel.CardNumber,
                                    BankCardType = cardType,
                                    BankCardYear = int.Parse(formModel.CardExpirationYear)
                                };

                                paymentResult = await Service.ProcessPaymentAsync(dtoOrder.Id, inPayment.Id, cardInfo);
                            }
                        }
                        else
                        {
                            paymentResult = await Service.ProcessPaymentAsync(dtoOrder.Id, inPayment.Id, null);
                        }

                        if (paymentResult != null)
                        {
                            if (paymentResult != null)
                            {
                                if (paymentResult.IsSuccess)
                                {
                                    if (paymentResult.PaymentMethodType == ApiClient.DataContracts.PaymentMethodType.Redirection)
                                    {
                                        if (!string.IsNullOrEmpty(paymentResult.RedirectUrl))
                                        {
                                            return Redirect(paymentResult.RedirectUrl);
                                        }
                                    }
                                    if (paymentResult.PaymentMethodType == ApiClient.DataContracts.PaymentMethodType.PreparedForm)
                                    {
                                        if (!string.IsNullOrEmpty(paymentResult.HtmlForm))
                                        {
                                            SiteContext.Current.Set("payment_html_form", paymentResult.HtmlForm);
                                            return View("payment");
                                        }
                                    }
                                    if (paymentResult.PaymentMethodType == ApiClient.DataContracts.PaymentMethodType.Standard)
                                    {
                                        var productsIds = dtoOrder.Items.Select(i => i.ProductId);
                                        var catalogItems = await Service.GetCatalogItemsByIdsAsync(productsIds, "ItemAssets");

                                        var nonShippingProducts = catalogItems.Where(ci => ci.ProductType == "Digital");
                                        if (nonShippingProducts.Count() > 0)
                                        {
                                            var downloadLinks = new List<ProductDownloadLinks>();

                                            foreach (var nonShippingProduct in nonShippingProducts)
                                            {
                                                var productLinks = new ProductDownloadLinks
                                                {
                                                    ProductName = nonShippingProduct.Name
                                                };

                                                int linkCount = 1;
                                                foreach (var asset in nonShippingProduct.Assets)
                                                {
                                                    var url = Url.Action("Index", "Download", new { @file = asset.Name, @oid = dtoOrder.Id, @pid = nonShippingProduct.Id }, Request.Url.Scheme);
                                                    productLinks.Links.Add(new DownloadLink
                                                    {
                                                        Filename = asset.Name,
                                                        Text = nonShippingProduct.Assets.Count() > 1 ? String.Format("Download link {0}", linkCount) : "Download link",
                                                        Url = url
                                                    });

                                                    linkCount++;
                                                }

                                                downloadLinks.Add(productLinks);
                                            }

                                            Context.Set("download_links", downloadLinks);
                                        }

                                        Context.Order = dtoOrder.AsWebModel();

                                        return View("thanks_page");
                                    }
                                }
                                else
                                {
                                    Context.ErrorMessage = paymentResult.Error;

                                    return View("error");
                                }
                            }
                        }
                    }
                }
                else
                {
                    form.Errors = formErrors;
                    form.PostedSuccessfully = false;

                    return RedirectToAction("Step2");
                }
            }

            return View("error");
        }