/// <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 = "1"
            };

            // 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);
        }
        /// <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);
        }