diff --git a/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.mjs b/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.mjs index a78486d15f..d03cb2cd05 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.mjs +++ b/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.mjs @@ -270,6 +270,12 @@ async function buildUsersSubscriptionViewModel(user, locale = 'en') { isEligibleForPause = stripePauseAssignment.variant === 'enabled' } + let activeCoupons = paymentRecord.coupons + if (paymentRecord.subscription.service.includes('stripe')) { + // TODO: consider using discount.coupon.valid after removing Recurly + activeCoupons = activeCoupons.filter(ac => !ac.isSingleUse) + } + personalSubscription.payment = { taxRate, billingDetailsLink: @@ -292,7 +298,7 @@ async function buildUsersSubscriptionViewModel(user, locale = 'en') { paymentRecord.subscription.trialPeriodEnd ), trialEndsAt: paymentRecord.subscription.trialPeriodEnd, - activeCoupons: paymentRecord.coupons, + activeCoupons, accountEmail: paymentRecord.account.email, hasPastDueInvoice: paymentRecord.account.hasPastDueInvoice, pausedAt: paymentRecord.subscription.pausePeriodStart, diff --git a/services/web/test/unit/src/Subscription/SubscriptionViewModelBuilder.test.mjs b/services/web/test/unit/src/Subscription/SubscriptionViewModelBuilder.test.mjs index da4a536899..d87ae4bf24 100644 --- a/services/web/test/unit/src/Subscription/SubscriptionViewModelBuilder.test.mjs +++ b/services/web/test/unit/src/Subscription/SubscriptionViewModelBuilder.test.mjs @@ -724,6 +724,39 @@ describe('SubscriptionViewModelBuilder', function () { }) }) + it('filters out single-use coupons for stripe subscriptions', async function (ctx) { + ctx.paymentRecord.service = 'stripe-us' + const foreverCoupon = { + code: 'forever', + name: 'Forever', + isSingleUse: false, + } + const singleUseCoupon = { + code: 'once', + name: 'Once', + isSingleUse: true, + } + ctx.Modules.hooks.fire + .withArgs('getPaymentFromRecord', ctx.individualSubscription) + .yields(null, [ + { + subscription: ctx.paymentRecord, + account: new PaymentProviderAccount({ + email: 'example@example.com', + hasPastDueInvoice: false, + }), + coupons: [foreverCoupon, singleUseCoupon], + }, + ]) + const result = + await ctx.SubscriptionViewModelBuilder.promises.buildUsersSubscriptionViewModel( + ctx.user + ) + assert.deepEqual(result.personalSubscription.payment.activeCoupons, [ + foreverCoupon, + ]) + }) + describe('isEligibleForGroupPlan', function () { it('is false when in trial', async function (ctx) { const msIn24Hours = 24 * 60 * 60 * 1000