コード例 #1
0
ファイル: OrderController.cs プロジェクト: haixie/test
        public async Task <IActionResult> ChargebackOrder(OrderViewModel viewModel, ChargebackStatus chargebackStatus)
        {
            return(await ModifyOrderView("ChargebackDone", viewModel, async order =>
            {
                #region Fraud Protection Service
                var chargeback = new Chargeback
                {
                    ChargebackId = Guid.NewGuid().ToString(),
                    Amount = order.Total,
                    Currency = order.RiskPurchase?.Currency,
                    BankEventTimestamp = DateTimeOffset.Now,
                    Reason = viewModel.ReturnOrChargebackReason,
                    Status = chargebackStatus.ToString(),
                    PurchaseId = order.RiskPurchase.PurchaseId,
                    UserId = order.RiskPurchase.User.UserId,
                };

                var correlationId = _fraudProtectionService.NewCorrelationId;
                var response = await _fraudProtectionService.PostChargeback(chargeback, correlationId);

                var fraudProtectionIO = new FraudProtectionIOModel(correlationId, chargeback, response, "Chargeback");
                TempData.Put(FraudProtectionIOModel.TempDataKey, fraudProtectionIO);
                #endregion

                order.ReturnOrChargebackReason = viewModel.ReturnOrChargebackReason;
                order.Status = OrderStatus.ChargeBack;
                order.RiskChargeback = chargeback;
                order.RiskChargebackResponse = response;
            }));
        }
コード例 #2
0
ファイル: OrderController.cs プロジェクト: haixie/test
        public async Task <IActionResult> ReturnOrder(OrderViewModel viewModel, RefundStatus refundStatus, RefundReason refundReason)
        {
            return(await ModifyOrderView("ReturnDone", viewModel, async order =>
            {
                #region Fraud Protection Service
                var refund = new Refund
                {
                    RefundId = Guid.NewGuid().ToString(),
                    Amount = order.Total,
                    Currency = order.RiskPurchase?.Currency,
                    BankEventTimestamp = DateTimeOffset.Now,
                    PurchaseId = order.RiskPurchase.PurchaseId,
                    Reason = refundReason.ToString(),
                    Status = refundStatus.ToString(),
                    UserId = order.RiskPurchase.User.UserId,
                };

                var correlationId = _fraudProtectionService.NewCorrelationId;
                var response = await _fraudProtectionService.PostRefund(refund, correlationId);

                var fraudProtectionIO = new FraudProtectionIOModel(correlationId, refund, response, "Refund");
                TempData.Put(FraudProtectionIOModel.TempDataKey, fraudProtectionIO);
                #endregion

                order.ReturnOrChargebackReason = refundReason.ToString();
                order.Status = refundStatus == RefundStatus.Approved ? OrderStatus.ReturnCompleted : OrderStatus.ReturnRejected;
                order.RiskRefund = refund;
                order.RiskRefundResponse = response;
            }));
        }
コード例 #3
0
        private async Task<IActionResult> CallCustomAssessmentApi(CustomAssessmentViewModel model, string returnUrl)
        {
            #region Fraud Protection Service
            var correlationId = _fraudProtectionService.NewCorrelationId;
            var assessment = new CustomAssessment { ApiName = model.ApiName, Payload = model.Payload };

            var response = await _fraudProtectionService.PostCustomAssessment(assessment, correlationId);
            var fraudProtectionIO = new FraudProtectionIOModel(correlationId, model.Payload, response, "Custom Assessment", true);
            TempData.Put(FraudProtectionIOModel.TempDataKey, fraudProtectionIO);
            #endregion

            return View("CustomAssessment", model);        
        }
