diff --git a/Directory.Packages.props b/Directory.Packages.props
index ba78a5d..74620e0 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -37,6 +37,7 @@
+
\ No newline at end of file
diff --git a/src/Application/Common/Interfaces/IStripeService.cs b/src/Application/Common/Interfaces/IStripeService.cs
new file mode 100644
index 0000000..1231a8e
--- /dev/null
+++ b/src/Application/Common/Interfaces/IStripeService.cs
@@ -0,0 +1,7 @@
+namespace Hutopy.Application.Common.Interfaces;
+
+
+public interface IStripeService
+{
+ public Task CreateCheckoutSession(int price, string currency);
+}
diff --git a/src/Application/Stripe/Commands/CreateSessionCheckoutCommand.cs b/src/Application/Stripe/Commands/CreateSessionCheckoutCommand.cs
new file mode 100644
index 0000000..3fa96c0
--- /dev/null
+++ b/src/Application/Stripe/Commands/CreateSessionCheckoutCommand.cs
@@ -0,0 +1,31 @@
+using Hutopy.Application.Common.Interfaces;
+
+
+namespace Hutopy.Application.Stripe.Commands;
+public record CreateSessionCheckoutCommand : IRequest
+{
+ public required int Price { get; init; }
+
+ public string Currency { get; init; } = "cad";
+}
+
+
+public class CreateSessionCheckoutCommandHandler : IRequestHandler
+{
+ private readonly IApplicationDbContext _context;
+ private readonly IStripeService _stripeService;
+
+
+ public CreateSessionCheckoutCommandHandler(IApplicationDbContext context, IStripeService stripeService)
+ {
+ _context = context;
+ _stripeService = stripeService;
+ }
+
+ public async Task Handle(CreateSessionCheckoutCommand request, CancellationToken cancellationToken)
+ {
+ var stripeSecret = await _stripeService.CreateCheckoutSession(request.Price, request.Currency);
+
+ return stripeSecret;
+ }
+}
diff --git a/src/Infrastructure/DependencyInjection.cs b/src/Infrastructure/DependencyInjection.cs
index f466e8f..7481df3 100644
--- a/src/Infrastructure/DependencyInjection.cs
+++ b/src/Infrastructure/DependencyInjection.cs
@@ -3,6 +3,7 @@ using Hutopy.Domain.Constants;
using Hutopy.Infrastructure.Data;
using Hutopy.Infrastructure.Data.Interceptors;
using Hutopy.Infrastructure.Identity;
+using Hutopy.Infrastructure.Stripe;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
@@ -49,6 +50,7 @@ public static class DependencyInjection
services.AddSingleton(TimeProvider.System);
services.AddTransient();
+ services.AddTransient();
services.AddAuthorization(options =>
options.AddPolicy(Policies.CanPurge, policy => policy.RequireRole(Roles.Administrator)));
diff --git a/src/Infrastructure/Infrastructure.csproj b/src/Infrastructure/Infrastructure.csproj
index ab862ba..2958bd6 100644
--- a/src/Infrastructure/Infrastructure.csproj
+++ b/src/Infrastructure/Infrastructure.csproj
@@ -4,18 +4,19 @@
Hutopy.Infrastructure
-
-
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
-
-
-
+
+
+
+
+
-
+
diff --git a/src/Infrastructure/Stripe/StripeService.cs b/src/Infrastructure/Stripe/StripeService.cs
new file mode 100644
index 0000000..dc18c62
--- /dev/null
+++ b/src/Infrastructure/Stripe/StripeService.cs
@@ -0,0 +1,46 @@
+using Stripe;
+using Stripe.Checkout;
+using Hutopy.Application.Common.Interfaces;
+
+
+namespace Hutopy.Infrastructure.Stripe;
+
+public class StripeService : IStripeService
+{
+ public StripeService()
+ {
+ // I removed the key to push. Will need to be in config.
+ StripeConfiguration.ApiKey = "";
+ }
+
+ public async Task CreateCheckoutSession(int price, string currency = "cad")
+ {
+ var options = new SessionCreateOptions
+ {
+ LineItems = new List
+ {
+ new SessionLineItemOptions
+ {
+ PriceData = new SessionLineItemPriceDataOptions
+ {
+ UnitAmount = price,
+ Currency = currency,
+ ProductData = new SessionLineItemPriceDataProductDataOptions
+ {
+ Name = "Tip",
+ },
+ },
+ Quantity = 1,
+ },
+ },
+ Mode = "payment",
+ UiMode = "embedded",
+ ReturnUrl = "http://localhost:5174",
+ };
+
+ var service = new SessionService();
+ Session session = await service.CreateAsync(options);
+
+ return session.ClientSecret;
+ }
+}
diff --git a/src/Web/Endpoints/Stripe.cs b/src/Web/Endpoints/Stripe.cs
new file mode 100644
index 0000000..c7753b0
--- /dev/null
+++ b/src/Web/Endpoints/Stripe.cs
@@ -0,0 +1,17 @@
+using Hutopy.Application.Stripe.Commands;
+
+namespace Hutopy.Web.Endpoints;
+
+public class Stripe : EndpointGroupBase
+{
+ public override void Map(WebApplication app)
+ {
+ app.MapGroup(this)
+ .MapPost(CreateSessionCheckout);
+ }
+
+ public Task CreateSessionCheckout(ISender sender, CreateSessionCheckoutCommand command)
+ {
+ return sender.Send(command);
+ }
+}
diff --git a/src/Web/wwwroot/api/specification.json b/src/Web/wwwroot/api/specification.json
index c4ab40c..158be32 100644
--- a/src/Web/wwwroot/api/specification.json
+++ b/src/Web/wwwroot/api/specification.json
@@ -39,6 +39,38 @@
}
}
},
+ "/api/Stripe": {
+ "post": {
+ "tags": [
+ "Stripe"
+ ],
+ "operationId": "CreateSessionCheckout",
+ "requestBody": {
+ "x-name": "command",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateSessionCheckoutCommand"
+ }
+ }
+ },
+ "required": true,
+ "x-position": 1
+ },
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/api/TodoItems": {
"get": {
"tags": [
@@ -814,6 +846,19 @@
}
}
},
+ "CreateSessionCheckoutCommand": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "price": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "currency": {
+ "type": "string"
+ }
+ }
+ },
"PaginatedListOfTodoItemBriefDto": {
"type": "object",
"additionalProperties": false,