/// <summary>
        /// Performs the setup for an express checkout.
        /// </summary>
        /// <param name="invoice">
        /// The <see cref="IInvoice"/>.
        /// </param>
        /// <param name="payment">
        /// The <see cref="IPayment"/>
        /// </param>
        /// <param name="returnUrl">
        /// The return URL.
        /// </param>
        /// <param name="cancelUrl">
        /// The cancel URL.
        /// </param>
        /// <returns>
        /// The <see cref="ExpressCheckoutResponse"/>.
        /// </returns>
        protected virtual PayPalExpressTransactionRecord SetExpressCheckout(IInvoice invoice, IPayment payment, string returnUrl, string cancelUrl)
        {
            var record = new PayPalExpressTransactionRecord
                             {
                                 Success = true,
                                 Data = { Authorized = false, CurrencyCode = invoice.CurrencyCode }
                             };

            var factory = new PayPalPaymentDetailsTypeFactory(new PayPalFactorySettings { WebsiteUrl = _websiteUrl });
            var paymentDetailsType = factory.Build(invoice, PaymentActionCodeType.ORDER);

            // The API requires this be in a list
            var paymentDetailsList = new List<PaymentDetailsType>() { paymentDetailsType };

            // ExpressCheckout details
            //// We do not want the customer to be able to reset their shipping address at PayPal
            //// due to the fact that it could affect shipping charges and in some cases tax rates.
            //// This is the AddressOverride = "0" - NOT WORKING!
            var ecDetails = new SetExpressCheckoutRequestDetailsType()
                    {
                        ReturnURL = returnUrl,
                        CancelURL = cancelUrl,
                        PaymentDetails = paymentDetailsList,
                        AddressOverride = "0"
                    };

            // Trigger the event to allow for overriding ecDetails
            var ecdOverride = new PayPalExpressCheckoutRequestDetailsOverride(invoice, payment, ecDetails);
            SettingCheckoutRequestDetails.RaiseEvent(new ObjectEventArgs<PayPalExpressCheckoutRequestDetailsOverride>(ecdOverride), this);

            // The ExpressCheckoutRequest
            var request = new SetExpressCheckoutRequestType
                    {
                        Version = Version,
                        SetExpressCheckoutRequestDetails = ecdOverride.ExpressCheckoutDetails
                    };

            // Crete the wrapper for Express Checkout
            var wrapper = new SetExpressCheckoutReq
                              {
                                  SetExpressCheckoutRequest = request
                              };

            try
            {
                var service = GetPayPalService();
                var response = service.SetExpressCheckout(wrapper);
                record.SetExpressCheckout = _responseFactory.Build(response, response.Token);
                record.Data.Token = response.Token;
                record.SetExpressCheckout.RedirectUrl = GetRedirectUrl(response.Token);
            }
            catch (Exception ex)
            {
                record.Success = false;
                record.SetExpressCheckout = _responseFactory.Build(ex);
            }

            return record;
        }
        /// <summary>
        /// Performs the setup for an express checkout.
        /// </summary>
        /// <param name="invoice">
        /// The <see cref="IInvoice"/>.
        /// </param>
        /// <param name="payment">
        /// The <see cref="IPayment"/>
        /// </param>
        /// <param name="returnUrl">
        /// The return URL.
        /// </param>
        /// <param name="cancelUrl">
        /// The cancel URL.
        /// </param>
        /// <returns>
        /// The <see cref="ExpressCheckoutResponse"/>.
        /// </returns>
        protected virtual PayPalExpressTransactionRecord SetExpressCheckout(IInvoice invoice, IPayment payment, string returnUrl, string cancelUrl)
        {
            var record = new PayPalExpressTransactionRecord
                             {
                                 Success = true,
                                 Data = { Authorized = false, CurrencyCode = invoice.CurrencyCode }
                             };

            var factory = new PayPalPaymentDetailsTypeFactory(new PayPalFactorySettings { WebsiteUrl = _websiteUrl });
            var paymentDetailsType = factory.Build(invoice, PaymentActionCodeType.ORDER);

            // The API requires this be in a list
            var paymentDetailsList = new List<PaymentDetailsType>() { paymentDetailsType };

            // ExpressCheckout details
            var ecDetails = new SetExpressCheckoutRequestDetailsType()
                    {
                        ReturnURL = returnUrl,
                        CancelURL = cancelUrl,
                        PaymentDetails = paymentDetailsList,
                        AddressOverride = "0"
                    };

            // Trigger the event to allow for overriding ecDetails
            var ecdOverride = new PayPalExpressCheckoutRequestDetailsOverride(invoice, payment, ecDetails);
            SettingCheckoutRequestDetails.RaiseEvent(new ObjectEventArgs<PayPalExpressCheckoutRequestDetailsOverride>(ecdOverride), this);

            // The ExpressCheckoutRequest
            var request = new SetExpressCheckoutRequestType
                    {
                        Version = Version,
                        SetExpressCheckoutRequestDetails = ecdOverride.ExpressCheckoutDetails
                    };

            // Crete the wrapper for Express Checkout
            var wrapper = new SetExpressCheckoutReq
                              {
                                  SetExpressCheckoutRequest = request
                              };

            try
            {
                var service = GetPayPalService();
                var response = service.SetExpressCheckout(wrapper);

                record.SetExpressCheckout = _responseFactory.Build(response, response.Token);
                if (record.SetExpressCheckout.Success())
                {
                    record.Data.Token = response.Token;
                    record.SetExpressCheckout.RedirectUrl = GetRedirectUrl(response.Token);
                }
                else
                {
                    foreach (var et in record.SetExpressCheckout.ErrorTypes)
                    {
                        var code = et.ErrorCode;
                        var sm = et.ShortMessage;
                        var lm = et.LongMessage;
                        MultiLogHelper.Warn<PayPalExpressCheckoutService>(string.Format("{0} {1} {2}", code, lm, sm));
                    }

                    record.Success = false;
                }
            }
            catch (Exception ex)
            {
                record.Success = false;
                record.SetExpressCheckout = _responseFactory.Build(ex);
            }

            return record;
        }