public async Task <IActionResult> ChargeACreditCard(PurchaseCourseViewModel model) { try { var selectedUserProfile = _userprofileRepo.GetUserProfileById(User.Identity.Name); var isUserProfileValid = selectedUserProfile != null && !selectedUserProfile.DeletedDate.HasValue; if (!isUserProfileValid) { _logger.LogCritical($"User profile { User.Identity.Name } not found."); ViewBag.ErrorMessage = _errorMsgs.AccountNotFound; return(View("Error")); } var selectedCourse = _courseCtrl.GetCourseDetail(model.CourseId); if (selectedCourse == null) { ViewBag.ErrorMessage = _errorMsgs.CourseNotFound; return(View("Error")); } var selectedClassRoom = _classRoomRepo.GetPublicClassRoomByCourseCatalogId(model.CourseId); var isClassRoomValid = selectedClassRoom != null && !selectedClassRoom.DeletedDate.HasValue; if (!isClassRoomValid) { _logger.LogCritical($"ClassRoom of CourseId: { model.CourseId } not found."); ViewBag.ErrorMessage = _errorMsgs.SelectedCourseIsNotAvailableForPurchase; return(View("Error")); } var isAlreadyHaveTheSelectedCourse = !_myCourseCtrl.CanAddNewCourseCatalog(User.Identity.Name, model.CourseId); if (isAlreadyHaveTheSelectedCourse) { return(RedirectToAction("entercourse", "my", new { @id = model.CourseId })); } if (ModelState.IsValid) { var paymentResult = Engines.Models.PaymentResult.Unknow; var isPaymentSuccessed = false; var newSubscriptionId = Guid.NewGuid().ToString(); var newPaymentId = string.Empty; var now = _dateTime.GetCurrentTime(); try { // Pay with Paypal paymentResult = _payment.ChargeCreditCard(new Engines.Models.PaymentInformation { Address = model.PrimaryAddress.Address, City = model.PrimaryAddress.City, Country = model.PrimaryAddress.Country.ToString(), PostalCode = model.PrimaryAddress.ZipCode, State = model.PrimaryAddress.State, TotalPrice = selectedCourse.PriceUSD, UserProfileId = User.Identity.Name, PurchaseForCourseId = model.CourseId, FirstName = model.CreditCardInfo.FirstName, LastName = model.CreditCardInfo.LastName, ExpiredYear = model.CreditCardInfo.ExpiredYear, ExpiredMonth = model.CreditCardInfo.ExpiredMonth, CVV = model.CreditCardInfo.CVV.ToString(), CreditCardNumber = model.CreditCardInfo.CardNumber, CardType = model.CreditCardInfo.CardType.ToString() }); } catch (Exception e) { _logger.LogError($"Paypal payment error, from user: { User.Identity.Name }, course id: { model.CourseId }, Error: { e.ToString() }"); ViewBag.ErrorMessage = _errorMsgs.CanNotChargeACreditCard; return(View("Error")); } finally { isPaymentSuccessed = paymentResult == Engines.Models.PaymentResult.approved; newSubscriptionId = isPaymentSuccessed ? newSubscriptionId : "None"; var payment = createNewPayment(selectedCourse.id, selectedCourse.SideName, newSubscriptionId, model, selectedCourse.PriceUSD, now, isPaymentSuccessed); await _paymentRepo.CreateNewPayment(payment); newPaymentId = payment.id; } if (!isPaymentSuccessed) { ViewBag.ErrorMessage = _errorMsgs.CanNotChargeACreditCard; return(View("Error")); } try { var requestLessonCatalogIds = selectedClassRoom.Lessons.Select(it => it.LessonCatalogId); var lessonCatalogs = _lessonCatalogRepo.GetLessonCatalogById(requestLessonCatalogIds).ToList(); var newClassCalendar = createClassCalendar(selectedClassRoom, lessonCatalogs, now); newClassCalendar.CalculateCourseSchedule(); newClassCalendar.ExpiredDate = null; selectedUserProfile.Subscriptions = addNewSelfPurchaseSubscription(selectedUserProfile.Subscriptions, selectedClassRoom, newClassCalendar.id, model.CourseId, now, newSubscriptionId); var userActivity = selectedUserProfile.CreateNewUserActivity(selectedClassRoom, newClassCalendar, lessonCatalogs, now); _classCalendarRepo.UpsertClassCalendar(newClassCalendar); _userprofileRepo.UpsertUserProfile(selectedUserProfile); _userActivityRepo.UpsertUserActivity(userActivity); return(RedirectToAction("Finished", new { @id = newPaymentId })); } catch (Exception e) { _logger.LogCritical($"User: '******' already purchased course id: '{ model.CourseId }' with payment id: '{ newPaymentId }' but the system can't create new course."); throw e; } } return(View(model)); } catch (Exception e) { _logger.LogError($"MongoDB: { e.ToString() }"); ViewBag.ErrorMessage = _errorMsgs.CanNotConnectToTheDatabase; return(View("Error")); } }