コード例 #4
0
        public async Task <IActionResult> CheckoutDetails(CheckoutDetailsViewModel checkoutDetails)
        {
            var basketViewModel = await GetBasketViewModelAsync();

            var address = new Address(
                string.Join(' ', checkoutDetails.ShippingAddress.Address1, checkoutDetails.ShippingAddress.Address2),
                checkoutDetails.ShippingAddress.City,
                checkoutDetails.ShippingAddress.State,
                checkoutDetails.ShippingAddress.CountryRegion,
                checkoutDetails.ShippingAddress.ZipCode);

            var paymentInfo = new PaymentInfo(
                string.Join(' ', checkoutDetails.User.FirstName, checkoutDetails.User.LastName),
                checkoutDetails.CreditCard.CardNumber,
                checkoutDetails.CreditCard.CardType,
                checkoutDetails.CreditCard.CVV,
                string.Join('/', checkoutDetails.CreditCard.ExpirationMonth, checkoutDetails.CreditCard.ExpirationYear));

            #region Fraud Protection Service
            //Call Fraud Protection to get the risk score for this purchase.
            //We get a correlation ID that we pass to all Fraud Protection calls (up to 4) that we make in the purchase workflow.
            //This is optional, but can help when troubleshooting bugs or performance issues.
            var purchase      = SetupPurchase(checkoutDetails, basketViewModel);
            var correlationId = _fraudProtectionService.NewCorrelationId;
            var result        = await _fraudProtectionService.PostPurchase(purchase, correlationId);

            var fraudProtectionIO = new FraudProtectionIOModel(correlationId, purchase, result, "Purchase");

            //Check the risk score that was returned and possibly complete the purchase.
            var status = await ApproveOrRejectPurchase(
                result.ResultDetails.MerchantRuleDecision,
                checkoutDetails.CreditCard.UnformattedCardNumber,
                purchase.PurchaseId,
                correlationId,
                fraudProtectionIO);

            TempData.Put(FraudProtectionIOModel.TempDataKey, fraudProtectionIO);
            #endregion

            await _orderService.CreateOrderAsync(basketViewModel.Id, address, paymentInfo, status, purchase, result);

            await _basketService.DeleteBasketAsync(basketViewModel.Id);

            ViewData["OrderResult"] = status;
            return(View("Checkout"));
        }
コード例 #5
0
        private async Task <IActionResult> RegisterUser(RegisterViewModel model, string returnUrl, bool useAP)
        {
            //Create the user object and validate it before calling Fraud Protection
            var user = new ApplicationUser
            {
                UserName      = model.User.Email,
                Email         = model.User.Email,
                FirstName     = model.User.FirstName,
                LastName      = model.User.LastName,
                PhoneNumber   = model.User.Phone,
                Address1      = model.Address.Address1,
                Address2      = model.Address.Address2,
                City          = model.Address.City,
                State         = model.Address.State,
                ZipCode       = model.Address.ZipCode,
                CountryRegion = model.Address.CountryRegion
            };

            foreach (var v in _userManager.UserValidators)
            {
                var validationResult = await v.ValidateAsync(_userManager, user);

                if (!validationResult.Succeeded)
                {
                    AddErrors(validationResult);
                }
            }
            ;

            foreach (var v in _userManager.PasswordValidators)
            {
                var validationResult = await v.ValidateAsync(_userManager, user, model.Password);

                if (!validationResult.Succeeded)
                {
                    AddErrors(validationResult);
                }
            }
            ;

            if (ModelState.ErrorCount > 0)
            {
                return(View("Register", model));
            }

            #region Fraud Protection Service
            var correlationId = _fraudProtectionService.NewCorrelationId;

            // Ask Fraud Protection to assess this signup/registration before registering the user in our database, etc.
            if (useAP)
            {
                AccountProtection.SignUp signupEvent = CreateSignupAPEvent(model);

                var signupAssessment = await _fraudProtectionService.PostSignupAP(signupEvent, correlationId);

                //Track Fraud Protection request/response for display only
                var fraudProtectionIO = new FraudProtectionIOModel(correlationId, signupEvent, signupAssessment, "Signup");
                TempData.Put(FraudProtectionIOModel.TempDataKey, fraudProtectionIO);

                bool rejectSignup = false;
                if (signupAssessment is AccountProtection.ResponseSuccess signupResponse)
                {
                    rejectSignup = signupResponse.ResultDetails.FirstOrDefault()?.Decision != AccountProtection.DecisionName.Approve;
                }

                if (rejectSignup)
                {
                    ModelState.AddModelError("", "Signup rejected by Fraud Protection. You can try again as it has a random likelihood of happening in this sample site.");
                    return(View("Register", model));
                }
            }
            else
            {
                SignUp signupEvent = CreateSignupEvent(model);

                var signupAssessment = await _fraudProtectionService.PostSignup(signupEvent, correlationId);

                //Track Fraud Protection request/response for display only
                var fraudProtectionIO = new FraudProtectionIOModel(correlationId, signupEvent, signupAssessment, "Signup");

                //2 out of 3 signups will succeed on average. Adjust if you want more or less signups blocked for tesing purposes.
                var rejectSignup     = new Random().Next(0, 3) != 0;
                var signupStatusType = rejectSignup ? SignupStatusType.Rejected.ToString() : SignupStatusType.Approved.ToString();

                var signupStatus = new SignupStatusEvent
                {
                    SignUpId   = signupEvent.SignUpId,
                    StatusType = signupStatusType,
                    StatusDate = DateTimeOffset.Now,
                    Reason     = "User is " + signupStatusType
                };

                if (!rejectSignup)
                {
                    signupStatus.User = new SignupStatusUser {
                        UserId = model.User.Email
                    };
                }

                var signupStatusResponse = await _fraudProtectionService.PostSignupStatus(signupStatus, correlationId);

                fraudProtectionIO.Add(signupStatus, signupStatusResponse, "Signup Status");

                TempData.Put(FraudProtectionIOModel.TempDataKey, fraudProtectionIO);

                if (rejectSignup)
                {
                    ModelState.AddModelError("", "Signup rejected by Fraud Protection. You can try again as it has a random likelihood of happening in this sample site.");
                    return(View("Register", model));
                }
            }
            #endregion

            var result = await _userManager.CreateAsync(user, model.Password);

            if (!result.Succeeded)
            {
                AddErrors(result);
                return(View("Register", model));
            }

            await _signInManager.SignInAsync(user, isPersistent : false);

            await TransferBasketToEmailAsync(user.Email);

            return(RedirectToLocal(returnUrl));
        }
