fix(stripe): correcting webhook

This commit is contained in:
2025-08-04 16:31:54 -04:00
parent c0a1eabecb
commit 18532963a8
2 changed files with 149 additions and 137 deletions

View File

@@ -8,11 +8,10 @@ using Stripe.Checkout;
namespace Hutopy.Modules.Memberships.Handlers;
public class StripeWebhookEndpoint(
internal class StripeWebhookEndpoint(
ITipPaymentNotifier tipPaymentNotifier,
IMembershipNotifier membershipNotifier,
IOptions<StripeOptions> options,
ILogger<StripeWebhookEndpoint> logger)
IOptions<StripeOptions> options)
: EndpointWithoutRequest
{
public override void Configure()
@@ -24,10 +23,11 @@ public class StripeWebhookEndpoint(
public override async Task HandleAsync(CancellationToken ct)
{
using StreamReader streamReader = new(HttpContext.Request.Body);
var json = await streamReader.ReadToEndAsync(ct);
var signatureHeader = HttpContext.Request.Headers["Stripe-Signature"];
using StreamReader streamReader = new(HttpContext.Request.Body);
var json = await streamReader.ReadToEndAsync(ct).ConfigureAwait(false);
var stripeEvent = EventUtility.ConstructEvent(json, signatureHeader, options.Value.WebhookSecret);
var stripeSession = stripeEvent.Data.Object as Session;
@@ -37,16 +37,10 @@ public class StripeWebhookEndpoint(
{
case "checkout.session.completed":
Debug.Assert(stripeSession != null);
logger.LogWarning(stripeSession.ToJson());
logger.LogWarning("stripeSession.PaymentIntentId: {PaymentIntentId}", stripeSession.PaymentIntentId);
logger.LogWarning("stripeSession.PaymentIntent.Status: {PaymentIntentStatus}", stripeSession.PaymentIntent.Status);
logger.LogWarning(stripeSession.ToJson());
logger.LogWarning(stripeSession.ToJson());
switch (stripeSession.Mode)
{
// Check if this is a one-time tip
case "payment" when stripeSession.PaymentIntentId != null
&& stripeSession.PaymentIntent.Status == "paid":
case "payment" when stripeSession is { PaymentIntentId: not null, PaymentStatus: "paid" }:
// Get the customer email from the appropriate place
var customerEmail = stripeSession.CustomerDetails?.Email ??
stripeSession.Customer?.Email ??
@@ -55,21 +49,25 @@ public class StripeWebhookEndpoint(
// Get the receipt URL, preferring the one directly on the charge if available
var receiptUrl = stripeSession.Invoice?.HostedInvoiceUrl ?? "";
await tipPaymentNotifier.NotifyPaymentSucceedAsync(
stripeSession.Id,
receiptUrl,
customerEmail,
ct);
await tipPaymentNotifier
.NotifyPaymentSucceedAsync(
stripeSession.Id,
receiptUrl,
customerEmail,
ct)
.ConfigureAwait(false);
break;
// Check if this is a subscription
case "subscription" when stripeSession.SubscriptionId != null:
await membershipNotifier.NotifyPaymentSucceedAsync(
stripeSession.SubscriptionId,
stripeSession.Invoice.HostedInvoiceUrl,
stripeSession.Invoice.Total,
stripeSession.Invoice.Currency,
ct);
await membershipNotifier
.NotifyPaymentSucceedAsync(
stripeSession.SubscriptionId,
stripeSession.Invoice.HostedInvoiceUrl,
stripeSession.Invoice.Total,
stripeSession.Invoice.Currency,
ct)
.ConfigureAwait(false);
break;
}
@@ -78,29 +76,35 @@ public class StripeWebhookEndpoint(
var invoice = stripeEvent.Data.Object as Invoice;
Debug.Assert(invoice != null);
Debug.Assert(invoice.Subscription != null);
await membershipNotifier.NotifyPaymentSucceedAsync(
invoice.SubscriptionId,
invoice.HostedInvoiceUrl,
invoice.Total,
invoice.Currency,
ct);
await membershipNotifier
.NotifyPaymentSucceedAsync(
invoice.SubscriptionId,
invoice.HostedInvoiceUrl,
invoice.Total,
invoice.Currency,
ct)
.ConfigureAwait(false);
break;
case "customer.subscription.updated":
Debug.Assert(stripeSubscription != null);
await membershipNotifier.NotifySubscriptionUpdatedAsync(
stripeSubscription.Id,
stripeSubscription.CancelAt ?? stripeSubscription.CanceledAt,
ct);
await membershipNotifier
.NotifySubscriptionUpdatedAsync(
stripeSubscription.Id,
stripeSubscription.CancelAt ?? stripeSubscription.CanceledAt,
ct)
.ConfigureAwait(false);
break;
case "customer.subscription.deleted":
Debug.Assert(stripeSubscription != null);
await membershipNotifier.NotifySubscriptionDeletedAsync(
stripeSubscription.Id,
ct);
await membershipNotifier
.NotifySubscriptionDeletedAsync(
stripeSubscription.Id,
ct)
.ConfigureAwait(false);
break;
}
await SendOkAsync(ct);
await SendOkAsync(ct).ConfigureAwait(false);
}
}