/// <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>
        /// 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>
        /// Refunds or partially refunds a payment.
        /// </summary>
        /// <param name="invoice">
        /// The invoice.
        /// </param>
        /// <param name="payment">
        /// The payment.
        /// </param>
        /// <param name="amount">
        /// The amount of the refund.
        /// </param>
        /// <returns>
        /// The <see cref="PayPalExpressTransactionRecord"/>.
        /// </returns>
        public ExpressCheckoutResponse Refund(IInvoice invoice, IPayment payment, decimal amount)
        {
            var record = payment.GetPayPalTransactionRecord();

            // Ensure the currency code
            if (record.Data.CurrencyCode.IsNullOrWhiteSpace())
            {
                var ex = new PayPalApiException("CurrencyCode was not found in payment extended data PayPal transaction data record.  Cannot perform refund.");
                return(_responseFactory.Build(ex));
            }

            // Ensure the transaction id
            if (record.Data.CaptureTransactionId.IsNullOrWhiteSpace())
            {
                var ex = new PayPalApiException("CaptureTransactionId was not found in payment extended data PayPal transaction data record.  Cannot perform refund.");
                return(_responseFactory.Build(ex));
            }

            // Get the decimal configuration for the current currency
            var currencyCodeType   = PayPalApiHelper.GetPayPalCurrencyCode(record.Data.CurrencyCode);
            var basicAmountFactory = new PayPalBasicAmountTypeFactory(currencyCodeType);

            ExpressCheckoutResponse result = null;

            if (amount > payment.Amount)
            {
                amount = payment.Amount;
            }

            try
            {
                var request = new RefundTransactionRequestType
                {
                    InvoiceID     = invoice.PrefixedInvoiceNumber(),
                    PayerID       = record.Data.PayerId,
                    RefundSource  = RefundSourceCodeType.DEFAULT,
                    Version       = record.DoCapture.Version,
                    TransactionID = record.Data.CaptureTransactionId,
                    Amount        = basicAmountFactory.Build(amount)
                };

                var wrapper = new RefundTransactionReq {
                    RefundTransactionRequest = request
                };

                var refundTransactionResponse = GetPayPalService().RefundTransaction(wrapper);

                result = _responseFactory.Build(refundTransactionResponse, record.Data.Token);
            }
            catch (Exception ex)
            {
                result = _responseFactory.Build(ex);
            }

            return(result);
        }
        /// <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);
        }
        /// <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);
        }
        private dynamic ExecuteExpress(dynamic parameters)
        {
            _setConfigurations();

            var longAccessToken = this.Request.Query["longAccessToken"];

            //Create an instance of PrecheckoutDataRequest
            PrecheckoutDataRequest precheckoutDataRequest = new PrecheckoutDataRequest()
                                                            .WithPairingDataTypes(new PairingDataTypes()
                                                                                  .WithPairingDataType(new PairingDataType()
                                                                                                       .WithType("CARD"))

                                                                                  .WithPairingDataType(new PairingDataType()
                                                                                                       .WithType("ADDRESS"))

                                                                                  .WithPairingDataType(new PairingDataType()
                                                                                                       .WithType("PROFILE")));

            //Call the PrecheckoutDataApi with required params
            PrecheckoutDataResponse precheckoutDataResponse = PrecheckoutDataApi.Create(longAccessToken, precheckoutDataRequest);

            ExpressCheckoutRequest expressCheckoutRequest = new ExpressCheckoutRequest
            {
                PrecheckoutTransactionId = precheckoutDataResponse.PrecheckoutData.PrecheckoutTransactionId,  // from precheckout data
                MerchantCheckoutId       = Contants.checkoutId,
                OriginUrl                = Contants.callbackURL,
                CurrencyCode             = "USD",
                AdvancedCheckoutOverride = true, // set to true to disable 3-DS authentication
                OrderAmount              = 1299,
                DigitalGoods             = false,
                CardId            = precheckoutDataResponse.PrecheckoutData.Cards.Card[0].CardId,
                ShippingAddressId = precheckoutDataResponse.PrecheckoutData.ShippingAddresses.ShippingAddress[0].AddressId,
            };
            ExpressCheckoutResponse response = ExpressCheckoutApi.Create(longAccessToken, expressCheckoutRequest);

            Checkout checkout = response.Checkout;

            Card    card                             = checkout.Card;
            Address billingAddress                   = card.BillingAddress;
            Contact contact                          = checkout.Contact;
            AuthenticationOptions authOptions        = checkout.AuthenticationOptions;
            string          preCheckoutTransactionId = checkout.PreCheckoutTransactionId;
            ShippingAddress shippingAddress          = checkout.ShippingAddress;
            string          transactionId            = checkout.TransactionId;
            string          walletId                 = checkout.WalletID;

            /// AQUI DEVE SER CHAMADO O GATEWAY DE PAGAMENTO PARA EXECUTAR O
            /// PAGAMENTO COM OS DADOS RECUPERADOS ACIMA...

            /// UMA VEZ QUE O PAGAMENTO FOI EXECUTADO, CONTINUAR COM O PASSO ABAIXO

            //Create an instance of MerchantTransactions
            MerchantTransactions merchantTransactions = new MerchantTransactions()
                                                        .With_MerchantTransactions(new MerchantTransaction()
                                                                                   .WithTransactionId(transactionId)
                                                                                   .WithPurchaseDate("2017-05-27T12:38:40.479+05:30")
                                                                                   .WithExpressCheckoutIndicator(false)
                                                                                   .WithApprovalCode("sample")
                                                                                   .WithTransactionStatus("Success")
                                                                                   .WithOrderAmount((long)76239)
                                                                                   .WithCurrency("USD")
                                                                                   .WithConsumerKey(Contants.consumerKey));

            //Call the PostbackService with required params
            MerchantTransactions merchantTransactionsResponse = PostbackApi.Create(merchantTransactions);


            return("Express Checkout realizado com sucesso. TransactionId:" + transactionId);
        }