コード例 #6
0
        private async Task <IActionResult> SignInUser(LoginViewModel model, string returnUrl, bool useAP)
        {
            var applicationUser = new ApplicationUser
            {
                UserName = model.Email
            };
            string hashedPassword = _userManager.PasswordHasher.HashPassword(applicationUser, model.Password);

            bool rejectSignIn = false;

            if (useAP)
            {
                var user = new AccountProtection.User()
                {
                    UserType = AccountProtection.UserType.Consumer,
                    Username = model.Email,
                    UserId   = model.Email
                };

                var device = new AccountProtection.DeviceContext()
                {
                    DeviceContextId = model.DeviceFingerPrinting.SessionId,
                    IpAddress       = _contextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString(),
                    Provider        = DeviceContextProvider.DFPFingerPrinting.ToString()
                };

                var metadata = new AccountProtection.EventMetadataAccountLogin()
                {
                    TrackingId        = Guid.NewGuid().ToString(),
                    LoginId           = Guid.NewGuid().ToString(),
                    CustomerLocalDate = DateTime.Now,
                    MerchantTimeStamp = DateTime.Now
                };

                var signIn = new AccountProtection.SignIn()
                {
                    Name     = "AP.AccountLogin",
                    Version  = "0.5",
                    Device   = device,
                    User     = user,
                    Metadata = metadata
                };

                var correlationId  = _fraudProtectionService.NewCorrelationId;
                var signInResponse = await _fraudProtectionService.PostSignInAP(signIn, correlationId);

                var fraudProtectionIO = new FraudProtectionIOModel(correlationId, signIn, signInResponse, "SignIn");
                TempData.Put(FraudProtectionIOModel.TempDataKey, fraudProtectionIO);

                if (signInResponse is AccountProtection.ResponseSuccess response)
                {
                    rejectSignIn = response.ResultDetails.FirstOrDefault()?.Decision != AccountProtection.DecisionName.Approve;
                }
            }
            else
            {
                var signIn = new SignIn
                {
                    SignInId          = Guid.NewGuid().ToString(),
                    PasswordHash      = hashedPassword,
                    MerchantLocalDate = DateTimeOffset.Now,
                    CustomerLocalDate = model.DeviceFingerPrinting.ClientDate,
                    UserId            = model.Email,
                    DeviceContextId   = model.DeviceFingerPrinting.SessionId,
                    AssessmentType    = AssessmentType.Protect.ToString(),
                    CurrentIpAddress  = _contextAccessor.HttpContext.Connection.RemoteIpAddress.ToString()
                };

                var correlationId  = _fraudProtectionService.NewCorrelationId;
                var signInResponse = await _fraudProtectionService.PostSignIn(signIn, correlationId);

                var fraudProtectionIO = new FraudProtectionIOModel(correlationId, signIn, signInResponse, "SignIn");
                TempData.Put(FraudProtectionIOModel.TempDataKey, fraudProtectionIO);

                //2 out of 3 signIn will be successful
                rejectSignIn = new Random().Next(0, 3) != 0;
            }

            if (!rejectSignIn)
            {
                var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure : false);

                if (!result.Succeeded)
                {
                    ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                    return(View("SignIn", model));
                }
                // redirect if signIn is not rejected and password sign-in is success
                await TransferBasketToEmailAsync(model.Email);

                return(RedirectToLocal(returnUrl));
            }
            else
            {
                ModelState.AddModelError("", "Signin rejected by Fraud Protection. You can try again as it has a random likelihood of happening in this sample site.");
                return(View("SignIn", model));
            }
        }
