1
0
mirror of https://github.com/bitwarden/server synced 2026-02-26 01:13:35 +00:00

[PM-30108] import discount from stripe (#6982)

* [PM-30108] import discount from stripe

* fix repo tests

* pr feedback

* wrap discounts in feature flag

* claude pr feedback
This commit is contained in:
Kyle Denney
2026-02-17 12:57:14 -06:00
committed by GitHub
parent 3753a5e853
commit f0c69cedc2
24 changed files with 1521 additions and 1 deletions

View File

@@ -39,6 +39,11 @@ public static class StripeConstants
}
}
public static class CouponExpandablePropertyNames
{
public const string AppliesTo = "applies_to";
}
public static class ErrorCodes
{
public const string CustomerTaxLocationInvalid = "customer_tax_location_invalid";

View File

@@ -6,8 +6,14 @@
/// </summary>
public enum DiscountAudienceType
{
/// <summary>
/// Discount applies to all users regardless of subscription history.
/// This is the default value (0) when audience restrictions are not applied.
/// </summary>
AllUsers = 0,
/// <summary>
/// Discount applies to users who have never had a subscription before.
/// </summary>
UserHasNoPreviousSubscriptions = 0
UserHasNoPreviousSubscriptions = 1
}

View File

@@ -48,4 +48,6 @@ public interface IStripeAdapter
Task CancelSetupIntentAsync(string id, SetupIntentCancelOptions options = null);
Task<SetupIntent> GetSetupIntentAsync(string id, SetupIntentGetOptions options = null);
Task<Price> GetPriceAsync(string id, PriceGetOptions options = null);
Task<Coupon> GetCouponAsync(string couponId, CouponGetOptions options = null);
Task<List<Product>> ListProductsAsync(ProductListOptions options = null);
}

View File

@@ -27,6 +27,8 @@ public class StripeAdapter : IStripeAdapter
private readonly TestClockService _testClockService;
private readonly CustomerBalanceTransactionService _customerBalanceTransactionService;
private readonly RegistrationService _taxRegistrationService;
private readonly CouponService _couponService;
private readonly ProductService _productService;
public StripeAdapter()
{
@@ -44,6 +46,8 @@ public class StripeAdapter : IStripeAdapter
_testClockService = new TestClockService();
_customerBalanceTransactionService = new CustomerBalanceTransactionService();
_taxRegistrationService = new RegistrationService();
_couponService = new CouponService();
_productService = new ProductService();
}
/**************
@@ -209,4 +213,16 @@ public class StripeAdapter : IStripeAdapter
public Task<Card> DeleteCardAsync(string customerId, string cardId, CardDeleteOptions options = null) =>
_cardService.DeleteAsync(customerId, cardId, options);
/************
** COUPON **
************/
public Task<Coupon> GetCouponAsync(string couponId, CouponGetOptions options = null) =>
_couponService.GetAsync(couponId, options);
/*************
** PRODUCT **
*************/
public async Task<List<Product>> ListProductsAsync(ProductListOptions options = null) =>
(await _productService.ListAsync(options)).Data;
}

View File

@@ -20,4 +20,13 @@ public interface ISubscriptionDiscountRepository : IRepository<SubscriptionDisco
/// <param name="stripeCouponId">The Stripe coupon ID to search for.</param>
/// <returns>The subscription discount if found; otherwise, null.</returns>
Task<SubscriptionDiscount?> GetByStripeCouponIdAsync(string stripeCouponId);
/// <summary>
/// Lists subscription discounts with pagination support.
/// Returns discounts ordered by creation date descending (newest first).
/// </summary>
/// <param name="skip">Number of records to skip (for pagination).</param>
/// <param name="take">Number of records to take (page size).</param>
/// <returns>A collection of subscription discounts for the requested page.</returns>
Task<ICollection<SubscriptionDiscount>> ListAsync(int skip, int take);
}

View File

@@ -189,6 +189,7 @@ public static class FeatureFlagKeys
public const string PM28265_EnableReconcileAdditionalStorageJob = "pm-28265-enable-reconcile-additional-storage-job";
public const string PM28265_ReconcileAdditionalStorageJobEnableLiveMode = "pm-28265-reconcile-additional-storage-job-enable-live-mode";
public const string PM29594_UpdateIndividualSubscriptionPage = "pm-29594-update-individual-subscription-page";
public const string PM29108_EnablePersonalDiscounts = "pm-29108-enable-personal-discounts";
/* Key Management Team */
public const string PrivateKeyRegeneration = "pm-12241-private-key-regeneration";