/// <summary>
        /// Performs the GetExpressCheckoutDetails operation.
        /// </summary>
        /// <param name="payment">
        /// The payment.
        /// </param>
        /// <param name="token">
        /// The token.
        /// </param>
        /// <param name="record">
        /// The record.
        /// </param>
        /// <returns>
        /// The <see cref="PayPalExpressTransactionRecord"/>.
        /// </returns>
        internal PayPalExpressTransactionRecord GetExpressCheckoutDetails(IPayment payment, string token, PayPalExpressTransactionRecord record)
        {
            record.Success = true;
            ExpressCheckoutResponse result = null;

            try
            {
                var getDetailsRequest = new GetExpressCheckoutDetailsReq
                {
                    GetExpressCheckoutDetailsRequest = new GetExpressCheckoutDetailsRequestType(token)
                };

                var service  = GetPayPalService();
                var response = service.GetExpressCheckoutDetails(getDetailsRequest);
                result = _responseFactory.Build(response, token);

                if (result.Success())
                {
                    record.Data.PayerId = response.GetExpressCheckoutDetailsResponseDetails.PayerInfo.PayerID;
                }
            }
            catch (Exception ex)
            {
                result = _responseFactory.Build(ex);
            }

            record.GetExpressCheckoutDetails = result;
            record.Success = result.Success();
            return(record);
        }
        /// <summary>
        /// Validates a successful response.
        /// </summary>
        /// <param name="invoice">
        /// The invoice.
        /// </param>
        /// <param name="payment">
        /// The payment.
        /// </param>
        /// <param name="token">
        /// The token.
        /// </param>
        /// <param name="payerId">
        /// The payer id.
        /// </param>
        /// <param name="record">
        /// The record.
        /// </param>
        /// <returns>
        /// The <see cref="ExpressCheckoutResponse"/>.
        /// </returns>
        /// <remarks>
        /// PayPal returns to the success URL even if the payment was declined. e.g.  The success URL represents a successful transaction
        /// not a successful payment so we need to do another request to verify the payment was completed and get additional information
        /// such as the transaction id so we can do refunds etc.
        /// </remarks>
        internal PayPalExpressTransactionRecord Authorize(IInvoice invoice, IPayment payment, string token, string payerId, PayPalExpressTransactionRecord record)
        {
            // Now we have to get the transaction details for the successful payment
            ExpressCheckoutResponse result = null;

            try
            {
                // do authorization
                var service = GetPayPalService();
                var doAuthorizationResponse = service.DoAuthorization(new DoAuthorizationReq
                {
                    DoAuthorizationRequest = new DoAuthorizationRequestType
                    {
                        TransactionID = record.Data.CheckoutPaymentTransactionId,
                        Amount        = new BasicAmountType(PayPalApiHelper.GetPayPalCurrencyCode(record.Data.CurrencyId), record.Data.AuthorizedAmount)
                    }
                });

                result = _responseFactory.Build(doAuthorizationResponse, token);
                if (result.Success())
                {
                    record.Data.Authorized = true;
                    record.Data.AuthorizationTransactionId = doAuthorizationResponse.TransactionID;
                }
            }
            catch (Exception ex)
            {
                result = _responseFactory.Build(ex);
            }

            record.DoAuthorization = result;

            return(record);
        }
        /// <summary>
        /// The capture success.
        /// </summary>
        /// <param name="invoice">
        /// The invoice.
        /// </param>
        /// <param name="payment">
        /// The payment.
        /// </param>
        /// <param name="amount">
        /// The amount.
        /// </param>
        /// <param name="isPartialPayment">
        /// The is partial payment.
        /// </param>
        /// <returns>
        /// The <see cref="ExpressCheckoutResponse"/>.
        /// </returns>
        public PayPalExpressTransactionRecord Capture(IInvoice invoice, IPayment payment, decimal amount, bool isPartialPayment)
        {
            // Get the transaction record
            var record = payment.GetPayPalTransactionRecord();

            ExpressCheckoutResponse result = null;

            try
            {
                var amountFactory = new PayPalBasicAmountTypeFactory(PayPalApiHelper.GetPayPalCurrencyCode(invoice.CurrencyCode));

                var authorizationId = record.Data.AuthorizationTransactionId;

                // do express checkout
                var request = new DoCaptureRequestType()
                {
                    AuthorizationID = authorizationId,
                    Amount          = amountFactory.Build(amount),
                    CompleteType    = isPartialPayment ? CompleteCodeType.NOTCOMPLETE : CompleteCodeType.COMPLETE
                };

                var doCaptureReq = new DoCaptureReq()
                {
                    DoCaptureRequest = request
                };

                var service           = GetPayPalService();
                var doCaptureResponse = service.DoCapture(doCaptureReq);
                result = _responseFactory.Build(doCaptureResponse, record.Data.Token);

                if (result.Success())
                {
                    var transactionId = doCaptureResponse.DoCaptureResponseDetails.PaymentInfo.TransactionID;
                    record.Data.CaptureTransactionId = transactionId;
                }
            }
            catch (Exception ex)
            {
                result = _responseFactory.Build(ex);
            }

            record.DoCapture = result;
            record.Success   = result.Success();
            return(record);
        }
        /// <summary>
        /// The do express checkout payment.
        /// </summary>
        /// <param name="invoice">
        /// The invoice.
        /// </param>
        /// <param name="payment">
        /// The payment.
        /// </param>
        /// <param name="token">
        /// The token.
        /// </param>
        /// <param name="payerId">
        /// The payer id.
        /// </param>
        /// <param name="record">
        /// The record of the transaction.
        /// </param>
        /// <returns>
        /// The <see cref="PayPalExpressTransactionRecord"/>.
        /// </returns>
        internal PayPalExpressTransactionRecord DoExpressCheckoutPayment(IInvoice invoice, IPayment payment, string token, string payerId, PayPalExpressTransactionRecord record)
        {
            var factory = new PayPalPaymentDetailsTypeFactory();

            ExpressCheckoutResponse result = null;

            try
            {
                // do express checkout
                var request = new DoExpressCheckoutPaymentRequestType(
                    new DoExpressCheckoutPaymentRequestDetailsType
                {
                    Token          = token,
                    PayerID        = payerId,
                    PaymentDetails =
                        new List <PaymentDetailsType>
                    {
                        factory.Build(invoice, PaymentActionCodeType.ORDER)
                    }
                });

                var doExpressCheckoutPayment = new DoExpressCheckoutPaymentReq
                {
                    DoExpressCheckoutPaymentRequest = request
                };

                var service  = GetPayPalService();
                var response = service.DoExpressCheckoutPayment(doExpressCheckoutPayment);
                result = _responseFactory.Build(response, token);

                var transactionId = response.DoExpressCheckoutPaymentResponseDetails.PaymentInfo[0].TransactionID;
                var currency      = response.DoExpressCheckoutPaymentResponseDetails.PaymentInfo[0].GrossAmount.currencyID;
                var amount        = response.DoExpressCheckoutPaymentResponseDetails.PaymentInfo[0].GrossAmount.value;

                record.Data.CheckoutPaymentTransactionId = transactionId;
                record.Data.CurrencyId       = currency.ToString();
                record.Data.AuthorizedAmount = amount;
            }
            catch (Exception ex)
            {
                result = _responseFactory.Build(ex);
            }

            record.DoExpressCheckoutPayment = result;
            record.Success = result.Success();

            return(record);
        }