public override string HandleRequestAndReturnUrlForRedirect(
            HttpContext context,
            string payPalToken,
            string payPalPayerId,
            PayPalLog setExpressCheckoutLog)
        {
            string redirectUrl = string.Empty;

            if ((payPalToken == null) || (payPalToken.Length == 0))
            {
                log.Error("WebStorePayPalReturnHandler received empty payPalToken");
                return(redirectUrl);
            }

            if (setExpressCheckoutLog == null)
            {
                log.Error("WebStorePayPalReturnHandler received null setExpressCheckoutLog for payPalToken " + payPalToken);
                return(redirectUrl);
            }

            if (setExpressCheckoutLog.SerializedObject.Length == 0)
            {
                log.Error("WebStorePayPalReturnHandler cart was not previously serialized for payPalToken " + payPalToken);
                return(redirectUrl);
            }

            if (setExpressCheckoutLog.CreatedUtc.AddHours(4) < DateTime.UtcNow)
            {
                log.Error("payPalToken " + payPalToken + " was more than 4 hours old, it should expire after 3 hours ");
                return(redirectUrl);
            }

            CommerceConfiguration commerceConfig = SiteUtils.GetCommerceConfig();

            PayPalExpressGateway gateway
                = new PayPalExpressGateway(
                      commerceConfig.PayPalAPIUsername,
                      commerceConfig.PayPalAPIPassword,
                      commerceConfig.PayPalAPISignature,
                      commerceConfig.PayPalStandardEmailAddress);

            if (WebConfigSettings.DebugPayPal && gateway == null)
            {
                log.Error("gateway is null");
            }

            gateway.UseTestMode   = commerceConfig.PaymentGatewayUseTestMode;
            gateway.PayPalToken   = payPalToken;
            gateway.PayPalPayerId = payPalPayerId;


            Cart savedCart = (Cart)SerializationHelper.DeserializeFromString(typeof(Cart), setExpressCheckoutLog.SerializedObject);

            if (WebConfigSettings.DebugPayPal && savedCart == null)
            {
                log.Error("cart is null");
            }

            savedCart.DeSerializeCartOffers();

            string siteRoot = SiteUtils.GetNavigationSiteRoot();

            gateway.MerchantCartId = savedCart.CartGuid.ToString();
            gateway.ChargeTotal    = savedCart.OrderTotal;
            gateway.ReturnUrl      = siteRoot + "/Services/PayPalReturnHandler.ashx";
            gateway.CancelUrl      = siteRoot;
            //gateway.PayPalPayerId = payPalPayerId;

            gateway.CallGetExpressCheckoutDetails();

            Store store = new Store(savedCart.StoreGuid);

            PayPalLog payPalLog = new PayPalLog
            {
                ProviderName     = WebStorePayPalReturnHandler.ProviderName,
                SerializedObject = setExpressCheckoutLog.SerializedObject,
                ReturnUrl        = setExpressCheckoutLog.ReturnUrl,
                RawResponse      = gateway.RawResponse,
                TransactionId    = gateway.TransactionId,
                CurrencyCode     = gateway.CurrencyCode,
                CartGuid         = savedCart.CartGuid,
                Token            = payPalToken,
                PayerId          = payPalPayerId,
                RequestType      = "GetExpressCheckoutDetails",
                SiteGuid         = store.SiteGuid,
                StoreGuid        = store.Guid,
                UserGuid         = savedCart.UserGuid
            };

            if (WebConfigSettings.DebugPayPal && payPalLog == null)
            {
                log.Error("payPalLog is null");
            }


            // update the order with customer shipping info
            savedCart.OrderInfo.DeliveryCompany    = gateway.ShipToCompanyName;
            savedCart.OrderInfo.DeliveryAddress1   = gateway.ShipToAddress;
            savedCart.OrderInfo.DeliveryAddress2   = gateway.ShipToAddress2;
            savedCart.OrderInfo.DeliveryCity       = gateway.ShipToCity;
            savedCart.OrderInfo.DeliveryFirstName  = gateway.ShipToFirstName;
            savedCart.OrderInfo.DeliveryLastName   = gateway.ShipToLastName;
            savedCart.OrderInfo.DeliveryPostalCode = gateway.ShipToPostalCode;
            savedCart.OrderInfo.DeliveryState      = gateway.ShipToState;
            savedCart.OrderInfo.DeliveryCountry    = gateway.ShipToCountry;

            //Note that PayPal only returns a phone number if your Merchant accounts is configured to require the
            // buyer to provide it.
            if (gateway.ShipToPhone.Length > 0)
            {
                savedCart.OrderInfo.CustomerTelephoneDay = gateway.ShipToPhone;
            }

            if (gateway.BuyerEmail.Length > 0)
            {
                savedCart.OrderInfo.CustomerEmail = gateway.BuyerEmail;
            }

            // if customer and billing aren't populated already, user was anonymous when checkout began, make them the same as shipping
            //if (savedCart.UserGuid == Guid.Empty)
            //{
            //2013-12-23 since all we get is shipping address this can be considered as the same thing as billing address for paypal purposes so always use it
            // especially because we may need to calculate tax for express checkout
            // based on the address provided by paypal
            savedCart.CopyShippingToBilling();
            savedCart.CopyShippingToCustomer();
            //}

            GeoCountry country = new GeoCountry(savedCart.OrderInfo.DeliveryCountry);

            if (WebConfigSettings.DebugPayPal && country == null)
            {
                if (WebConfigSettings.DebugPayPal)
                {
                    log.Error("country is null");
                }
                country = new GeoCountry(SiteUtils.GetDefaultCountry());
            }

            GeoZone taxZone = GeoZone.GetByCode(country.Guid, savedCart.OrderInfo.DeliveryState);

            if (taxZone == null)
            {
                if (WebConfigSettings.DebugPayPal)
                {
                    log.Error("taxZone is null");
                }

                country = new GeoCountry(SiteUtils.GetDefaultCountry());
                var siteSettings = CacheHelper.GetCurrentSiteSettings();
                if (siteSettings != null)
                {
                    taxZone = new GeoZone(siteSettings.DefaultStateGuid);
                }
            }

            savedCart.OrderInfo.TaxZoneGuid = taxZone == null ? Guid.Empty : taxZone.Guid;

            savedCart.OrderInfo.Save();

            // refresh totals to calculate tax or shipping now that we have an address
            savedCart.RefreshTotals();
            savedCart.Save();

            savedCart.SerializeCartOffers();
            payPalLog.SerializedObject = SerializationHelper.SerializeToString(savedCart);

            payPalLog.Save();

            if (gateway.Response == PaymentGatewayResponse.Error)
            {
                redirectUrl = siteRoot + "/WebStore/PayPalGatewayError.aspx?plog=" + payPalLog.RowGuid.ToString();
                return(redirectUrl);
            }

            if (gateway.PayPalPayerId.Length == 0)
            {
                redirectUrl = siteRoot + "/WebStore/PayPalGatewayError.aspx?plog=" + payPalLog.RowGuid.ToString();
                return(redirectUrl);
            }


            int pageId = -1;

            List <PageModule> pageModules = PageModule.GetPageModulesByModule(store.ModuleId);

            if (WebConfigSettings.DebugPayPal && pageModules == null)
            {
                log.Error("pageModules is null");
            }
            foreach (PageModule pm in pageModules)
            {
                // use first pageid found, really a store should only
                // be on one page
                pageId = pm.PageId;
                break;
            }

            // after the CallGetExpressCheckoutDetails
            // we have the option of directing to a final review page before
            // calling CallDoExpressCheckoutPayment

            redirectUrl = siteRoot +
                          "/WebStore/PayPalExpressCheckout.aspx?pageid="
                          + pageId.ToString(CultureInfo.InvariantCulture)
                          + "&mid=" + store.ModuleId.ToString(CultureInfo.InvariantCulture)
                          + "&plog=" + payPalLog.RowGuid.ToString();

            return(redirectUrl);
        }