1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-25 12:45:18 +01:00

Retrieve all Stripe invoices (#3431)

This commit is contained in:
Alex Morask 2023-11-09 09:05:05 -05:00 committed by GitHub
parent 95680b434b
commit 8f4a1d8639
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 9 deletions

View File

@ -0,0 +1,27 @@
using Stripe;
namespace Bit.Core.Models.BitStripe;
/// <summary>
/// A model derived from the Stripe <see cref="InvoiceListOptions"/> class that includes a flag used to
/// retrieve all invoices from the Stripe API rather than a limited set.
/// </summary>
public class StripeInvoiceListOptions : InvoiceListOptions
{
public bool SelectAll { get; set; }
public InvoiceListOptions ToInvoiceListOptions()
{
var options = (InvoiceListOptions)this;
if (!SelectAll)
{
return options;
}
options.EndingBefore = null;
options.StartingAfter = null;
return options;
}
}

View File

@ -18,7 +18,7 @@ public interface IStripeAdapter
Task<Stripe.Invoice> InvoiceCreateAsync(Stripe.InvoiceCreateOptions options); Task<Stripe.Invoice> InvoiceCreateAsync(Stripe.InvoiceCreateOptions options);
Task<Stripe.InvoiceItem> InvoiceItemCreateAsync(Stripe.InvoiceItemCreateOptions options); Task<Stripe.InvoiceItem> InvoiceItemCreateAsync(Stripe.InvoiceItemCreateOptions options);
Task<Stripe.Invoice> InvoiceGetAsync(string id, Stripe.InvoiceGetOptions options); Task<Stripe.Invoice> InvoiceGetAsync(string id, Stripe.InvoiceGetOptions options);
Task<Stripe.StripeList<Stripe.Invoice>> InvoiceListAsync(Stripe.InvoiceListOptions options); Task<List<Stripe.Invoice>> InvoiceListAsync(StripeInvoiceListOptions options);
IEnumerable<InvoiceItem> InvoiceItemListAsync(InvoiceItemListOptions options); IEnumerable<InvoiceItem> InvoiceItemListAsync(InvoiceItemListOptions options);
Task<Stripe.Invoice> InvoiceUpdateAsync(string id, Stripe.InvoiceUpdateOptions options); Task<Stripe.Invoice> InvoiceUpdateAsync(string id, Stripe.InvoiceUpdateOptions options);
Task<Stripe.Invoice> InvoiceFinalizeInvoiceAsync(string id, Stripe.InvoiceFinalizeOptions options); Task<Stripe.Invoice> InvoiceFinalizeInvoiceAsync(string id, Stripe.InvoiceFinalizeOptions options);

View File

@ -97,9 +97,23 @@ public class StripeAdapter : IStripeAdapter
return _invoiceService.GetAsync(id, options); return _invoiceService.GetAsync(id, options);
} }
public Task<Stripe.StripeList<Stripe.Invoice>> InvoiceListAsync(Stripe.InvoiceListOptions options) public async Task<List<Stripe.Invoice>> InvoiceListAsync(StripeInvoiceListOptions options)
{ {
return _invoiceService.ListAsync(options); if (!options.SelectAll)
{
return (await _invoiceService.ListAsync(options.ToInvoiceListOptions())).Data;
}
options.Limit = 100;
var invoices = new List<Stripe.Invoice>();
await foreach (var invoice in _invoiceService.ListAutoPagingAsync(options.ToInvoiceListOptions()))
{
invoices.Add(invoice);
}
return invoices;
} }
public IEnumerable<InvoiceItem> InvoiceItemListAsync(InvoiceItemListOptions options) public IEnumerable<InvoiceItem> InvoiceItemListAsync(InvoiceItemListOptions options)

View File

@ -2,6 +2,7 @@
using Bit.Core.Entities; using Bit.Core.Entities;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.BitStripe;
using Bit.Core.Models.Business; using Bit.Core.Models.Business;
using Bit.Core.Repositories; using Bit.Core.Repositories;
using Bit.Core.Settings; using Bit.Core.Settings;
@ -668,7 +669,7 @@ public class StripePaymentService : IPaymentService
if (!stripePaymentMethod && subInvoiceMetadata.Any()) if (!stripePaymentMethod && subInvoiceMetadata.Any())
{ {
var invoices = await _stripeAdapter.InvoiceListAsync(new Stripe.InvoiceListOptions var invoices = await _stripeAdapter.InvoiceListAsync(new StripeInvoiceListOptions
{ {
Subscription = subscription.Id Subscription = subscription.Id
}); });
@ -2138,15 +2139,26 @@ public class StripePaymentService : IPaymentService
return null; return null;
} }
var invoices = await _stripeAdapter.InvoiceListAsync(new Stripe.InvoiceListOptions var options = new StripeInvoiceListOptions
{ {
Customer = customer.Id, Customer = customer.Id,
Limit = 50 SelectAll = true
}); };
return invoices.Data.Where(i => i.Status != "void" && i.Status != "draft") try
.OrderByDescending(i => i.Created).Select(i => new BillingInfo.BillingInvoice(i)); {
var invoices = await _stripeAdapter.InvoiceListAsync(options);
return invoices
.Where(invoice => invoice.Status != "void" && invoice.Status != "draft")
.OrderByDescending(invoice => invoice.Created)
.Select(invoice => new BillingInfo.BillingInvoice(invoice));
}
catch (Stripe.StripeException exception)
{
_logger.LogError(exception, "An error occurred while listing Stripe invoices");
throw new GatewayException("Failed to retrieve current invoices", exception);
}
} }
// We are taking only first 30 characters of the SubscriberName because stripe provide // We are taking only first 30 characters of the SubscriberName because stripe provide