diff --git a/src/Api/Billing/Controllers/AccountsBillingController.cs b/src/Api/Billing/Controllers/AccountsBillingController.cs index a72d79673..574ac3e65 100644 --- a/src/Api/Billing/Controllers/AccountsBillingController.cs +++ b/src/Api/Billing/Controllers/AccountsBillingController.cs @@ -1,4 +1,5 @@ -using Bit.Api.Billing.Models.Responses; +#nullable enable +using Bit.Api.Billing.Models.Responses; using Bit.Core.Billing.Services; using Bit.Core.Services; using Bit.Core.Utilities; @@ -43,7 +44,7 @@ public class AccountsBillingController( } [HttpGet("invoices")] - public async Task GetInvoicesAsync([FromQuery] string startAfter = null) + public async Task GetInvoicesAsync([FromQuery] string? status = null, [FromQuery] string? startAfter = null) { var user = await userService.GetUserByPrincipalAsync(User); if (user == null) @@ -54,6 +55,7 @@ public class AccountsBillingController( var invoices = await paymentHistoryService.GetInvoiceHistoryAsync( user, 5, + status, startAfter); return TypedResults.Ok(invoices); diff --git a/src/Api/Billing/Controllers/OrganizationBillingController.cs b/src/Api/Billing/Controllers/OrganizationBillingController.cs index 8d926ec9f..f6ba87c71 100644 --- a/src/Api/Billing/Controllers/OrganizationBillingController.cs +++ b/src/Api/Billing/Controllers/OrganizationBillingController.cs @@ -1,4 +1,5 @@ -using Bit.Api.Billing.Models.Requests; +#nullable enable +using Bit.Api.Billing.Models.Requests; using Bit.Api.Billing.Models.Responses; using Bit.Core; using Bit.Core.Billing.Services; @@ -63,7 +64,7 @@ public class OrganizationBillingController( } [HttpGet("invoices")] - public async Task GetInvoicesAsync([FromRoute] Guid organizationId, [FromQuery] string startAfter = null) + public async Task GetInvoicesAsync([FromRoute] Guid organizationId, [FromQuery] string? status = null, [FromQuery] string? startAfter = null) { if (!await currentContext.ViewBillingHistory(organizationId)) { @@ -80,6 +81,7 @@ public class OrganizationBillingController( var invoices = await paymentHistoryService.GetInvoiceHistoryAsync( organization, 5, + status, startAfter); return TypedResults.Ok(invoices); diff --git a/src/Core/Billing/Services/IPaymentHistoryService.cs b/src/Core/Billing/Services/IPaymentHistoryService.cs index e38659b94..c2e1a7df8 100644 --- a/src/Core/Billing/Services/IPaymentHistoryService.cs +++ b/src/Core/Billing/Services/IPaymentHistoryService.cs @@ -1,4 +1,5 @@ -using Bit.Core.Billing.Models; +#nullable enable +using Bit.Core.Billing.Models; using Bit.Core.Entities; namespace Bit.Core.Billing.Services; @@ -8,7 +9,8 @@ public interface IPaymentHistoryService Task> GetInvoiceHistoryAsync( ISubscriber subscriber, int pageSize = 5, - string startAfter = null); + string? status = null, + string? startAfter = null); Task> GetTransactionHistoryAsync( ISubscriber subscriber, diff --git a/src/Core/Billing/Services/Implementations/PaymentHistoryService.cs b/src/Core/Billing/Services/Implementations/PaymentHistoryService.cs index 1e5e3ea0e..69e1a4cfb 100644 --- a/src/Core/Billing/Services/Implementations/PaymentHistoryService.cs +++ b/src/Core/Billing/Services/Implementations/PaymentHistoryService.cs @@ -1,4 +1,5 @@ -using Bit.Core.AdminConsole.Entities; +#nullable enable +using Bit.Core.AdminConsole.Entities; using Bit.Core.Billing.Models; using Bit.Core.Entities; using Bit.Core.Models.BitStripe; @@ -16,11 +17,12 @@ public class PaymentHistoryService( public async Task> GetInvoiceHistoryAsync( ISubscriber subscriber, int pageSize = 5, - string startAfter = null) + string? status = null, + string? startAfter = null) { if (subscriber is not { GatewayCustomerId: not null, GatewaySubscriptionId: not null }) { - return null; + return Array.Empty(); } var invoices = await stripeAdapter.InvoiceListAsync(new StripeInvoiceListOptions @@ -28,6 +30,7 @@ public class PaymentHistoryService( Customer = subscriber.GatewayCustomerId, Subscription = subscriber.GatewaySubscriptionId, Limit = pageSize, + Status = status, StartingAfter = startAfter }); @@ -48,6 +51,7 @@ public class PaymentHistoryService( }; return transactions?.OrderByDescending(i => i.CreationDate) - .Select(t => new BillingHistoryInfo.BillingTransaction(t)); + .Select(t => new BillingHistoryInfo.BillingTransaction(t)) + ?? Array.Empty(); } } diff --git a/test/Core.Test/Billing/Services/PaymentHistoryServiceTests.cs b/test/Core.Test/Billing/Services/PaymentHistoryServiceTests.cs index 34bbb368b..c9278e448 100644 --- a/test/Core.Test/Billing/Services/PaymentHistoryServiceTests.cs +++ b/test/Core.Test/Billing/Services/PaymentHistoryServiceTests.cs @@ -29,7 +29,7 @@ public class PaymentHistoryServiceTests var result = await paymentHistoryService.GetInvoiceHistoryAsync(subscriber); // Assert - Assert.NotNull(result); + Assert.NotEmpty(result); Assert.Single(result); await stripeAdapter.Received(1).InvoiceListAsync(Arg.Any()); } @@ -47,7 +47,7 @@ public class PaymentHistoryServiceTests var result = await paymentHistoryService.GetInvoiceHistoryAsync(null); // Assert - Assert.Null(result); + Assert.Empty(result); } [Fact] @@ -66,7 +66,7 @@ public class PaymentHistoryServiceTests var result = await paymentHistoryService.GetTransactionHistoryAsync(subscriber); // Assert - Assert.NotNull(result); + Assert.NotEmpty(result); Assert.Single(result); await transactionRepository.Received(1).GetManyByOrganizationIdAsync(subscriber.Id, Arg.Any(), Arg.Any()); } @@ -84,6 +84,6 @@ public class PaymentHistoryServiceTests var result = await paymentHistoryService.GetTransactionHistoryAsync(null); // Assert - Assert.Null(result); + Assert.Empty(result); } }