diff --git a/src/Exceptionless.Core/Exceptionless.Core.csproj b/src/Exceptionless.Core/Exceptionless.Core.csproj
index 6cb23ef1a..d5a486733 100644
--- a/src/Exceptionless.Core/Exceptionless.Core.csproj
+++ b/src/Exceptionless.Core/Exceptionless.Core.csproj
@@ -31,7 +31,7 @@
-
+
diff --git a/src/Exceptionless.Web/Controllers/OrganizationController.cs b/src/Exceptionless.Web/Controllers/OrganizationController.cs
index 4a2bb3d18..8c9ec8c2b 100644
--- a/src/Exceptionless.Web/Controllers/OrganizationController.cs
+++ b/src/Exceptionless.Web/Controllers/OrganizationController.cs
@@ -239,17 +239,34 @@ public async Task> GetInvoiceAsync(string id)
OrganizationId = organization.Id,
OrganizationName = organization.Name,
Date = stripeInvoice.Created,
- Paid = stripeInvoice.Paid,
+ Paid = String.Equals(stripeInvoice.Status, "paid"),
Total = stripeInvoice.Total / 100.0m
};
+ // In Stripe.net v49, Price information needs to be fetched separately
+ var client2 = new StripeClient(_options.StripeOptions.StripeApiKey);
+ var priceService = new PriceService(client2);
+
foreach (var line in stripeInvoice.Lines.Data)
{
var item = new InvoiceLineItem { Amount = line.Amount / 100.0m, Description = line.Description };
- if (line.Plan is not null)
+
+ // In v49, access price ID from Pricing.PriceDetails.Price
+ var priceId = line.Pricing?.PriceDetails?.Price;
+ if (!String.IsNullOrEmpty(priceId))
{
- string planName = line.Plan.Nickname ?? _billingManager.GetBillingPlan(line.Plan.Id)?.Name ?? line.Plan.Id;
- item.Description = $"Exceptionless - {planName} Plan ({(line.Plan.Amount / 100.0):c}/{line.Plan.Interval})";
+ try
+ {
+ var price = await priceService.GetAsync(priceId);
+ string planName = price.Nickname ?? _billingManager.GetBillingPlan(price.Id)?.Name ?? price.Id;
+ var intervalText = price.Recurring?.Interval ?? "one-time";
+ var priceAmount = line.Pricing?.UnitAmountDecimal.HasValue == true ? (line.Pricing.UnitAmountDecimal.Value / 100.0m) : 0.0m;
+ item.Description = $"Exceptionless - {planName} Plan ({priceAmount:c}/{intervalText})";
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning(ex, "Failed to fetch price details for price ID: {PriceId}", priceId);
+ }
}
var periodStart = line.Period.Start >= DateTime.MinValue ? line.Period.Start : stripeInvoice.PeriodStart;
@@ -258,7 +275,7 @@ public async Task> GetInvoiceAsync(string id)
invoice.Items.Add(item);
}
- var coupon = stripeInvoice.Discount?.Coupon;
+ var coupon = stripeInvoice.Discounts?.FirstOrDefault(d => d.Deleted is false)?.Source?.Coupon;
if (coupon is not null)
{
if (coupon.AmountOff.HasValue)
@@ -429,15 +446,28 @@ public async Task> ChangePlanAsync(string id, str
var createCustomer = new CustomerCreateOptions
{
Source = stripeToken,
- Plan = planId,
Description = organization.Name,
Email = CurrentUser.EmailAddress
};
+ var customer = await customerService.CreateAsync(createCustomer);
+
+ // Create subscription separately since Plan is deprecated in CustomerCreateOptions
+ var subscriptionCreateOptions = new SubscriptionCreateOptions
+ {
+ Customer = customer.Id,
+ Items = new List { new SubscriptionItemOptions { Price = planId } }
+ };
+
if (!String.IsNullOrWhiteSpace(couponId))
- createCustomer.Coupon = couponId;
+ {
+ subscriptionCreateOptions.Discounts = new List
+ {
+ new SubscriptionDiscountOptions { Coupon = couponId }
+ };
+ }
- var customer = await customerService.CreateAsync(createCustomer);
+ await subscriptionService.CreateAsync(subscriptionCreateOptions);
organization.BillingStatus = BillingStatus.Active;
organization.RemoveSuspension();
@@ -466,12 +496,12 @@ public async Task> ChangePlanAsync(string id, str
var subscription = subscriptionList.FirstOrDefault(s => !s.CanceledAt.HasValue);
if (subscription is not null)
{
- update.Items.Add(new SubscriptionItemOptions { Id = subscription.Items.Data[0].Id, Plan = planId });
+ update.Items.Add(new SubscriptionItemOptions { Id = subscription.Items.Data[0].Id, Price = planId });
await subscriptionService.UpdateAsync(subscription.Id, update);
}
else
{
- create.Items.Add(new SubscriptionItemOptions { Plan = planId });
+ create.Items.Add(new SubscriptionItemOptions { Price = planId });
await subscriptionService.CreateAsync(create);
}