Merge pull request #30826 from overleaf/oa-filter-out-once-coupons

[web] Filter out once coupons for Stripe

GitOrigin-RevId: 60aad9c557632c3a3a4b5e6d578d786feaa9508f
This commit is contained in:
Olzhas Askar
2026-01-20 14:36:14 +01:00
committed by Copybot
parent 21d672c0f4
commit a5b56c7579
2 changed files with 40 additions and 1 deletions

View File

@@ -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,

View File

@@ -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