public void Execute()
        {
            _contaAzulService.RefreshToken();

            var customers = _customerService.GetAllCustomers();

            // var storeScope = GetActiveStoreScopeConfiguration(_storeService, _workContext);
            CustomerResponse[] GetCustomerResponse = null;
            CustomerResponse   CustomerResponse    = null;
            var ContaAzulMiscSettings = _settingService.LoadSetting <ContaAzulMiscSettings>();

            var number     = string.Empty;
            var complement = string.Empty;
            var cpfCnpj    = string.Empty;

            foreach (var item in customers)
            {
                var customer = new CustomerMessage();

                new AddressHelper(_addressAttributeParser, _workContext).GetCustomNumberAndComplement(item.BillingAddress != null ? item.BillingAddress.CustomAttributes : null,
                                                                                                      out number, out complement, out cpfCnpj);

                customer.name = item.BillingAddress != null?AddressHelper.GetFullName(item.BillingAddress) : null;

                customer.companyName           = item.BillingAddress != null ? item.BillingAddress.Company : null;
                customer.email                 = item.Email;
                customer.personType            = "NATURAL";
                customer.stateRegistrationType = "NO_CONTRIBUTOR";
                customer.mobilePhone           = item.BillingAddress != null ? item.BillingAddress.PhoneNumber : null;
                customer.address.city.name     = item.BillingAddress != null ? item.BillingAddress.City : null;
                customer.address.state.name    = item.BillingAddress != null ? item.BillingAddress.StateProvince != null ? item.BillingAddress.StateProvince.Name : null : null;
                customer.address.zipCode       = item.BillingAddress != null ? item.BillingAddress.ZipPostalCode : null;
                customer.address.street        = item.BillingAddress != null ? item.BillingAddress.Address1 : null;
                customer.address.complement    = complement;
                customer.address.number        = number;
                customer.document              = cpfCnpj == "" ? null : cpfCnpj;

                try
                {
                    var filtro = "?search=";
                    if (cpfCnpj == string.Empty)
                    {
                        filtro = filtro + item.Email;
                    }
                    else
                    {
                        filtro = filtro + cpfCnpj;
                    }
                    using (var getcustomer = new GetCustomer(ContaAzulMiscSettings.UseSandbox))
                        GetCustomerResponse = getcustomer.CreateAsync(null, ContaAzulMiscSettings.access_token, filtro).ConfigureAwait(false).GetAwaiter().GetResult();
                    //busca por cpf conta azul, se existir, verifica se já foi adicionado na tabela do banco
                    if (GetCustomerResponse.Count() > 0)
                    {
                        var customerTable = _contaAzulCustomerService.GetCustomer(GetCustomerResponse[0]);
                        //caso ele não exista na tabela relacional do banco, insere e atualiza no conta azul
                        if (customerTable == null)
                        {
                            var customerContaAzul = new CustomerContaAzul();

                            customerContaAzul.ContaAzulId = GetCustomerResponse[0].id;
                            customerContaAzul.CustomerId  = item.Id;
                            customerContaAzul.DataCriacao = DateTime.Now;
                            _contaAzulCustomerService.InsertCustomer(customerContaAzul);

                            customer.id = customerTable.ContaAzulId.ToString();
                            customer.address.city.name = null;

                            var data1 = JsonConvert.SerializeObject(GetCustomerResponse[0]);
                            var data2 = JsonConvert.SerializeObject(customer);


                            // var data = data2.Equals(data1);

                            if (!data1.Equals(data2))
                            {
                                //se ele já existe na tabela, só faz o update no conta azul
                                using (var customerCreation = new CustomerCreation(ContaAzulMiscSettings.UseSandbox))
                                    CustomerResponse = customerCreation.CreateAsyncUpdate(customer, GetCustomerResponse[0].id.ToString(), ContaAzulMiscSettings.access_token).ConfigureAwait(false).GetAwaiter().GetResult();
                            }
                        }
                        else
                        {
                            customer.id = customerTable.ContaAzulId.ToString();
                            customer.address.city.name = null;

                            var data1 = JsonConvert.SerializeObject(GetCustomerResponse[0]);
                            var data2 = JsonConvert.SerializeObject(customer);


                            var data = data2.Equals(data1);

                            if (!data1.Equals(data2))
                            {
                                //se ele já existe na tabela, só faz o update no conta azul
                                using (var customerCreation = new CustomerCreation(ContaAzulMiscSettings.UseSandbox))
                                    CustomerResponse = customerCreation.CreateAsyncUpdate(customer, customerTable.ContaAzulId.ToString(), ContaAzulMiscSettings.access_token).ConfigureAwait(false).GetAwaiter().GetResult();
                            }
                        }
                    }
                    else
                    {//caso ele não exista no conta azul, faz a inserção dele no conta azul e no banco de dados
                        var data2 = JsonConvert.SerializeObject(customer);
                        using (var customerCreation = new CustomerCreation(ContaAzulMiscSettings.UseSandbox))
                            CustomerResponse = customerCreation.CreateAsync(customer, ContaAzulMiscSettings.access_token).ConfigureAwait(false).GetAwaiter().GetResult();

                        if (CustomerResponse != null)
                        {
                            var customerContaAzul = new CustomerContaAzul();

                            customerContaAzul.ContaAzulId = CustomerResponse.id;
                            customerContaAzul.CustomerId  = item.Id;
                            customerContaAzul.DataCriacao = DateTime.Now;
                            _contaAzulCustomerService.InsertCustomer(customerContaAzul);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error(ex.Message, ex);
                }
            }
        }
        public void SincronizaContatos()
        {
            var customers  = _customerService.GetAllCustomers();
            var storeScope = this.GetActiveStoreScopeConfiguration(_storeService, _workContext);

            CustomerResponse[] GetCustomerResponse = null;
            CustomerResponse   CustomerResponse    = null;
            var ContaAzulMiscSettings = _settingService.LoadSetting <ContaAzulMiscSettings>(storeScope);


            var number     = string.Empty;
            var complement = string.Empty;
            var cpfCnpj    = string.Empty;

            foreach (var item in customers)
            {
                var customer = new CustomerMessage();

                new AddressHelper(_addressAttributeParser, _workContext).GetCustomNumberAndComplement(item.BillingAddress != null ? item.BillingAddress.CustomAttributes : null,
                                                                                                      out number, out complement, out cpfCnpj);

                customer.name = item.BillingAddress != null?AddressHelper.GetFullName(item.BillingAddress) : null;

                customer.companyName        = item.BillingAddress != null ? item.BillingAddress.Company : null;
                customer.email              = item.Email;
                customer.personType         = "NATURAL";
                customer.mobilePhone        = item.BillingAddress != null ? item.BillingAddress.PhoneNumber : null;
                customer.address.city.name  = item.BillingAddress != null ? item.BillingAddress.City : null;
                customer.address.state.name = item.BillingAddress != null ? item.BillingAddress.StateProvince != null ? item.BillingAddress.StateProvince.Name : null : null;
                // customer.address.zipCode = item.BillingAddress != null ? item.BillingAddress.ZipPostalCode : null;
                customer.address.street     = item.BillingAddress != null ? item.BillingAddress.Address1 : null;
                customer.address.complement = complement;
                customer.address.number     = number;
                customer.document           = cpfCnpj;

                try
                {
                    var filtro = "?search=" + cpfCnpj;
                    using (var getcustomer = new GetCustomer(ContaAzulMiscSettings.UseSandbox))
                        GetCustomerResponse = getcustomer.CreateAsync(null, ContaAzulMiscSettings.access_token, filtro).ConfigureAwait(false).GetAwaiter().GetResult();
                    //busca por cpf conta azul, se existir, verifica se já foi adicionado na tabela do banco
                    if (GetCustomerResponse != null)
                    {
                        var customerPayPalPlus = _contaAzulCustomerService.GetCustomer(GetCustomerResponse[0]);
                        //caso ele não exista na tabela relacional do banco, insere e atualiza no conta azul
                        if (customerPayPalPlus == null)
                        {
                            using (var customerCreation = new CustomerCreation(ContaAzulMiscSettings.UseSandbox))
                                CustomerResponse = customerCreation.CreateAsyncUpdate(customer, GetCustomerResponse[0].id.ToString(), ContaAzulMiscSettings.access_token).ConfigureAwait(false).GetAwaiter().GetResult();

                            if (CustomerResponse != null)
                            {
                                var customerContaAzul = new CustomerContaAzul();

                                customerContaAzul.ContaAzulId = CustomerResponse.id;
                                customerContaAzul.CustomerId  = item.Id;
                                customerContaAzul.DataCriacao = DateTime.Now;
                                _contaAzulCustomerService.InsertCustomer(customerContaAzul);
                            }
                        }
                        else
                        {
                            //se ele já existe na tabela, só faz o update no conta azul
                            using (var customerCreation = new CustomerCreation(ContaAzulMiscSettings.UseSandbox))
                                CustomerResponse = customerCreation.CreateAsyncUpdate(customer, customerPayPalPlus.ContaAzulId.ToString(), ContaAzulMiscSettings.access_token).ConfigureAwait(false).GetAwaiter().GetResult();
                        }
                    }
                    else
                    {//caso ele não exista no conta azul, faz a inserção dele no conta azul e no banco de dados
                        using (var customerCreation = new CustomerCreation(ContaAzulMiscSettings.UseSandbox))
                            CustomerResponse = customerCreation.CreateAsync(customer, ContaAzulMiscSettings.access_token).ConfigureAwait(false).GetAwaiter().GetResult();

                        if (CustomerResponse != null)
                        {
                            var customerContaAzul = new CustomerContaAzul();

                            customerContaAzul.ContaAzulId = CustomerResponse.id;
                            customerContaAzul.CustomerId  = item.Id;
                            customerContaAzul.DataCriacao = DateTime.Now;
                            _contaAzulCustomerService.InsertCustomer(customerContaAzul);
                        }
                    }
                }
                catch (Exception ex)
                {
                    try
                    {
                        var retorno = JsonConvert.DeserializeObject <MiscExecutitionResponse>(ex.Message, ConverterPaymentExecution.Settings);

                        if (retorno.StatusCode == "401")
                        {
                            RefreshToken();
                            _logger.Error("Token expirado " + ContaAzulMiscSettings.access_token, ex);
                        }
                        else
                        {
                            _logger.Error(ex.Message, ex);
                        }
                    }
                    catch (Exception erro)
                    {
                        _logger.Error(erro.Message, erro);

                        throw;
                    }

                    // ErrorNotification("O Customer com id " + item.Id + " não foi encontrado" );
                }
            }
        }
        private PaymentMessage GetPaymentoMessage(PayPalPlusBrasilPaymentSettings payPalPlusBrasilPaymentSettings, Customer customer)
        {
            var cart = _workContext.CurrentCustomer.ShoppingCartItems.
                       Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
                       .LimitPerStore(_storeContext.CurrentStore.Id)
                       .ToList();

            List <AppliedGiftCard> appliedGiftCards;
            List <Discount>        orderAppliedDiscounts;
            decimal orderDiscountAmount;
            int     redeemedRewardPoints;
            decimal redeemedRewardPointsAmount;
            var     orderTotal = _orderTotalCalculationService.GetShoppingCartTotal(cart, out orderDiscountAmount,
                                                                                    out orderAppliedDiscounts, out appliedGiftCards, out redeemedRewardPoints, out redeemedRewardPointsAmount);

            decimal         tax;
            List <Discount> shippingTotalDiscounts;
            var             orderShippingTotalInclTax = _orderTotalCalculationService.GetShoppingCartShippingTotal(cart, true, out tax, out shippingTotalDiscounts);

            decimal         orderSubTotalDiscountAmount;
            List <Discount> orderSubTotalAppliedDiscounts;
            decimal         subTotalWithoutDiscountBase;
            decimal         subTotalWithDiscountBase;

            _orderTotalCalculationService.GetShoppingCartSubTotal(cart, true, out orderSubTotalDiscountAmount,
                                                                  out orderSubTotalAppliedDiscounts, out subTotalWithoutDiscountBase, out subTotalWithDiscountBase);

            var paymentMessage = new PaymentMessage();

            paymentMessage.Intent = "sale";
            paymentMessage.Payer.PaymentMethod = "paypal";

            paymentMessage.ExperienceProfileId = payPalPlusBrasilPaymentSettings.IdProfileExperience;

            var transactionList = new List <Models.Message.Request.Transaction>();
            var itemTransaction = new Models.Message.Request.Transaction();

            itemTransaction.Amount.Currency         = "BRL";
            itemTransaction.Amount.Total            = orderTotal.Value.ToString("N", new CultureInfo("en-US"));
            itemTransaction.Amount.Details.Shipping = orderShippingTotalInclTax.Value.ToString("N", new CultureInfo("en-US"));
            itemTransaction.Amount.Details.Subtotal = subTotalWithoutDiscountBase.ToString("N", new CultureInfo("en-US"));
            itemTransaction.Amount.Details.Discount = (orderDiscountAmount + orderSubTotalDiscountAmount).ToString("N", new CultureInfo("en-US"));

            itemTransaction.Description = "This is the payment transaction description";
            itemTransaction.PaymentOptions.AllowedPaymentMethod = "IMMEDIATE_PAY";
            itemTransaction.InvoiceNumber = string.Empty;


            var number     = string.Empty;
            var complement = string.Empty;

            new AddressHelper(_addressAttributeParser, _workContext).GetCustomNumberAndComplement(customer.ShippingAddress.CustomAttributes,
                                                                                                  out number, out complement);

            itemTransaction.ItemList.ShippingAddress.RecipientName = AddressHelper.GetFullName(customer.ShippingAddress);
            itemTransaction.ItemList.ShippingAddress.Line1         = customer.ShippingAddress.Address1;
            itemTransaction.ItemList.ShippingAddress.Line2         = complement;
            itemTransaction.ItemList.ShippingAddress.City          = customer.ShippingAddress.City;
            itemTransaction.ItemList.ShippingAddress.CountryCode   = customer.ShippingAddress.Country.TwoLetterIsoCode;
            itemTransaction.ItemList.ShippingAddress.PostalCode    = customer.ShippingAddress.ZipPostalCode;
            itemTransaction.ItemList.ShippingAddress.State         = customer.ShippingAddress.StateProvince.Name;
            itemTransaction.ItemList.ShippingAddress.Phone         = AddressHelper.FormatarCelular(customer.ShippingAddress.PhoneNumber);

            var itemList = new List <Models.Message.Request.Item>();

            foreach (var itemCart in cart)
            {
                var item = new Models.Message.Request.Item();

                item.Name        = itemCart.Product.Name;
                item.Description = itemCart.Product.ShortDescription;
                item.Quantity    = itemCart.Quantity;

                List <Discount> scDiscounts;
                decimal         discountAmount;

                var scUnitPrice = _priceCalculationService.GetUnitPrice(itemCart, true, out discountAmount, out scDiscounts);

                item.Price    = decimal.Round(scUnitPrice, 2).ToString("N2", new CultureInfo("en-US"));
                item.Sku      = itemCart.Product.Sku;
                item.Currency = "BRL";

                itemList.Add(item);
            }

            itemTransaction.ItemList.Items = itemList.ToArray();

            transactionList.Add(itemTransaction);

            paymentMessage.Transactions = transactionList.ToArray();

            string returnUrl       = _webHelper.GetStoreLocation(false) + "Plugins/PaymentPayPalPlusBrasil/IPNHandler";
            string cancelReturnUrl = _webHelper.GetStoreLocation(false) + "Plugins/PaymentPayPalPlusBrasil/IPNHandler";

            paymentMessage.RedirectUrls.ReturnUrl = new Uri(returnUrl);
            paymentMessage.RedirectUrls.CancelUrl = new Uri(cancelReturnUrl);


            return(paymentMessage);
        }
        public void PostProcessPayment(PostProcessPaymentRequest postProcessPaymentRequest)
        {
            var addressHelper = new AddressHelper(_addressAttributeParser, _workContext);

            var invoiceDate = DateTime.Now.AddDays(3);

            string urlRedirect = string.Empty;

            // Act
            using (var apiInvoice = new Invoice())
            {
                string number     = string.Empty;
                string complement = string.Empty;
                string cnpjcpf    = string.Empty;

                addressHelper.GetCustomNumberAndComplement(postProcessPaymentRequest.Order.BillingAddress.CustomAttributes,
                                                           out number, out complement, out cnpjcpf);

                InvoiceModel invoice;

                var customVariables = new List <CustomVariables>
                {
                    new CustomVariables {
                        name  = IuguHelper.CODIGO_PEDIDO,
                        value = postProcessPaymentRequest.Order.Id.ToString()
                    }
                };

                var addressModel = new AddressModel()
                {
                    ZipCode  = postProcessPaymentRequest.Order.BillingAddress.ZipPostalCode,
                    District = postProcessPaymentRequest.Order.BillingAddress.Address2,
                    State    = postProcessPaymentRequest.Order.BillingAddress.StateProvince.Name,
                    Street   = postProcessPaymentRequest.Order.BillingAddress.Address1,
                    Number   = number,
                    City     = postProcessPaymentRequest.Order.BillingAddress.City,
                    Country  = postProcessPaymentRequest.Order.BillingAddress.Country.Name
                };

                var invoiceItems = new Item[postProcessPaymentRequest.Order.OrderItems.Count + 1];
                int i            = 0;
                var cartItems    = postProcessPaymentRequest.Order.OrderItems;
                foreach (var item in cartItems)
                {
                    var productID = string.IsNullOrWhiteSpace(item.Product.Sku)
                        ? item.Product.Id.ToString()
                        : item.Product.Sku;

                    var productName = ProductHelper.GetProcuctName(item);

                    productName = ProductHelper.AddItemDescrition(productName, item);

                    invoiceItems[i] = new Item()
                    {
                        description = productName,
                        price_cents = ObterPrecoCentavos(decimal.Round(item.UnitPriceInclTax, 2)),
                        quantity    = item.Quantity
                    };
                    i++;
                }

                invoiceItems[i] = new Item()
                {
                    description = postProcessPaymentRequest.Order.ShippingMethod,
                    price_cents = ObterPrecoCentavos(decimal.Round(postProcessPaymentRequest.Order.OrderShippingInclTax, 2)),
                    quantity    = 1
                };


                string email = !string.IsNullOrWhiteSpace(postProcessPaymentRequest.Order.Customer.Email)?
                               postProcessPaymentRequest.Order.Customer.Email:
                               postProcessPaymentRequest.Order.BillingAddress.Email;
                string name  = AddressHelper.GetFullName(postProcessPaymentRequest.Order.BillingAddress);
                string phone = AddressHelper.FormatarCelular(postProcessPaymentRequest.Order.BillingAddress.PhoneNumber);

                string phoneNumber     = AddressHelper.ObterNumeroTelefone(phone);
                string phonePrefix     = AddressHelper.ObterAreaTelefone(postProcessPaymentRequest.Order.BillingAddress.PhoneNumber);
                string urlRetorno      = _storeContext.CurrentStore.Url + "checkout/completed/" + postProcessPaymentRequest.Order.Id.ToString();
                string urlNotification = _storeContext.CurrentStore.Url + "Plugins/PaymentIugu/PaymentReturn";

                int descontoCentavos = 0;

                //Desconto aplicado na ordem subtotal
                if (postProcessPaymentRequest.Order.OrderSubTotalDiscountExclTax > 0)
                {
                    var discount = postProcessPaymentRequest.Order.OrderSubTotalDiscountExclTax;
                    discount          = Math.Round(discount, 2);
                    descontoCentavos += ObterPrecoCentavos(decimal.Round(discount, 2));
                }

                //desconto fixo, dado por cupom, os descontos podem ser cumulativos
                if (postProcessPaymentRequest.Order.OrderDiscount > 0)
                {
                    var discount = postProcessPaymentRequest.Order.OrderDiscount;
                    discount          = Math.Round(discount, 2);
                    descontoCentavos += ObterPrecoCentavos(decimal.Round(discount, 2));
                }


                var payer = new PayerModel()
                {
                    CpfOrCnpj   = cnpjcpf,
                    Address     = addressModel,
                    Email       = email,
                    Name        = name,
                    Phone       = phone,
                    PhonePrefix = phonePrefix
                };

                var invoiceRequest = new InvoiceRequestMessage(email, invoiceDate, invoiceItems)
                {
                    Payer           = payer,
                    ReturnUrl       = urlRetorno,
                    NotificationUrl = urlNotification,
                    DiscountCents   = descontoCentavos,
                    CustomVariables = customVariables.ToArray()
                };

                invoice = apiInvoice.CreateAsync(invoiceRequest, _iuguPaymentSettings.CustomApiToken).ConfigureAwait(false).GetAwaiter().GetResult();

                urlRedirect = invoice.secure_url;
            };


            _orderNoteService.AddOrderNote("Fatura IUGU Bradesco gerada.", true, postProcessPaymentRequest.Order);

            System.Web.HttpContext.Current.Response.Redirect(urlRedirect);
        }