コード例 #7
0
ファイル: OrderController.cs プロジェクト: haixie/test
        public async Task <IActionResult> LabelOrder(
            OrderViewModel viewModel,
            LabelSource labelSource,
            LabelObjectType labelObjectType,
            LabelState labelStatus,
            LabelReasonCodes labelReasonCode)
        {
            var order = await GetOrder(viewModel.OrderNumber);

            if (order == null)
            {
                return(BadRequest("No such order found for this user."));
            }

            #region Fraud Protection Service
            string labelObjectId;
            switch (labelObjectType)
            {
            case LabelObjectType.Purchase:
                labelObjectId = order.RiskPurchase.PurchaseId;
                break;

            case LabelObjectType.Account:
                labelObjectId = order.RiskPurchase.User.UserId;
                break;

            case LabelObjectType.Email:
                labelObjectId = order.RiskPurchase.User.Email;
                break;

            case LabelObjectType.PI:
                labelObjectId = order.RiskPurchase.PaymentInstrumentList[0].MerchantPaymentInstrumentId;
                break;

            default:
                throw new InvalidOperationException("Label object type not supported: " + labelObjectType);
            }

            var label = new Label
            {
                LabelObjectType  = labelObjectType.ToString(),
                LabelObjectId    = labelObjectId,
                LabelSource      = labelSource.ToString(),
                LabelReasonCodes = labelReasonCode.ToString(),
                LabelState       = labelStatus.ToString(),
                EventTimeStamp   = DateTimeOffset.Now,
                Processor        = "Fraud Protection sample site",
            };

            if (labelObjectType == LabelObjectType.Purchase)
            {
                label.Amount   = order.Total;
                label.Currency = order.RiskPurchase?.Currency;
            }

            var correlationId = _fraudProtectionService.NewCorrelationId;
            var response      = await _fraudProtectionService.PostLabel(label, correlationId);

            var fraudProtectionIO = new FraudProtectionIOModel(correlationId, label, response, "Label");
            TempData.Put(FraudProtectionIOModel.TempDataKey, fraudProtectionIO);
            #endregion

            return(View("LabelDone"));
        }
