private Purchase SetupPurchase()

in src/Web/Controllers/BasketController.cs [288:436]


        private Purchase SetupPurchase(CheckoutDetailsViewModel checkoutDetails, BasketViewModel basketViewModel)
        {
            var shippingAddress = new AddressDetails
            {
                FirstName = checkoutDetails.User.FirstName,
                LastName = checkoutDetails.User.LastName,
                PhoneNumber = checkoutDetails.User.Phone,
                Street1 = checkoutDetails.ShippingAddress.Address1,
                Street2 = checkoutDetails.ShippingAddress.Address2,
                City = checkoutDetails.ShippingAddress.City,
                State = checkoutDetails.ShippingAddress.State,
                ZipCode = checkoutDetails.ShippingAddress.ZipCode,
                Country = checkoutDetails.ShippingAddress.CountryRegion
            };

            var billingAddress = new AddressDetails
            {
                FirstName = checkoutDetails.User.FirstName,
                LastName = checkoutDetails.User.LastName,
                PhoneNumber = checkoutDetails.User.Phone,
                Street1 = checkoutDetails.BillingAddress.Address1,
                Street2 = checkoutDetails.BillingAddress.Address2,
                City = checkoutDetails.BillingAddress.City,
                State = checkoutDetails.BillingAddress.State,
                ZipCode = checkoutDetails.BillingAddress.ZipCode,
                Country = checkoutDetails.BillingAddress.CountryRegion
            };

            var device = new DeviceContext
            {
                DeviceContextId = _contextAccessor.GetSessionId(),
                IPAddress = _contextAccessor.HttpContext.Connection.RemoteIpAddress.ToString(),
                Provider = DeviceContextProvider.DFPFingerPrinting.ToString()
            };

            static string getCategoryFromName(string productName)
            {
                if (productName.Contains("mug", StringComparison.InvariantCultureIgnoreCase))
                {
                    return ProductCategory.HomeGarden.ToString();
                }

                if (productName.Contains("shirt", StringComparison.InvariantCultureIgnoreCase))
                {
                    return ProductCategory.ClothingShoes.ToString();
                }

                if (productName.Contains("sheet", StringComparison.InvariantCultureIgnoreCase))
                {
                    return ProductCategory.Jewelry.ToString();
                }

                return "Other";
            }

            var productList = basketViewModel.Items
                .Select(i => new Product
                {
                    ProductId = i.Id.ToString(),
                    PurchasePrice = i.UnitPrice,
                    Quantity = i.Quantity,
                    Margin = 2.1M,
                    IsPreorder = false,
                    ShippingMethod = PurchaseShippingMethod.Standard.ToString(),
                    ProductName = i.ProductName,
                    Type = ProductType.Digital.ToString(),
                    Category = getCategoryFromName(i.ProductName),
                    Market = "US",
                    COGS = 0.11M,
                    IsRecurring = false,
                    SalesPrice = i.UnitPrice,
                    Currency = "USD",
                    IsFree = false,
                    Language = "EN-US",
                    Sku = i.Id.ToString()
                })
                .ToList();

            //Logged in vs. anonymous user checkout.
            //If they are logged in, use their email.
            //Otherwise, try to use the basket ID (from the cookie).
            //If that isn't available - it always should be - create a new GUID.
            var userId = User?.Identity?.Name ?? basketViewModel.BuyerId ?? Guid.NewGuid().ToString();

            var user = new UserDetails
            {
                UserId = userId,
                CreationDate = DateTimeOffset.Now,
                UpdateDate = DateTimeOffset.Now,
                FirstName = checkoutDetails.User.FirstName,
                LastName = checkoutDetails.User.LastName,
                Country = checkoutDetails.ShippingAddress.CountryRegion,
                ZipCode = checkoutDetails.ShippingAddress.ZipCode,
                TimeZone = TimeZoneInfo.Local.Id,
                Language = "EN-US",
                PhoneNumber = checkoutDetails.User.Phone,
                Email = checkoutDetails.User.Email,
                ProfileType = UserProfileType.Consumer.ToString()
            };

            var paymentInstrument = new PurchasePaymentInstrument
            {
                PurchaseAmount = basketViewModel.Total,
                MerchantPaymentInstrumentId = $"{userId}-CreditCard",
                Type = PaymentInstrumentType.CreditCard.ToString(),
                CardType = checkoutDetails.CreditCard.CardType,
                State = PaymentInstrumentState.Active.ToString(),
                HolderName = checkoutDetails.CreditCard.CardName,
                BIN = checkoutDetails.CreditCard.UnformattedCardNumber.Substring(0, 6),
                ExpirationDate = string.Join('/', checkoutDetails.CreditCard.ExpirationMonth, checkoutDetails.CreditCard.ExpirationYear),
                LastFourDigits = checkoutDetails.CreditCard.UnformattedCardNumber.Substring(checkoutDetails.CreditCard.UnformattedCardNumber.Length - 4),
                CreationDate = DateTimeOffset.Now.AddMonths(-14),
                BillingAddress = billingAddress,
            };

            Product mostExpensiveProduct = productList.FirstOrDefault();
            foreach( var product in productList)
            {
                if ((product.SalesPrice / product.Quantity) > (mostExpensiveProduct.SalesPrice / mostExpensiveProduct.Quantity))
                {
                    mostExpensiveProduct = product;
                }
            }

            var customData = new Dictionary<string, object>()
            {
                { "MostExpensiveProduct", mostExpensiveProduct.ProductName },
                { "TotalCOGS", productList.Sum(p => p.COGS * p.Quantity) },
                { "ContainsRiskyProducts", productList.Any(p => p.Category == ProductCategory.Jewelry.ToString() || p.Category == ProductCategory.HomeGarden.ToString()) }
            };

            return new Purchase
            {
                PurchaseId = Guid.NewGuid().ToString(),
                AssessmentType = AssessmentType.Protect.ToString(),
                ShippingAddress = shippingAddress,
                ShippingMethod = PurchaseShippingMethod.Standard.ToString(),
                Currency = "USD",
                DeviceContext = device,
                MerchantLocalDate = DateTimeOffset.Now,
                CustomerLocalDate = checkoutDetails.DeviceFingerPrinting.ClientDate,
                ProductList = productList,
                TotalAmount = basketViewModel.Total,
                SalesTax = basketViewModel.Tax,
                User = user,
                PaymentInstrumentList = new List<PurchasePaymentInstrument> { paymentInstrument },
                CustomData = customData
            };
        }