public async Task<PaymentsTopicViewModel> GetViewModel(PaymentFormBindingModel bindingModel = null) { /*------------------------------------------------------------------------------------------------------------------------ | Establish variables \-----------------------------------------------------------------------------------------------------------------------*/ var braintreeGateway = _braintreeConfiguration.GetGateway(); var clientToken = braintreeGateway.ClientToken.Generate(); /*------------------------------------------------------------------------------------------------------------------------ | Establish view model \-----------------------------------------------------------------------------------------------------------------------*/ var viewModel = await _topicMappingService.MapAsync<PaymentsTopicViewModel>(CurrentTopic); viewModel.BindingModel = bindingModel; /*------------------------------------------------------------------------------------------------------------------------ | Pass client token to model \-----------------------------------------------------------------------------------------------------------------------*/ if (viewModel != null) { viewModel.ClientToken = clientToken; } /*------------------------------------------------------------------------------------------------------------------------ | Return topic view \-----------------------------------------------------------------------------------------------------------------------*/ return viewModel; }
public async Task <IHttpActionResult> SendForm(PaymentFormBindingModel model) { var user = User.Identity as ApplicationUser; var prevHash = user.PhoneNumber; if (prevHash != model.Hash) { return(BadRequest("BAD HASH!")); } user.PhoneNumber = CreateMD5("http://localhost:4200" + model.Hash); IdentityResult result = await UserManager.UpdateAsync(user); if (!result.Succeeded) { return(GetErrorResult(result)); } return(Ok()); }
public async Task<IActionResult> IndexAsync(PaymentFormBindingModel bindingModel) { /*------------------------------------------------------------------------------------------------------------------------ | Validate invoice \-----------------------------------------------------------------------------------------------------------------------*/ // ### HACK JJC20200408: One might reasonably expect for the [Remote] model validation attribute to be validated as part // of ModelState.IsValid, but it doesn't appear to be. As a result, it needs to be revalidated here. Contract.Requires(bindingModel, nameof(bindingModel)); var invoice = GetInvoice(bindingModel.InvoiceNumber); var invoiceAmount = invoice.Attributes.GetDouble("InvoiceAmount", 1.00); if (invoice is null) { ModelState.AddModelError("InvoiceAmount", $"The invoice #{bindingModel.InvoiceNumber} is not valid."); } else if (invoiceAmount != bindingModel.InvoiceAmount) { ModelState.AddModelError( "InvoiceAmount", $"The invoice {bindingModel.InvoiceNumber} is correct, but doesn't match the expected invoice amount. Please " + $"recheck the amount owed. If it is confirmed to be correct, contact GoldSim." ); } /*------------------------------------------------------------------------------------------------------------------------ | Validate binding model \-----------------------------------------------------------------------------------------------------------------------*/ if (!ModelState.IsValid) { return TopicView(await GetViewModel(bindingModel).ConfigureAwait(true)); } /*------------------------------------------------------------------------------------------------------------------------ | Assemble and send Braintree transaction \-----------------------------------------------------------------------------------------------------------------------*/ var braintreeGateway = _braintreeConfiguration.GetGateway(); var request = new TransactionRequest { Amount = (decimal)bindingModel.InvoiceAmount, PurchaseOrderNumber = bindingModel.InvoiceNumber.ToString(CultureInfo.InvariantCulture), PaymentMethodNonce = bindingModel.PaymentMethodNonce, CustomFields = new() { { "cardholder" , bindingModel.CardholderName }, { "email" , bindingModel.Email },
public async Task<PaymentsTopicViewModel> GetViewModel(PaymentFormBindingModel bindingModel = null) { /*------------------------------------------------------------------------------------------------------------------------ | Establish variables \-----------------------------------------------------------------------------------------------------------------------*/ var braintreeGateway = _braintreeConfiguration.GetGateway(); var clientToken = braintreeGateway.ClientToken.Generate(); /*------------------------------------------------------------------------------------------------------------------------ | Establish view model \-----------------------------------------------------------------------------------------------------------------------*/ var viewModel = new PaymentsTopicViewModel { ClientToken = clientToken, BindingModel = bindingModel }; viewModel = (PaymentsTopicViewModel)await _topicMappingService.MapAsync(CurrentTopic, viewModel).ConfigureAwait(true); /*------------------------------------------------------------------------------------------------------------------------ | Return topic view \-----------------------------------------------------------------------------------------------------------------------*/ return viewModel; }
/*========================================================================================================================== | FUNCTION: SEND EMAIL RECEIPT \-------------------------------------------------------------------------------------------------------------------------*/ /// <summary> /// Sends an email receipt to GoldSim providing a record of the transaction. /// </summary> private async Task SendEmailReceipt(Result<Transaction> result, PaymentFormBindingModel bindingModel) { /*------------------------------------------------------------------------------------------------------------------------ | Set up notification email \-----------------------------------------------------------------------------------------------------------------------*/ var notificationEmail = new MailMessage(new MailAddress("*****@*****.**"), new MailAddress("*****@*****.**")); var emailSubjectPrefix = "GoldSim Payments: Credit Card Payment for Invoice"; var emailBody = new StringBuilder(""); var transaction = result.Target?? result.Transaction; var creditCard = transaction?.CreditCard; /*------------------------------------------------------------------------------------------------------------------------ | Apply common attributes \-----------------------------------------------------------------------------------------------------------------------*/ emailBody.AppendLine(); emailBody.AppendLine("Transaction details:"); emailBody.AppendLine(" - Cardholder Name: " + bindingModel.CardholderName); emailBody.AppendLine(" - Customer Email: " + bindingModel.Email); emailBody.AppendLine(" - Company Name: " + bindingModel.Organization); emailBody.AppendLine(" - Invoice Number: " + bindingModel.InvoiceNumber); emailBody.AppendLine(" - Amount: " + "$" + bindingModel.InvoiceAmount); emailBody.AppendLine(" - Credit Card (Last Four Digits): "+ creditCard?.LastFour?? "Not Available"); emailBody.AppendLine(" - Card Type: " + creditCard?.CardType.ToString()?? "Not Available"); /*------------------------------------------------------------------------------------------------------------------------ | Process successful result \-----------------------------------------------------------------------------------------------------------------------*/ if (result.IsSuccess() && transaction != null && TransactionSuccessStatuses.Contains(transaction.Status)) { notificationEmail.Subject = $"{emailSubjectPrefix} {bindingModel.InvoiceNumber} Successful"; emailBody.Insert(0, "PAYMENT STATUS: " + transaction.Status.ToString().ToUpper().Replace("_", " ")); notificationEmail.Body = emailBody.ToString(); await _smtpService.SendAsync(notificationEmail); return; } /*------------------------------------------------------------------------------------------------------------------------ | Process unsuccessful result \-----------------------------------------------------------------------------------------------------------------------*/ notificationEmail.Subject = $"{emailSubjectPrefix} {bindingModel.InvoiceNumber} Failed"; if (transaction != null) { var status = transaction.ProcessorResponseText; if (String.IsNullOrEmpty(status)) { status = transaction.Status.ToString(); } emailBody.Insert(0, "PAYMENT STATUS: " + status.ToUpper().Replace("_", " ")); } else { emailBody.Insert(0, "PAYMENT STATUS: NOT AVAILABLE"); } /*------------------------------------------------------------------------------------------------------------------------ | Process errors \-----------------------------------------------------------------------------------------------------------------------*/ // Display general error message ModelState.AddModelError( "Transaction", "Your transaction was unsuccessful. Please correct any errors with your submission or contact GoldSim at " + "[email protected] or +1 (425)295-6985 for assistance." ); // Display transaction message returned from Braintree if (!String.IsNullOrEmpty(result.Message)) { ModelState.AddModelError("Transaction", "Payment Status: " + result.Message); emailBody.AppendLine(" - Transaction Result: " + result.Message); } // Display any specific error messages returned from Braintree foreach (var error in result.Errors.DeepAll()) { ModelState.AddModelError(error.Code.ToString(), "Error: " + error.Message); emailBody.AppendLine(" - Error: " + error.Message); } /*------------------------------------------------------------------------------------------------------------------------ | Send email \-----------------------------------------------------------------------------------------------------------------------*/ notificationEmail.Body = emailBody.ToString(); await _smtpService.SendAsync(notificationEmail); }
public async Task<IActionResult> IndexAsync(PaymentFormBindingModel bindingModel) { /*------------------------------------------------------------------------------------------------------------------------ | Validate invoice \-----------------------------------------------------------------------------------------------------------------------*/ // ### HACK JJC20200408: One might reasonably expect for the [Remote] model validation attribute to be validated as part // of ModelState.IsValid, but it doesn't appear to be. As a result, it needs to be revalidated here. var invoice = GetInvoice(bindingModel.InvoiceNumber); var invoiceAmount = invoice.Attributes.GetDouble("InvoiceAmount", 1.00); if (invoice == null) { ModelState.AddModelError("InvoiceAmount", $"The invoice #{bindingModel.InvoiceNumber} is not valid."); } else if (invoiceAmount != bindingModel.InvoiceAmount) { ModelState.AddModelError( "InvoiceAmount", $"The invoice {bindingModel.InvoiceNumber} is correct, but doesn't match the expected invoice amount. Please " + $"recheck the amount owed. If it is confirmed to be correct, contact GoldSim." ); } /*------------------------------------------------------------------------------------------------------------------------ | Validate binding model \-----------------------------------------------------------------------------------------------------------------------*/ if (!ModelState.IsValid) { return TopicView(await GetViewModel(bindingModel)); } /*------------------------------------------------------------------------------------------------------------------------ | Assemble and send Braintree transaction \-----------------------------------------------------------------------------------------------------------------------*/ var braintreeGateway = _braintreeConfiguration.GetGateway(); var request = new TransactionRequest { Amount = (decimal)bindingModel.InvoiceAmount, PurchaseOrderNumber = bindingModel.InvoiceNumber.ToString(), PaymentMethodNonce = bindingModel.PaymentMethodNonce, CustomFields = new Dictionary<string, string> { { "cardholder" , bindingModel.CardholderName }, { "email" , bindingModel.Email }, { "company" , bindingModel.Organization }, { "invoice" , bindingModel.InvoiceNumber.ToString() } }, Options = new TransactionOptionsRequest { SubmitForSettlement = true } }; var result = braintreeGateway.Transaction.Sale(request); /*------------------------------------------------------------------------------------------------------------------------ | Send email \-----------------------------------------------------------------------------------------------------------------------*/ await SendEmailReceipt(result, bindingModel); /*------------------------------------------------------------------------------------------------------------------------ | Handle success \-----------------------------------------------------------------------------------------------------------------------*/ if (result.IsSuccess()) { invoice.Attributes.SetDateTime("DatePaid", DateTime.Now); TopicRepository.Save(invoice); return Redirect("/Web/Purchase/PaymentConfirmation"); } /*------------------------------------------------------------------------------------------------------------------------ | Return to view to display ModelState errors \-----------------------------------------------------------------------------------------------------------------------*/ return TopicView(await GetViewModel(bindingModel)); }