Merge pull request #27215 from overleaf/rh-stripe-pause-status
Update features and subscription state when Stripe pause starts and ends GitOrigin-RevId: 368f5d9b046cfe26e996be336189081b96926713
This commit is contained in:
@@ -40,6 +40,7 @@ class PaymentProviderSubscription {
|
||||
* @param {Date|null} [props.trialPeriodStart]
|
||||
* @param {Date|null} [props.trialPeriodEnd]
|
||||
* @param {Date|null} [props.pausePeriodStart]
|
||||
* @param {Date|null} [props.pausePeriodEnd]
|
||||
* @param {number|null} [props.remainingPauseCycles]
|
||||
*/
|
||||
constructor(props) {
|
||||
@@ -66,6 +67,7 @@ class PaymentProviderSubscription {
|
||||
this.trialPeriodStart = props.trialPeriodStart ?? null
|
||||
this.trialPeriodEnd = props.trialPeriodEnd ?? null
|
||||
this.pausePeriodStart = props.pausePeriodStart ?? null
|
||||
this.pausePeriodEnd = props.pausePeriodEnd ?? null
|
||||
this.remainingPauseCycles = props.remainingPauseCycles ?? null
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,63 @@
|
||||
const { formatCurrency } = require('../../util/currency')
|
||||
const GroupPlansData = require('./GroupPlansData')
|
||||
const { isStandaloneAiAddOnPlanCode } = require('./AiHelper')
|
||||
const { Subscription } = require('../../models/Subscription')
|
||||
|
||||
const MILLISECONDS = 1_000
|
||||
/**
|
||||
* Recompute the subscription state for Stripe subscriptions based on pause periods.
|
||||
* This function checks if a subscription should transition between 'active' and 'paused'
|
||||
* states based on the current time and pause period metadata.
|
||||
*
|
||||
* @param {Object} subscription - The MongoDB subscription document
|
||||
* @returns {Promise<Object>} - The updated subscription document with recomputed state
|
||||
*/
|
||||
async function recomputeSubscriptionState(subscription) {
|
||||
if (
|
||||
!subscription?.paymentProvider?.subscriptionId ||
|
||||
!subscription.paymentProvider.pausePeriodStart ||
|
||||
!subscription.paymentProvider.pausePeriodEnd ||
|
||||
!subscription?.paymentProvider.service.includes('stripe')
|
||||
) {
|
||||
return subscription
|
||||
}
|
||||
const now = Date.now() / MILLISECONDS
|
||||
const pauseStartTime =
|
||||
new Date(subscription.paymentProvider.pausePeriodStart).getTime() /
|
||||
MILLISECONDS
|
||||
const currentState = subscription.paymentProvider.state
|
||||
|
||||
const pauseEndTime =
|
||||
new Date(subscription.paymentProvider.pausePeriodEnd).getTime() /
|
||||
MILLISECONDS
|
||||
|
||||
const shouldBePaused =
|
||||
pauseEndTime && now >= pauseStartTime && now < pauseEndTime
|
||||
|
||||
let newState
|
||||
|
||||
if (shouldBePaused && currentState !== 'paused') {
|
||||
newState = 'paused'
|
||||
} else if (
|
||||
!shouldBePaused &&
|
||||
currentState === 'paused' &&
|
||||
pauseEndTime &&
|
||||
now >= pauseEndTime
|
||||
) {
|
||||
newState = 'active'
|
||||
}
|
||||
|
||||
if (newState) {
|
||||
await Subscription.updateOne(
|
||||
{ _id: subscription._id },
|
||||
{ 'paymentProvider.state': newState }
|
||||
).exec()
|
||||
|
||||
subscription.paymentProvider.state = newState
|
||||
}
|
||||
|
||||
return subscription
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user changes to a less expensive plan, we shouldn't apply the change immediately.
|
||||
@@ -149,4 +206,5 @@ module.exports = {
|
||||
getSubscriptionTrialStartedAt,
|
||||
getSubscriptionTrialEndsAt,
|
||||
isInTrial,
|
||||
recomputeSubscriptionState,
|
||||
}
|
||||
|
||||
@@ -15,6 +15,11 @@ const SubscriptionLocator = {
|
||||
const userId = SubscriptionLocator._getUserId(userOrId)
|
||||
const subscription = await Subscription.findOne({ admin_id: userId }).exec()
|
||||
logger.debug({ userId }, 'got users subscription')
|
||||
|
||||
if (subscription) {
|
||||
return await SubscriptionHelper.recomputeSubscriptionState(subscription)
|
||||
}
|
||||
|
||||
return subscription
|
||||
},
|
||||
|
||||
|
||||
@@ -76,6 +76,12 @@ const SubscriptionSchema = new Schema(
|
||||
state: {
|
||||
type: String,
|
||||
},
|
||||
pausePeriodStart: {
|
||||
type: Date,
|
||||
},
|
||||
pausePeriodEnd: {
|
||||
type: Date,
|
||||
},
|
||||
trialStartedAt: {
|
||||
type: Date,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user