コード例 #8
0
        /// <summary>
        /// Checks the purchase's risk score.
        ///    If the purchase is rejected, submit a REJECTED purchase status.
        ///    If the purchase is approved, submit the bank AUTH, bank CHARGE, and purchase status (approved if the bank also approves the auth and charge, or rejected otherwise).
        ///    If the purchase is in review, submit unknown bank AUTH and unknown purchase status (so that case management case is still created)
        /// </summary>
        private async Task <OrderStatus> ApproveOrRejectPurchase(string merchantRuleDecision, string cardNumber, string purchaseId, string correlationId, FraudProtectionIOModel fraudProtectionIO)
        {
            var                 status = OrderStatus.Received;
            BankEvent           auth   = null;
            BankEvent           charge = null;
            PurchaseStatusEvent purchaseStatus;

            if (!FakeCreditCardBankResponses.CreditCardResponses.TryGetValue(cardNumber, out FakeCreditCardBankResponses creditCardBankResponse))
            {
                //default response
                creditCardBankResponse = new FakeCreditCardBankResponses
                {
                    IgnoreFraudRiskRecommendation = false,
                    IsAuthApproved   = true,
                    IsChargeApproved = true
                };
            }

            var isApproved = merchantRuleDecision.StartsWith("APPROVE", StringComparison.OrdinalIgnoreCase);
            var inReview   = merchantRuleDecision.StartsWith("REVIEW", StringComparison.OrdinalIgnoreCase);

            if (isApproved || inReview || creditCardBankResponse.IgnoreFraudRiskRecommendation)
            {
                if (!creditCardBankResponse.IsAuthApproved)
                {
                    //Auth - Rejected
                    auth = SetupBankEvent(BankEventType.Auth, DateTimeOffset.Now, purchaseId, BankEventStatus.Declined);
                    //Purchase status - Rejected
                    purchaseStatus = SetupPurchaseStatus(purchaseId, PurchaseStatusType.Rejected);
                    status         = OrderStatus.Rejected;
                }
                else
                {
                    //Auth - Approved/Unknown
                    var authStatus = inReview ? BankEventStatus.Unknown : BankEventStatus.Approved;
                    auth = SetupBankEvent(BankEventType.Auth, DateTimeOffset.Now, purchaseId, authStatus);

                    //Charge
                    var chargeStatus = creditCardBankResponse.IsChargeApproved ? BankEventStatus.Approved : BankEventStatus.Declined;
                    if (!inReview)
                    {
                        charge = SetupBankEvent(BankEventType.Charge, DateTimeOffset.Now, purchaseId, chargeStatus);
                    }

                    if (inReview)
                    {
                        //Purchase status - Unknown
                        purchaseStatus = SetupPurchaseStatus(purchaseId, PurchaseStatusType.Unknown);
                        status         = OrderStatus.InReview;
                    }
                    else if (creditCardBankResponse.IsChargeApproved)
                    {
                        //Purchase status - Approved
                        purchaseStatus = SetupPurchaseStatus(purchaseId, PurchaseStatusType.Approved);
                    }
                    else
                    {
                        //Purchase status - Rejected
                        purchaseStatus = SetupPurchaseStatus(purchaseId, PurchaseStatusType.Rejected);
                        status         = OrderStatus.Rejected;
                    }
                }
            }
            else
            {
                purchaseStatus = SetupPurchaseStatus(purchaseId, PurchaseStatusType.Rejected);
                status         = OrderStatus.Rejected;
            }

            if (auth != null)
            {
                var response = await _fraudProtectionService.PostBankEvent(auth, correlationId);

                fraudProtectionIO.Add(auth, response, "BankEvent Auth");
            }
            if (charge != null)
            {
                var response = await _fraudProtectionService.PostBankEvent(charge, correlationId);

                fraudProtectionIO.Add(charge, response, "BankEvent Charge");
            }
            if (purchaseStatus != null)
            {
                var response = await _fraudProtectionService.PostPurchaseStatus(purchaseStatus, correlationId);

                fraudProtectionIO.Add(purchaseStatus, response, "PurchaseStatus");
            }

            return(status);
        }
