Make the payment service more modular

This commit is contained in:
2025-06-09 17:53:45 -07:00
parent 8c3e3d1096
commit 76ebf30518
3 changed files with 112 additions and 61 deletions
@@ -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,74 +23,25 @@ namespace MistoxWebsite.Server.Controllers {
[HttpPost]
public async Task<string> 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> cart = await _databaseService.GetCart( acc );
if (acc != null) {
List<Cart> cart = await _databaseService.GetCart(acc);
// build Recipt and calculate Tax
var options = new CalculationCreateOptions{
Currency = "usd",
CustomerDetails = new CalculationCustomerDetailsOptions{
AddressSource = "billing",
},
Expand = new List<string>(){ "line_items" },
LineItems = new List<CalculationLineItemOptions>()
};
IPayment PaymentPlugin = new StripeIntent(_databaseService);
List<int> prods = new List<int>();
// 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<string, string> {
{ "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";
}
@@ -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> cart);
}
}
@@ -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> cart) {
try {
// build Recipt and calculate Tax
var options = new CalculationCreateOptions {
Currency = "usd",
CustomerDetails = new CalculationCustomerDetailsOptions {
AddressSource = "billing",
},
Expand = new List<string>() { "line_items" },
LineItems = new List<CalculationLineItemOptions>()
};
List<int> prods = new List<int>();
// 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<string, string> {
{ "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());
}
}
}
}