+ Memberships
- DDD
- FutureCreator
- UserTransactions
This commit is contained in:
2024-10-20 14:01:58 -04:00
parent 3d10427821
commit 28d74503df
117 changed files with 2149 additions and 1999 deletions

View File

@@ -0,0 +1,117 @@
using Hutopy.Web.Common;
using Hutopy.Web.Features.Memberships.Data;
using Hutopy.Web.Features.Memberships.Services;
namespace Hutopy.Web.Features.Memberships.Handlers;
[PublicAPI]
public record SendTipRequest
{
public Guid CreatorId { get; set; }
public required decimal Amount { get; init; }
public required string Currency { get; init; }
public required string Message { get; init; }
public required string CheckoutSuccessUrl { get; init; }
public required string CheckoutCancelledUrl { get; init; }
}
[PublicAPI]
public class SendTipResponse
{
public required string Status { get; init; }
public required string StripeCheckoutUrl { get; init; }
}
[PublicAPI]
public class SendTipRequestValidator : Validator<SendTipRequest>
{
public SendTipRequestValidator()
{
RuleFor(x => x.Amount)
.GreaterThan(0)
.WithMessage("Tip amount must be greater than 0");
RuleFor(x => x.CreatorId)
.NotEmpty()
.WithMessage("Creator ID is required");
RuleFor(x => x.CheckoutSuccessUrl)
.NotEmpty()
.WithMessage("CheckoutSuccessUrl is required");
RuleFor(x => x.CheckoutCancelledUrl)
.NotEmpty()
.WithMessage("CheckoutCancelledUrl is required");
}
}
[PublicAPI]
public class SendTipHandler(
MembershipDbContext dbDbContext,
StripeService stripeService)
: Endpoint<SendTipRequest, SendTipResponse>
{
public override void Configure()
{
Post("/api/tips/{CreatorId}");
Options(o => o.WithTags("Memberships"));
}
public override async Task HandleAsync(
SendTipRequest req,
CancellationToken ct)
{
var userId = User.GetUserId();
var userName = User.GetName();
var creator = await dbDbContext.Creators.FindAsync(
[req.CreatorId],
cancellationToken: ct);
if (creator == null)
{
await SendNotFoundAsync(ct);
return;
}
var checkoutSession = await stripeService.CreateTipCheckoutSession(
userId,
req.Amount,
req.Currency,
creator.Id,
creator.Name,
creator.StripeAccountId,
req.CheckoutSuccessUrl,
req.CheckoutCancelledUrl);
dbDbContext.Tips.Add(
new Tip
{
Id = Guid.NewGuid(),
CreatedAt = DateTimeOffset.UtcNow,
TipperId = userId,
TipperName = userName,
CreatorId = creator.Id,
CreatorName = creator.Name,
Amount = req.Amount,
Currency = req.Currency,
Message = req.Message,
StripeSessionId = checkoutSession.Id
});
dbDbContext.Transactions.Add(
new Transaction
{
Id = Guid.NewGuid(),
StripeCheckoutSessionId = checkoutSession.Id,
Amount = req.Amount,
Type = "Tip",
Timestamp = DateTime.UtcNow
});
await dbDbContext.SaveChangesAsync(ct);
await SendAsync(
new SendTipResponse { Status = "Pending", StripeCheckoutUrl = checkoutSession.Url },
cancellation: ct);
}
}