mirror of
https://github.com/bitwarden/server.git
synced 2025-07-01 16:12:49 -05:00
[AC-2568] Added invoices and transaction history endpoints. Added cursor paging for each (#4692)
* Added invoices and transaction history endpoints. Added cursor paging for each * Removed try/catch since it's handled by middleware. Updated condition to use pattern matching * Added unit tests for PaymentHistoryService * Removed organizationId from account billing controller endpoints
This commit is contained in:
@ -38,6 +38,7 @@ public class BillingHistoryInfo
|
||||
{
|
||||
public BillingInvoice(Invoice inv)
|
||||
{
|
||||
Id = inv.Id;
|
||||
Date = inv.Created;
|
||||
Url = inv.HostedInvoiceUrl;
|
||||
PdfUrl = inv.InvoicePdf;
|
||||
@ -46,6 +47,7 @@ public class BillingHistoryInfo
|
||||
Amount = inv.Total / 100M;
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public DateTime? Date { get; set; }
|
||||
public string Url { get; set; }
|
||||
|
17
src/Core/Billing/Services/IPaymentHistoryService.cs
Normal file
17
src/Core/Billing/Services/IPaymentHistoryService.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Bit.Core.Billing.Models;
|
||||
using Bit.Core.Entities;
|
||||
|
||||
namespace Bit.Core.Billing.Services;
|
||||
|
||||
public interface IPaymentHistoryService
|
||||
{
|
||||
Task<IEnumerable<BillingHistoryInfo.BillingInvoice>> GetInvoiceHistoryAsync(
|
||||
ISubscriber subscriber,
|
||||
int pageSize = 5,
|
||||
string startAfter = null);
|
||||
|
||||
Task<IEnumerable<BillingHistoryInfo.BillingTransaction>> GetTransactionHistoryAsync(
|
||||
ISubscriber subscriber,
|
||||
int pageSize = 5,
|
||||
DateTime? startAfter = null);
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Billing.Models;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.BitStripe;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Bit.Core.Billing.Services.Implementations;
|
||||
|
||||
public class PaymentHistoryService(
|
||||
IStripeAdapter stripeAdapter,
|
||||
ITransactionRepository transactionRepository,
|
||||
ILogger<PaymentHistoryService> logger) : IPaymentHistoryService
|
||||
{
|
||||
public async Task<IEnumerable<BillingHistoryInfo.BillingInvoice>> GetInvoiceHistoryAsync(
|
||||
ISubscriber subscriber,
|
||||
int pageSize = 5,
|
||||
string startAfter = null)
|
||||
{
|
||||
if (subscriber is not { GatewayCustomerId: not null, GatewaySubscriptionId: not null })
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var invoices = await stripeAdapter.InvoiceListAsync(new StripeInvoiceListOptions
|
||||
{
|
||||
Customer = subscriber.GatewayCustomerId,
|
||||
Subscription = subscriber.GatewaySubscriptionId,
|
||||
Limit = pageSize,
|
||||
StartingAfter = startAfter
|
||||
});
|
||||
|
||||
return invoices.Select(invoice => new BillingHistoryInfo.BillingInvoice(invoice));
|
||||
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<BillingHistoryInfo.BillingTransaction>> GetTransactionHistoryAsync(
|
||||
ISubscriber subscriber,
|
||||
int pageSize = 5,
|
||||
DateTime? startAfter = null)
|
||||
{
|
||||
var transactions = subscriber switch
|
||||
{
|
||||
User => await transactionRepository.GetManyByUserIdAsync(subscriber.Id, pageSize, startAfter),
|
||||
Organization => await transactionRepository.GetManyByOrganizationIdAsync(subscriber.Id, pageSize, startAfter),
|
||||
_ => null
|
||||
};
|
||||
|
||||
return transactions?.OrderByDescending(i => i.CreationDate)
|
||||
.Select(t => new BillingHistoryInfo.BillingTransaction(t));
|
||||
}
|
||||
}
|
@ -7,8 +7,8 @@ namespace Bit.Core.Repositories;
|
||||
|
||||
public interface ITransactionRepository : IRepository<Transaction, Guid>
|
||||
{
|
||||
Task<ICollection<Transaction>> GetManyByUserIdAsync(Guid userId, int? limit = null);
|
||||
Task<ICollection<Transaction>> GetManyByOrganizationIdAsync(Guid organizationId, int? limit = null);
|
||||
Task<ICollection<Transaction>> GetManyByProviderIdAsync(Guid providerId, int? limit = null);
|
||||
Task<ICollection<Transaction>> GetManyByUserIdAsync(Guid userId, int? limit = null, DateTime? startAfter = null);
|
||||
Task<ICollection<Transaction>> GetManyByOrganizationIdAsync(Guid organizationId, int? limit = null, DateTime? startAfter = null);
|
||||
Task<ICollection<Transaction>> GetManyByProviderIdAsync(Guid providerId, int? limit = null, DateTime? startAfter = null);
|
||||
Task<Transaction?> GetByGatewayIdAsync(GatewayType gatewayType, string gatewayId);
|
||||
}
|
||||
|
Reference in New Issue
Block a user