コード例 #9
0
        public async Task <IActionResult> Index(IndexViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            var user = await _userManager.GetUserAsync(User);

            if (user == null)
            {
                throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
            }

            // Update the Application User
            user.FirstName     = model.User.FirstName;
            user.LastName      = model.User.LastName;
            user.Email         = model.User.Email;
            user.UserName      = model.Username;
            user.PhoneNumber   = model.User.Phone;
            user.Address1      = model.Address.Address1;
            user.Address2      = model.Address.Address2;
            user.City          = model.Address.City;
            user.State         = model.Address.State;
            user.ZipCode       = model.Address.ZipCode;
            user.CountryRegion = model.Address.CountryRegion;

            var result = await _userManager.UpdateAsync(user);

            #region Fraud Protection Service
            // If storing the user locally succeeds, update Fraud Protection
            if (result.Succeeded)
            {
                var billingAddress = new UserAddress
                {
                    Type      = UserAddressType.Billing.ToString(),
                    FirstName = user.FirstName,
                    LastName  = user.LastName,
                    Street1   = user.Address1,
                    Street2   = user.Address2,
                    City      = user.City,
                    State     = user.State,
                    ZipCode   = user.ZipCode,
                    Country   = user.CountryRegion
                };

                var shippingAddress = new UserAddress
                {
                    Type      = UserAddressType.Shipping.ToString(),
                    FirstName = user.FirstName,
                    LastName  = user.LastName,
                    Street1   = user.Address1,
                    Street2   = user.Address2,
                    City      = user.City,
                    State     = user.State,
                    ZipCode   = user.ZipCode,
                    Country   = user.CountryRegion
                };

                var fraudProtectionUser = new User
                {
                    UserId      = user.Email,
                    UpdateDate  = DateTimeOffset.Now,
                    Email       = user.Email,
                    FirstName   = user.FirstName,
                    LastName    = user.LastName,
                    PhoneNumber = user.PhoneNumber,
                    AddressList = new List <UserAddress> {
                        billingAddress, shippingAddress
                    },
                    ZipCode       = user.ZipCode,
                    Country       = user.CountryRegion,
                    TimeZone      = new TimeSpan(0, 0, -model.DeviceFingerPrinting.ClientTimeZone, 0).ToString(),
                    DeviceContext = new DeviceContext
                    {
                        DeviceContextId = _contextAccessor.GetSessionId(),
                        IPAddress       = _contextAccessor.HttpContext.Connection.RemoteIpAddress.ToString(),
                        Provider        = DeviceContextProvider.DFPFingerPrinting.ToString()
                    }
                };

                var correlationId = _fraudProtectionService.NewCorrelationId;
                var response      = await _fraudProtectionService.PostUser(fraudProtectionUser, correlationId);

                var fraudProtectionIO = new FraudProtectionIOModel(correlationId, fraudProtectionUser, response, "UpdateAccount");
                TempData.Put(FraudProtectionIOModel.TempDataKey, fraudProtectionIO);
            }
            #endregion

            StatusMessage = "Your profile has been updated";
            return(RedirectToAction(nameof(Index)));
        }
