60 lines
1.8 KiB
C#
60 lines
1.8 KiB
C#
using System.Security.Claims;
|
|
using FastEndpoints;
|
|
using FluentValidation;
|
|
using TrackQrApi.Features.Auth.Common;
|
|
using TrackQrApi.Features.Billing.Common;
|
|
using TrackQrApi.Features.Billing.Services;
|
|
|
|
namespace TrackQrApi.Features.Billing.Endpoints;
|
|
|
|
public class CreatePortalSessionValidator : Validator<PortalSessionRequest>
|
|
{
|
|
public CreatePortalSessionValidator()
|
|
{
|
|
RuleFor(x => x.ReturnUrl).NotEmpty().Must(BeValidUrl);
|
|
}
|
|
|
|
private static bool BeValidUrl(string url)
|
|
{
|
|
return Uri.TryCreate(url, UriKind.Absolute, out var uri)
|
|
&& (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps);
|
|
}
|
|
}
|
|
|
|
public class CreatePortalSessionEndpoint(IStripeService stripeService)
|
|
: Endpoint<PortalSessionRequest, PortalSessionResponse>
|
|
{
|
|
public override void Configure()
|
|
{
|
|
Post("/billing/portal");
|
|
}
|
|
|
|
public override async Task HandleAsync(PortalSessionRequest req, CancellationToken ct)
|
|
{
|
|
var userId = Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
|
|
|
|
try
|
|
{
|
|
var portalUrl = await stripeService.CreateCustomerPortalSessionAsync(
|
|
userId,
|
|
req.ReturnUrl,
|
|
ct);
|
|
|
|
await HttpContext.Response.SendAsync(new PortalSessionResponse(portalUrl), cancellation: ct);
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
await HttpContext.Response.SendAsync(
|
|
new MessageResponse(ex.Message),
|
|
400,
|
|
cancellation: ct);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await HttpContext.Response.SendAsync(
|
|
new MessageResponse($"Failed to create portal session: {ex.Message}"),
|
|
500,
|
|
cancellation: ct);
|
|
}
|
|
}
|
|
} |