From 76ebf30518fac755a8496736aebe09d9e09ce37d Mon Sep 17 00:00:00 2001 From: Derek Holloway Date: Mon, 9 Jun 2025 17:53:45 -0700 Subject: [PATCH] Make the payment service more modular --- .../Controllers/PaymentController.cs | 74 +++------------- .../Controllers/PaymentMethods/IPayment.cs | 11 +++ .../PaymentMethods/StripeIntents.cs | 88 +++++++++++++++++++ 3 files changed, 112 insertions(+), 61 deletions(-) create mode 100644 src/MistoxWebsite.Server/Controllers/PaymentMethods/IPayment.cs create mode 100644 src/MistoxWebsite.Server/Controllers/PaymentMethods/StripeIntents.cs diff --git a/src/MistoxWebsite.Server/Controllers/PaymentController.cs b/src/MistoxWebsite.Server/Controllers/PaymentController.cs index df87f62..ba348c1 100755 --- a/src/MistoxWebsite.Server/Controllers/PaymentController.cs +++ b/src/MistoxWebsite.Server/Controllers/PaymentController.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Mvc; +using MistoxWebsite.Server.Controllers.Payment; using MistoxWebsite.Server.Services.DatabaseService; using MistoxWebsite.Shared; using Newtonsoft.Json; @@ -22,73 +23,24 @@ namespace MistoxWebsite.Server.Controllers { [HttpPost] public async Task GetPaymentKey( [FromQuery] string userID ) { - // Stored Variables string OrderNumber = Guid.NewGuid().ToString().Substring(0,10); - int subtotal = 0; - - // Get the user purchasing the items - string UserID = ""; Shared.Account? acc = await _databaseService.GetAccount(userID); - if( acc != null ) { - UserID = acc.ID.ToString(); - List cart = await _databaseService.GetCart( acc ); + if (acc != null) { + List cart = await _databaseService.GetCart(acc); - // build Recipt and calculate Tax - var options = new CalculationCreateOptions{ - Currency = "usd", - CustomerDetails = new CalculationCustomerDetailsOptions{ - AddressSource = "billing", - }, - Expand = new List(){ "line_items" }, - LineItems = new List() - }; + IPayment PaymentPlugin = new StripeIntent(_databaseService); - List prods = new List(); - - // Add items to receipt - foreach( Cart items in cart ) { - Shared.Product? product = await _databaseService.GetProduct( items.ProductID ); - if (product != null){ - prods.Add(product.ID); - if( product != null ) { - subtotal += product.Cost; - options.LineItems.Add( new CalculationLineItemOptions { - Amount = product.Cost, - TaxCode = "txcd_10201000", // Tax code for downloadable digital games - Quantity = 1, - Reference = product.Name, - TaxBehavior = "exclusive" - } ); - } - } - + (bool, string) PaymentResponse = await PaymentPlugin.Purchase(OrderNumber, acc, cart); + if (PaymentResponse.Item1) { + return PaymentResponse.Item2; + } + else { + Console.WriteLine("An error has occured in the payment plugin\n\n"); + Console.WriteLine(PaymentResponse.Item2); + Console.WriteLine("\n"); + return "0"; } - var service = new CalculationService(); - Calculation result = service.Create( options ); - - string csv = ""; - foreach (int cur in prods ) { - csv = csv + cur + ","; - } - - // Crate Payment Intent - PaymentIntentCreateOptions paymentIntent = new PaymentIntentCreateOptions(){ - Amount = result.AmountTotal, - Currency = "usd", - Metadata = new Dictionary { - { "ordernumber", OrderNumber }, - { "user", UserID }, - { "products", csv }, - { "subtotal", subtotal.ToString() }, - { "total", result.AmountTotal.ToString() } - }, - StatementDescriptor = "Mistox.Net #" + OrderNumber - }; - - PaymentIntentService intentService = new PaymentIntentService(); - PaymentIntent x = await intentService.CreateAsync( paymentIntent ); - return x.ClientSecret; } return "0"; } diff --git a/src/MistoxWebsite.Server/Controllers/PaymentMethods/IPayment.cs b/src/MistoxWebsite.Server/Controllers/PaymentMethods/IPayment.cs new file mode 100644 index 0000000..b36973a --- /dev/null +++ b/src/MistoxWebsite.Server/Controllers/PaymentMethods/IPayment.cs @@ -0,0 +1,11 @@ +using MistoxWebsite.Shared; + +namespace MistoxWebsite.Server.Controllers.Payment { + + public interface IPayment { + + public Task<(bool, string)> Purchase(string OrderNumber, Account user, List cart); + + } + +} \ No newline at end of file diff --git a/src/MistoxWebsite.Server/Controllers/PaymentMethods/StripeIntents.cs b/src/MistoxWebsite.Server/Controllers/PaymentMethods/StripeIntents.cs new file mode 100644 index 0000000..ee7f0f0 --- /dev/null +++ b/src/MistoxWebsite.Server/Controllers/PaymentMethods/StripeIntents.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using MistoxWebsite.Server.Controllers.Payment; +using MistoxWebsite.Server.Services.DatabaseService; +using MistoxWebsite.Shared; +using Stripe; +using Stripe.Tax; + +namespace MistoxWebsite.Server.Controllers { + + public class StripeIntent : IPayment { + + DatabaseService _databaseService; + + public StripeIntent( DatabaseService databaseService ) { + _databaseService = databaseService; + } + + public async Task<(bool, string)> Purchase(string OrderNumber, Shared.Account user, List cart) { + try { + // build Recipt and calculate Tax + var options = new CalculationCreateOptions { + Currency = "usd", + CustomerDetails = new CalculationCustomerDetailsOptions { + AddressSource = "billing", + }, + Expand = new List() { "line_items" }, + LineItems = new List() + }; + + List prods = new List(); + + // Add items to receipt + int subtotal = 0; + foreach (Cart items in cart) { + Shared.Product? product = await _databaseService.GetProduct(items.ProductID); + if (product != null) { + prods.Add(product.ID); + if (product != null) { + subtotal += product.Cost; + options.LineItems.Add(new CalculationLineItemOptions { + Amount = product.Cost, + TaxCode = "txcd_10201000", // Tax code for downloadable digital games + Quantity = 1, + Reference = product.Name, + TaxBehavior = "exclusive" + }); + } + } + + } + + var service = new CalculationService(); + Calculation result = service.Create(options); + + string csv = ""; + foreach (int cur in prods) { + csv = csv + cur + ","; + } + + // Crate Payment Intent + PaymentIntentCreateOptions paymentIntent = new PaymentIntentCreateOptions() { + Amount = result.AmountTotal, + Currency = "usd", + Metadata = new Dictionary { + { "ordernumber", OrderNumber }, + { "user", user.ID.ToString() }, + { "products", csv }, + { "subtotal", subtotal.ToString() }, + { "total", result.AmountTotal.ToString() } + }, + StatementDescriptor = "Mistox.Net #" + OrderNumber + }; + + PaymentIntentService intentService = new PaymentIntentService(); + PaymentIntent x = await intentService.CreateAsync(paymentIntent); + + return (true, x.ClientSecret); + } catch(Exception e) { + return (false, e.ToString()); + } + + } + + } + +} \ No newline at end of file