From 05028d9d15285818c5acb89da069541ed04450fa Mon Sep 17 00:00:00 2001 From: Filip Bekic Date: Mon, 30 Sep 2024 11:54:07 +0200 Subject: [PATCH] Update Stripe event handler --- .../EventHandler/EventHandlerFeature.cs | 136 ++++++++++++++---- 1 file changed, 110 insertions(+), 26 deletions(-) diff --git a/backend/ResQueue/ResQueue/Features/Stripe/EventHandler/EventHandlerFeature.cs b/backend/ResQueue/ResQueue/Features/Stripe/EventHandler/EventHandlerFeature.cs index efde1c9..b3d9d9e 100644 --- a/backend/ResQueue/ResQueue/Features/Stripe/EventHandler/EventHandlerFeature.cs +++ b/backend/ResQueue/ResQueue/Features/Stripe/EventHandler/EventHandlerFeature.cs @@ -27,42 +27,126 @@ public async Task> ExecuteAsync(EventHandl settings.Value.StripeSecretWebhook ); - if (stripeEvent.Type == Events.CustomerSubscriptionDeleted) + switch (stripeEvent.Type) { - var subscription = stripeEvent.Data.Object as Subscription; - - var user = await userManager.FirstOrDefaultByStripeId(subscription!.CustomerId); - if (user is null) + case Events.CustomerSubscriptionDeleted or Events.CustomerSubscriptionUpdated: { - return OperationResult.Failure(new ProblemDetails + var subscription = stripeEvent.Data.Object as Subscription; + + var user = await userManager.FirstOrDefaultByStripeId(subscription!.CustomerId); + if (user is null) { - Title = "Unauthorized Access", - Detail = "The user could not be found or is not authorized.", - Status = StatusCodes.Status401Unauthorized - }); - } + return OperationResult.Failure(new ProblemDetails + { + Title = "Unauthorized Access", + Detail = "The user could not be found or is not authorized.", + Status = StatusCodes.Status401Unauthorized + }); + } + + if (user.Subscription?.StripeId != subscription.Id) + { + return OperationResult.Failure(new ProblemDetails + { + Title = "Invalid Subscription", + Detail = "The subscription does not match the user's records.", + Status = StatusCodes.Status400BadRequest + }); + } - if (user.Subscription?.StripeId != subscription.Id) + user.Subscription.StripeStatus = subscription.Status; + + var filter = Builders.Filter.Eq(q => q.Id, user.Id); + var update = Builders.Update + .Set(q => q.Subscription, user.Subscription); + + await usersCollection.UpdateOneAsync(filter, update); + break; + } + case Events.InvoicePaymentFailed or Events.InvoicePaymentSucceeded: { - return OperationResult.Failure(new ProblemDetails + var invoice = stripeEvent.Data.Object as Invoice; + var subscriptionId = invoice?.SubscriptionId; + var subscriptionService = new SubscriptionService(); + var subscription = await subscriptionService.GetAsync(subscriptionId); + + var user = await userManager.FirstOrDefaultByStripeId(subscription.CustomerId); + + if (user is not null) { - Title = "Invalid Subscription", - Detail = "The subscription does not match the user's records.", - Status = StatusCodes.Status400BadRequest - }); + if (user.Subscription is not null) + { + user.Subscription.StripeStatus = subscription.Status; + + var filter = Builders.Filter.Eq(q => q.Id, user.Id); + var update = Builders.Update.Set(q => q.Subscription!.StripeStatus, + user.Subscription.StripeStatus); + await usersCollection.UpdateOneAsync(filter, update); + } + else + { + return OperationResult.Failure(new ProblemDetails + { + Title = "Subscription Not Found", + Detail = "No subscription found for provided user.", + Status = StatusCodes.Status404NotFound + }); + } + } + else + { + return OperationResult.Failure(new ProblemDetails + { + Title = "User Not Found", + Detail = "No user found with the provided Stripe customer ID.", + Status = StatusCodes.Status404NotFound + }); + } + + break; } + case Events.PaymentIntentSucceeded or Events.PaymentIntentPaymentFailed: + { + var paymentIntent = stripeEvent.Data.Object as PaymentIntent; + var subscriptionId = paymentIntent?.Metadata["subscription_id"]; + var subscriptionService = new SubscriptionService(); + var subscription = await subscriptionService.GetAsync(subscriptionId); + + var user = await userManager.FirstOrDefaultByStripeId(subscription.CustomerId); - user.Subscription.StripeStatus = subscription.Status; + if (user is not null) + { + if (user.Subscription is not null) + { + user.Subscription.StripeStatus = subscription.Status; - var filter = Builders.Filter.Eq(q => q.Id, user.Id); - var update = Builders.Update - .Set(q => q.Subscription, user.Subscription); + var filter = Builders.Filter.Eq(q => q.Id, user.Id); + var update = Builders.Update.Set(q => q.Subscription!.StripeStatus, + user.Subscription.StripeStatus); + await usersCollection.UpdateOneAsync(filter, update); + } + else + { + return OperationResult.Failure(new ProblemDetails + { + Title = "Subscription Not Found", + Detail = "No subscription found for provided user.", + Status = StatusCodes.Status404NotFound + }); + } + } + else + { + return OperationResult.Failure(new ProblemDetails + { + Title = "User Not Found", + Detail = "No user found with the provided Stripe customer ID.", + Status = StatusCodes.Status404NotFound + }); + } - await usersCollection.UpdateOneAsync(filter, update); - } - else if (stripeEvent.Type == Events.InvoicePaymentFailed) - { - // todo: send e-mail to the user + break; + } } return OperationResult.Success(new EventHandlerResponse());