Browse Source

refactoring continues

AC-1527-refactor-the-stripe-webhook-logic
Cy Okeke 2 years ago
parent
commit
7c5724e48f
No known key found for this signature in database
GPG Key ID: B758F6C46EB146A2
  1. 9
      src/Billing/Services/Implementations/ChargeSucceededHandler.cs
  2. 33
      src/Billing/Services/Implementations/InvoiceCreatedHandler.cs
  3. 105
      src/Billing/Services/Implementations/PaymentMethodAttachedHandler.cs
  4. 7
      src/Billing/Services/Implementations/PaymentSucceededHandler.cs
  5. 9
      src/Billing/Services/Implementations/SubscriptionUpdatedHandler.cs

9
src/Billing/Services/Implementations/ChargeSucceededHandler.cs

@ -15,16 +15,19 @@ public class ChargeSucceededHandler : StripeWebhookHandler @@ -15,16 +15,19 @@ public class ChargeSucceededHandler : StripeWebhookHandler
private readonly ITransactionRepository _transactionRepository;
private readonly ILogger<StripeController> _logger;
private readonly IStripeEventService _stripeEventService;
private readonly IWebhookUtility _webhookUtility;
public ChargeSucceededHandler(
ITransactionRepository transactionRepository,
ILogger<StripeController> logger,
IStripeEventService stripeEventService)
IStripeEventService stripeEventService,
IWebhookUtility webhookUtility)
{
_transactionRepository = transactionRepository;
_logger = logger;
_stripeEventService = stripeEventService;
_webhookUtility = webhookUtility;
}
protected override bool CanHandle(Event parsedEvent)
@ -54,7 +57,7 @@ public class ChargeSucceededHandler : StripeWebhookHandler @@ -54,7 +57,7 @@ public class ChargeSucceededHandler : StripeWebhookHandler
if (invoice?.SubscriptionId != null)
{
subscription = await subscriptionService.GetAsync(invoice.SubscriptionId);
ids = GetIdsFromMetaData(subscription?.Metadata);
ids = _webhookUtility.GetIdsFromMetaData(subscription?.Metadata);
}
}
@ -68,7 +71,7 @@ public class ChargeSucceededHandler : StripeWebhookHandler @@ -68,7 +71,7 @@ public class ChargeSucceededHandler : StripeWebhookHandler
{
if (sub.Status != StripeSubscriptionStatus.Canceled && sub.Status != StripeSubscriptionStatus.IncompleteExpired)
{
ids = GetIdsFromMetaData(sub.Metadata);
ids = _webhookUtility.GetIdsFromMetaData(sub.Metadata);
if (ids.Item1.HasValue || ids.Item2.HasValue)
{
subscription = sub;

33
src/Billing/Services/Implementations/InvoiceCreatedHandler.cs

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
using Bit.Billing.Constants;
using Microsoft.AspNetCore.Mvc;
using Stripe;
namespace Bit.Billing.Services.Implementations;
public class InvoiceCreatedHandler : StripeWebhookHandler
{
private readonly IStripeEventService _stripeEventService;
private readonly IWebhookUtility _webhookUtility;
public InvoiceCreatedHandler(IStripeEventService stripeEventService,
IWebhookUtility webhookUtility)
{
_stripeEventService = stripeEventService;
_webhookUtility = webhookUtility;
}
protected override bool CanHandle(Event parsedEvent)
{
return parsedEvent.Type.Equals(HandledStripeWebhook.InvoiceCreated);
}
protected override async Task<IActionResult> ProcessEvent(Event parsedEvent)
{
var invoice = await _stripeEventService.GetInvoice(parsedEvent, true);
if (!invoice.Paid && _webhookUtility.UnpaidAutoChargeInvoiceForSubscriptionCycle(invoice))
{
await _webhookUtility.AttemptToPayInvoice(invoice);
}
return new OkResult();
}
}

105
src/Billing/Services/Implementations/PaymentMethodAttachedHandler.cs

@ -0,0 +1,105 @@ @@ -0,0 +1,105 @@
using Bit.Billing.Constants;
using Microsoft.AspNetCore.Mvc;
using Stripe;
namespace Bit.Billing.Services.Implementations;
public class PaymentMethodAttachedHandler : StripeWebhookHandler
{
private readonly IStripeEventService _stripeEventService;
private readonly IWebhookUtility _webhookUtility;
private readonly ILogger<PaymentMethodAttachedHandler> _logger;
public PaymentMethodAttachedHandler(IStripeEventService stripeEventService,
IWebhookUtility webhookUtility,
ILogger<PaymentMethodAttachedHandler> logger)
{
_stripeEventService = stripeEventService;
_webhookUtility = webhookUtility;
_logger = logger;
}
protected override bool CanHandle(Event parsedEvent)
{
return parsedEvent.Type.Equals(HandledStripeWebhook.InvoiceCreated);
}
protected override async Task<IActionResult> ProcessEvent(Event parsedEvent)
{
var paymentMethod = await _stripeEventService.GetPaymentMethod(parsedEvent);
await HandlePaymentMethodAttachedAsync(paymentMethod);
return new OkResult();
}
private async Task HandlePaymentMethodAttachedAsync(PaymentMethod paymentMethod)
{
if (paymentMethod is null)
{
_logger.LogWarning("Attempted to handle the event payment_method.attached but paymentMethod was null");
return;
}
var subscriptionService = new SubscriptionService();
var subscriptionListOptions = new SubscriptionListOptions
{
Customer = paymentMethod.CustomerId,
Status = StripeSubscriptionStatus.Unpaid,
Expand = new List<string> { "data.latest_invoice" }
};
StripeList<Subscription> unpaidSubscriptions;
try
{
unpaidSubscriptions = await subscriptionService.ListAsync(subscriptionListOptions);
}
catch (Exception e)
{
_logger.LogError(e,
"Attempted to get unpaid invoices for customer {CustomerId} but encountered an error while calling Stripe",
paymentMethod.CustomerId);
return;
}
foreach (var unpaidSubscription in unpaidSubscriptions)
{
await AttemptToPayOpenSubscriptionAsync(unpaidSubscription);
}
}
private async Task AttemptToPayOpenSubscriptionAsync(Subscription unpaidSubscription)
{
var latestInvoice = unpaidSubscription.LatestInvoice;
if (unpaidSubscription.LatestInvoice is null)
{
_logger.LogWarning(
"Attempted to pay unpaid subscription {SubscriptionId} but latest invoice didn't exist",
unpaidSubscription.Id);
return;
}
if (latestInvoice.Status != StripeInvoiceStatus.Open)
{
_logger.LogWarning(
"Attempted to pay unpaid subscription {SubscriptionId} but latest invoice wasn't \"open\"",
unpaidSubscription.Id);
return;
}
try
{
await _webhookUtility.AttemptToPayInvoice(latestInvoice, true);
}
catch (Exception e)
{
_logger.LogError(e,
"Attempted to pay open invoice {InvoiceId} on unpaid subscription {SubscriptionId} but encountered an error",
latestInvoice.Id, unpaidSubscription.Id);
throw;
}
}
}

7
src/Billing/Services/Implementations/PaymentSucceededHandler.cs

@ -21,6 +21,7 @@ public class PaymentSucceededHandler : StripeWebhookHandler @@ -21,6 +21,7 @@ public class PaymentSucceededHandler : StripeWebhookHandler
private readonly ICurrentContext _currentContext;
private readonly IUserService _userService;
private readonly IUserRepository _userRepository;
private readonly IWebhookUtility _webhookUtility;
public PaymentSucceededHandler(IStripeEventService stripeEventService,
IOrganizationService organizationService,
@ -28,7 +29,8 @@ public class PaymentSucceededHandler : StripeWebhookHandler @@ -28,7 +29,8 @@ public class PaymentSucceededHandler : StripeWebhookHandler
IReferenceEventService referenceEventService,
ICurrentContext currentContext,
IUserService userService,
IUserRepository userRepository)
IUserRepository userRepository,
IWebhookUtility webhookUtility)
{
_stripeEventService = stripeEventService;
_organizationService = organizationService;
@ -37,6 +39,7 @@ public class PaymentSucceededHandler : StripeWebhookHandler @@ -37,6 +39,7 @@ public class PaymentSucceededHandler : StripeWebhookHandler
_currentContext = currentContext;
_userService = userService;
_userRepository = userRepository;
_webhookUtility = webhookUtility;
}
protected override bool CanHandle(Event parsedEvent)
{
@ -57,7 +60,7 @@ public class PaymentSucceededHandler : StripeWebhookHandler @@ -57,7 +60,7 @@ public class PaymentSucceededHandler : StripeWebhookHandler
await Task.Delay(5000);
}
var ids = GetIdsFromMetaData(subscription.Metadata);
var ids = _webhookUtility.GetIdsFromMetaData(subscription.Metadata);
// org
if (ids.Item1.HasValue)
{

9
src/Billing/Services/Implementations/SubscriptionUpdatedHandler.cs

@ -12,16 +12,19 @@ public class SubscriptionUpdatedHandler : StripeWebhookHandler @@ -12,16 +12,19 @@ public class SubscriptionUpdatedHandler : StripeWebhookHandler
private readonly IUserService _userService;
private readonly IStripeEventService _stripeEventService;
private readonly IOrganizationSponsorshipRenewCommand _organizationSponsorshipRenewCommand;
private readonly IWebhookUtility _webhookUtility;
public SubscriptionUpdatedHandler(IOrganizationService organizationService,
IUserService userService,
IStripeEventService stripeEventService,
IOrganizationSponsorshipRenewCommand organizationSponsorshipRenewCommand)
IOrganizationSponsorshipRenewCommand organizationSponsorshipRenewCommand,
IWebhookUtility webhookUtility)
{
_organizationService = organizationService;
_userService = userService;
_stripeEventService = stripeEventService;
_organizationSponsorshipRenewCommand = organizationSponsorshipRenewCommand;
_webhookUtility = webhookUtility;
}
protected override bool CanHandle(Event parsedEvent)
{
@ -33,7 +36,7 @@ public class SubscriptionUpdatedHandler : StripeWebhookHandler @@ -33,7 +36,7 @@ public class SubscriptionUpdatedHandler : StripeWebhookHandler
if (parsedEvent.Type.Equals(HandledStripeWebhook.SubscriptionUpdated))
{
var subscription = await _stripeEventService.GetSubscription(parsedEvent, true);
var ids = GetIdsFromMetaData(subscription.Metadata);
var ids = _webhookUtility.GetIdsFromMetaData(subscription.Metadata);
var organizationId = ids.Item1 ?? Guid.Empty;
var userId = ids.Item2 ?? Guid.Empty;
var subActive = subscription.Status == StripeSubscriptionStatus.Active;
@ -51,7 +54,7 @@ public class SubscriptionUpdatedHandler : StripeWebhookHandler @@ -51,7 +54,7 @@ public class SubscriptionUpdatedHandler : StripeWebhookHandler
await _organizationService.UpdateExpirationDateAsync(organizationId, subscription.CurrentPeriodEnd);
if (IsSponsoredSubscription(subscription))
if (_webhookUtility.IsSponsoredSubscription(subscription))
{
await _organizationSponsorshipRenewCommand.UpdateExpirationDateAsync(organizationId,
subscription.CurrentPeriodEnd);

Loading…
Cancel
Save