internal static CreditCardData GetCreditCardByToken(CustomerPaymentTokenizer tokenizer)
        {
            try
            {
                Log.Info($"Create Search for instant buy key {tokenizer.Token}");

                var serviceClient = new GatewayServiceClient(merchantKey, hostUri);

                Guid instantBuyKey = Guid.Parse(tokenizer.Token);

                Log.Info($"Make request for instant buy key {tokenizer.Token}");
                var httpResponse = serviceClient.CreditCard.GetInstantBuyData(instantBuyKey);

                if (httpResponse.HttpStatusCode == HttpStatusCode.OK
                    && httpResponse.Response.CreditCardDataCollection.Any() == true)
                {
                    return httpResponse.Response.CreditCardDataCollection.FirstOrDefault();
                }

                return default(CreditCardData);
            }
            catch (System.Exception ex)
            {
                Log.Error($"Request Error for instant buy key {tokenizer.Token}", ex);
                throw ex;
            }
            finally
            {
                Log.Info($"End Request for instant buy key {tokenizer.Token}");
            }

        }
  public MundiPaggClient()
  {
   //   var key = new Guid("5e62ba71-73d4-4ca0-8c03-26d1f78d6c71");
 //     const string link = "https://sandbox.mundipaggone.com";
      // Creates the client that will send the transaction.
      _serviceClient = new GatewayServiceClient();
  }
        public void MakeTransactionWithCreditCardToken(UserCreditCard userCreditCardInfo)
        {
            Guid instantBuyKey = GetInstantBuyKeyByUserId(userCreditCardInfo.UserId);

            try
            {
                var transaction = CreateCreditCardTransactionWithToken(userCreditCardInfo, instantBuyKey);

                Collection<CreditCardTransaction> CreditCardTransactionCollection =
                    new Collection<CreditCardTransaction>(new CreditCardTransaction[] { transaction });

                var createSaleRequest = CreateSaleRequest(CreditCardTransactionCollection);

                var serviceClient = new GatewayServiceClient(_merchantKey, _hostUri);

                var httpResponse = serviceClient.Sale.Create(createSaleRequest);

                // API response code
                ResponseProcess(userCreditCardInfo, httpResponse);
            }
            catch (Exception)
            {
                throw;
            }

        }
        internal static bool ProcessPayment(CustomerTicket ticket, Guid instantBuy, string securityCode)
        {
            var amountTransaction = (long)(ticket.Quantity * ticket.Event.Price);

            try
            {
                Log.Info($"Create transaction for ticket {ticket.Id} and for customer {ticket.IdCustomer}");

                // Cria a transação.
                var transaction = new CreditCardTransaction()
                {
                    AmountInCents = amountTransaction,
                    CreditCard = new CreditCard()
                    {
                        InstantBuyKey = instantBuy,
                        SecurityCode = securityCode
                    },
                };

                // Cria requisição.
                var createSaleRequest = new CreateSaleRequest()
                {
                    // Adiciona a transação na requisição.
                    CreditCardTransactionCollection = new Collection<CreditCardTransaction>(new CreditCardTransaction[] { transaction }),
                };

                Log.Info($"Make request for transaction for ticket {ticket.Id} and for customer {ticket.IdCustomer}");

                var serviceClient = new GatewayServiceClient(merchantKey, hostUri);

                // Autoriza a transação e recebe a resposta do gateway.
                var httpResponse = serviceClient.Sale.Create(createSaleRequest);

                Log.Info($"Request Status for transaction for ticket {ticket.Id} and for customer {ticket.IdCustomer} with status {httpResponse.HttpStatusCode}");
                if (httpResponse.Response.CreditCardTransactionResultCollection != null)
                {
                    var transactionStatus = httpResponse.Response.CreditCardTransactionResultCollection.FirstOrDefault().CreditCardTransactionStatus;
                    Log.Info($"Transaction Status for ticket {ticket.Id} with status {transactionStatus.ToString()}");

                    if (transactionStatus == CreditCardTransactionStatusEnum.NotAuthorized)
                        ticket.Status = Enum.StatusEnum.NotAuthorized;

                    if (transactionStatus == CreditCardTransactionStatusEnum.Captured)
                        ticket.Status = Enum.StatusEnum.Authorized;
                    
                    return true;
                }

                return false;
            }
            catch (System.Exception ex)
            {
                Log.Error($"Request Error for transaction for ticket {ticket.Id} and for customer {ticket.IdCustomer}", ex);
                throw ex;
            }
            finally
            {
                Log.Info($"End Request for transaction for ticket {ticket.Id} and for customer {ticket.IdCustomer}");
            }

        }
        internal static bool ProcessPayment(CustomerTicket ticket, CustomerPayment payment, out Guid instantBuy)
        {
            var amountTransaction = (long)(ticket.Quantity * ticket.Event.Price);
            var expiration = payment.Expiration.Split('/');
            var expMonth = Convert.ToInt32(expiration.FirstOrDefault());
            var expYear = Convert.ToInt32(expiration.LastOrDefault());

            instantBuy = Guid.Empty;

            try
            {
                Log.Info($"Create transaction for ticket {ticket.Id} and for customer {ticket.IdCustomer}");

                // Cria a transação.
                var transaction = new CreditCardTransaction()
                {
                    AmountInCents = amountTransaction,
                    CreditCard = new CreditCard()
                    {
                        CreditCardBrand = ConvertCreditCardBrand(payment),
                        CreditCardNumber = payment.CreditCardNumber,
                        ExpMonth = expMonth,
                        ExpYear = expYear,
                        HolderName = payment.HolderName,
                        SecurityCode = payment.SecurityCode
                    },
                };

                // Cria requisição.
                var createSaleRequest = new CreateSaleRequest()
                {
                    // Adiciona a transação na requisição.
                    CreditCardTransactionCollection = new Collection<CreditCardTransaction>(new CreditCardTransaction[] { transaction }),
                };

                Log.Info($"Make request for transaction for ticket {ticket.Id} and for customer {ticket.IdCustomer}");

                var serviceClient = new GatewayServiceClient(merchantKey, hostUri);

                // Autoriza a transação e recebe a resposta do gateway.
                var httpResponse = serviceClient.Sale.Create(createSaleRequest);

                Log.Info($"Request Status for transaction for ticket {ticket.Id} and for customer {ticket.IdCustomer} with status {httpResponse.HttpStatusCode}");
                if (httpResponse.Response.CreditCardTransactionResultCollection != null)
                {
                    var transactionStatus = httpResponse.Response.CreditCardTransactionResultCollection.FirstOrDefault().CreditCardTransactionStatus;
                    Log.Info($"Transaction Status for ticket {ticket.Id} with status {transactionStatus.ToString()}");

                    if (transactionStatus == CreditCardTransactionStatusEnum.NotAuthorized)
                        ticket.Status = Enum.StatusEnum.NotAuthorized;

                    if (transactionStatus == CreditCardTransactionStatusEnum.Captured)
                        ticket.Status = Enum.StatusEnum.Authorized;

                    if (payment.KeepSave)
                        instantBuy = httpResponse.Response.CreditCardTransactionResultCollection.FirstOrDefault().CreditCard.InstantBuyKey;
                    
                    return true;

                }

                return false;
            }
            catch (System.Exception ex)
            {
                Log.Error($"Request Error for transaction for ticket {ticket.Id} and for customer {ticket.IdCustomer}", ex);
                throw ex;
            }
            finally
            {
                Log.Info($"End Request for transaction for ticket {ticket.Id} and for customer {ticket.IdCustomer}");
            }

        }
        public string SendRequest(Infra.Models.CreditCard c)
        {
            try
            {
                var transaction = new CreditCardTransaction()
                {
                    AmountInCents = 100,
                    CreditCard = new GatewayApiClient.DataContracts.CreditCard()
                    {
                        CreditCardNumber = c.Number,
                        CreditCardBrand = CreditCardBrandEnum.Visa,
                        ExpMonth = c.Expiry.Date.Month,
                        ExpYear = c.Expiry.Date.Year,
                        SecurityCode = c.Cvc,
                        HolderName = c.Name
                    }
                };

                Guid merchantKey = Guid.Parse("2feddd0e-174d-4a1e-889b-e7f6785ccf11");

                string statusCode = String.Empty;
                string errorCode = String.Empty;
                string descriptionError = String.Empty;

                var serviceClient = new GatewayServiceClient(merchantKey);
                var httpResponse = serviceClient.Sale.Create(transaction);

                if (httpResponse.HttpStatusCode.ToString() != "Created")
                {
                    errorCode = httpResponse.Response.ErrorReport.ErrorItemCollection[0].ErrorCode.ToString();
                    descriptionError = httpResponse.Response.ErrorReport.ErrorItemCollection[0].Description.ToString();
                    switch (errorCode)
                    {
                        case "400":
                            TempData["AlertMessage"] = "Algum campo não foi enviado ou foi enviado de maneira incorreta. " + descriptionError;
                            break;
                        case "404":
                            TempData["AlertMessage"] = "Recurso não encontrado. " + descriptionError;
                            break;
                        case "500":
                            TempData["AlertMessage"] = "Erro nos servidores da MundiPagg, tente novamente mais tarde. " + descriptionError;
                            break;
                        case "504":
                            TempData["AlertMessage"] = "Tempo comunicação excedida entre a MundiPagg e a adquirente. " + descriptionError;
                            break;
                        default:
                            break;
                    }

                    return TempData["AlertMessage"].ToString();
                }
                else
                {
                    var httpResponse2 = serviceClient.Sale.QueryOrder(httpResponse.Response.OrderResult.OrderKey);
                    statusCode = httpResponse2.HttpStatusCode.ToString();

                    return statusCode;
                }
            }
            catch (Exception e)
            {
                TempData["AlertMessage"] = "Ocorreu um erro ao cadastrar o Cartão de Crédito. Por favor, tente novamente";
                throw new Exception("Erro: " + e.Message);
            }
        }
        //------Private Methods-----

        //send the transaction to Mundipagg API
        private bool AuthorizeTransaction(Transaction item)
        {

            var cardBrand = CardTypetoEnum(item.CardType);
            //if the card is not supported by Mundipagg Api return
            if (cardBrand == null) return false;           

            // Creates the credit card transaction.
            var transaction = new CreditCardTransaction()
            {
                AmountInCents = (long)double.Parse(item.Value) * 100,
                CreditCard = new CreditCard()
                {
                    CreditCardNumber = item.CardNumber,
                    CreditCardBrand = cardBrand,
                    ExpMonth = item.CardExpMonth,
                    ExpYear = item.CardExpYear,
                    SecurityCode = item.CardCVV,
                    HolderName = item.CardName,
                }
            };

            try
            {
                // Creates the client that will send the transaction.
                var guid = new Guid("85328786-8BA6-420F-9948-5352F5A183EB");
                var uri = new Uri("https://sandbox.mundipaggone.com");
                var serviceClient = new GatewayServiceClient(guid,uri);

                // Authorizes the credit card transaction and returns the gateway response.
                var httpResponse = serviceClient.Sale.Create(transaction);

                // API response code
                Debug.WriteLine("Status: {0}", httpResponse.HttpStatusCode);

                var createSaleResponse = httpResponse.Response;
                if (httpResponse.HttpStatusCode == HttpStatusCode.Created)
                {
                    foreach (var creditCardTransaction in createSaleResponse.CreditCardTransactionResultCollection)
                    {
                        Debug.WriteLine(creditCardTransaction.AcquirerMessage);                        
                    }
                    return true;
                }
                else
                {
                    if (createSaleResponse.ErrorReport != null)
                    {
                        foreach (ErrorItem errorItem in createSaleResponse.ErrorReport.ErrorItemCollection)
                        {
                            Debug.WriteLine("Error {0}: {1}", errorItem.ErrorCode, errorItem.Description);                            
                        }
                    }
                    return false;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                return false;         
            }
        }
        //-------------------------

        private Guid GetInstantBuyKeyByUserId(int userId)
        {
            Guid instantBuyKey = _creditCardTokenService.GetCreditCardTokenByUserId(userId).CreditCardTokenId;

            // Cria o cliente para obter os dados do cartão.
            var client = new GatewayServiceClient(_merchantKey, _hostUri);

            // Obtém os dados do cartão de crédito no gateway.
            var httpResponse = client.CreditCard.GetInstantBuyData(instantBuyKey);

            if (httpResponse.HttpStatusCode == HttpStatusCode.OK
                && httpResponse.Response.CreditCardDataCollection.Any() == true)
            {
                return instantBuyKey;
            }

            throw new Exception("Erro ao buscar o token do cartão de crédito");
        }
        private void MainTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            MainTimer.Stop();

            // Recupera a última mensagem da fila.
            var queue = new MessageQueue(_queue_name);
            var message = queue.Receive().Body.ToString();

            // Deserializa o conteúdo da mensagem.
            var jsonSerializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };
            var dt = JsonConvert.DeserializeObject<ItemSoldViewModel>(message, jsonSerializerSettings);

            // Envia a mensagem para a MundiPagg.
            if (dt != null)
            {
                var transaction = new CreditCardTransaction()
                {
                    AmountInCents = (long)(dt.Value * 100),
                    CreditCard = new CreditCard()
                    {
                        CreditCardNumber = dt.CardNumber1 + dt.CardNumber2 + dt.CardNumber3 + dt.CardNumber4,
                        CreditCardBrand = CreditCardBrandEnum.Visa,
                        ExpMonth = dt.ExpMonth,
                        ExpYear = dt.ExpYear,
                        SecurityCode = dt.SecurityCode,
                        HolderName = dt.HolderName
                    }
                };

                var ok = true;

                try
                {
                    var serviceClient = new GatewayServiceClient();
                    var httpResponse = serviceClient.Sale.Create(transaction);

                    var createSaleResponse = httpResponse.Response;
                    if (httpResponse.HttpStatusCode == HttpStatusCode.Created)
                    {
                        foreach (var creditCardTransaction in createSaleResponse.CreditCardTransactionResultCollection)
                        {
                            //SendEmailOK();
                        }
                    }
                    else
                    {
                        if (createSaleResponse.ErrorReport != null)
                        {
                            foreach (ErrorItem errorItem in createSaleResponse.ErrorReport.ErrorItemCollection)
                            {
                                ok = false;
                            }
                        }
                    }
                }
                catch
                {
                    ok = false;
                }

                if (!ok)
                {
                    //SendEmailError();
                }
            }

            MainTimer.Start();
        }