コード例 #10
0
        public async Task <IActionResult> ManagePaymentInstrument(ManagePaymentInstrumentViewModel model)
        {
            var user = await _userManager.GetUserAsync(User);

            if (user == null)
            {
                throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
            }

            // Set card info
            user.DefaultCardType        = model.CreditCard.CardType;
            user.DefaultCardNumber      = model.CreditCard.CardNumber;
            user.DefaultCardName        = model.CreditCard.CardName;
            user.DefaultCVV             = model.CreditCard.CVV;
            user.DefaultExpirationMonth = model.CreditCard.ExpirationMonth;
            user.DefaultExpirationYear  = model.CreditCard.ExpirationYear;

            // Set billing address info
            user.BillingAddress1      = model.BillingAddress.Address1;
            user.BillingAddress2      = model.BillingAddress.Address2;
            user.BillingCity          = model.BillingAddress.City;
            user.BillingState         = model.BillingAddress.State;
            user.BillingZipCode       = model.BillingAddress.ZipCode;
            user.BillingCountryRegion = model.BillingAddress.CountryRegion;

            var updateResult = await _userManager.UpdateAsync(user);

            #region Fraud Protection Service
            // If storing the user's payment information succeeds, update Fraud Protection.
            if (updateResult.Succeeded)
            {
                var billingAddress = new AddressDetails
                {
                    FirstName = user.FirstName,
                    LastName  = user.LastName,
                    Street1   = user.BillingAddress1,
                    Street2   = user.BillingAddress2,
                    City      = user.BillingCity,
                    State     = user.BillingState,
                    ZipCode   = user.BillingZipCode,
                    Country   = user.BillingCountryRegion
                };

                var userId = user.Email;

                var fraudProtectionUser = new User
                {
                    UserId = userId,
                    PaymentInstrumentList = new List <PaymentInstrument>
                    {
                        new PaymentInstrument
                        {
                            MerchantPaymentInstrumentId = $"{userId}-CreditCard",
                            Type           = PaymentInstrumentType.CreditCard.ToString(),
                            CardType       = model.CreditCard.CardType,
                            HolderName     = model.CreditCard.CardName,
                            BIN            = model.CreditCard.BIN,
                            ExpirationDate = model.CreditCard.ExpirationDate,
                            LastFourDigits = model.CreditCard.LastFourDigits,
                            BillingAddress = billingAddress,
                            CreationDate   = DateTimeOffset.Now,
                            State          = PaymentInstrumentState.Active.ToString(),
                        }
                    },
                    DeviceContext = new DeviceContext
                    {
                        DeviceContextId = _contextAccessor.GetSessionId(),
                        IPAddress       = _contextAccessor.HttpContext.Connection.RemoteIpAddress.ToString(),
                        Provider        = DeviceContextProvider.DFPFingerPrinting.ToString()
                    }
                };

                var correlationId = _fraudProtectionService.NewCorrelationId;
                var response      = await _fraudProtectionService.PostUser(fraudProtectionUser, correlationId);

                var fraudProtectionIO = new FraudProtectionIOModel(correlationId, fraudProtectionUser, response, "UpdateAccount");
                TempData.Put(FraudProtectionIOModel.TempDataKey, fraudProtectionIO);
            }
            #endregion

            StatusMessage = "Your payment information has been updated";
            return(RedirectToAction(nameof(ManagePaymentInstrument)));
        }
        private async Task <IActionResult> RegisterUser(RegisterViewModel model, string returnUrl)
        {
            //Create the user object and validate it before calling Fraud Protection
            var user = new ApplicationUser
            {
                UserName      = model.User.Email,
                Email         = model.User.Email,
                FirstName     = model.User.FirstName,
                LastName      = model.User.LastName,
                PhoneNumber   = model.User.Phone,
                Address1      = model.Address.Address1,
                Address2      = model.Address.Address2,
                City          = model.Address.City,
                State         = model.Address.State,
                ZipCode       = model.Address.ZipCode,
                CountryRegion = model.Address.CountryRegion
            };

            foreach (var v in _userManager.UserValidators)
            {
                var validationResult = await v.ValidateAsync(_userManager, user);

                if (!validationResult.Succeeded)
                {
                    AddErrors(validationResult);
                }
            }
            ;

            foreach (var v in _userManager.PasswordValidators)
            {
                var validationResult = await v.ValidateAsync(_userManager, user, model.Password);

                if (!validationResult.Succeeded)
                {
                    AddErrors(validationResult);
                }
            }
            ;

            if (ModelState.ErrorCount > 0)
            {
                return(View("Register", model));
            }

            #region Fraud Protection Service
            var correlationId = _fraudProtectionService.NewCorrelationId;

            // Ask Fraud Protection to assess this signup/registration before registering the user in our database, etc.
            AccountProtection.SignUp signupEvent = CreateSignupAPEvent(model);

            var signupAssessment = await _fraudProtectionService.PostSignup(signupEvent, correlationId, HttpContext.Session.GetString("envId"));

            //Track Fraud Protection request/response for display only
            var fraudProtectionIO = new FraudProtectionIOModel(correlationId, signupEvent, signupAssessment, "Signup");
            TempData.Put(FraudProtectionIOModel.TempDataKey, fraudProtectionIO);

            bool rejectSignup = false;
            if (signupAssessment is ResponseSuccess signupResponse)
            {
                rejectSignup = signupResponse.ResultDetails.FirstOrDefault()?.Decision != DecisionName.Approve;
            }

            if (rejectSignup)
            {
                ModelState.AddModelError("", "Signup rejected by Fraud Protection. You can try again as it has a random likelihood of happening in this sample site.");
                return(View("Register", model));
            }
            #endregion

            var result = await _userManager.CreateAsync(user, model.Password);

            if (!result.Succeeded)
            {
                AddErrors(result);
                return(View("Register", model));
            }

            await _signInManager.SignInAsync(user, isPersistent : false);

            await TransferBasketToEmailAsync(user.Email);

            return(RedirectToLocal(returnUrl));
        }