Files
cfw-autumn/server/src/internal/billing/v2/setup/setupTrialContext.ts
2026-01-11 11:01:19 +00:00

86 lines
2.0 KiB
TypeScript

import type {
FullCusProduct,
FullProduct,
UpdateSubscriptionV0Params,
} from "@autumn/shared";
import {
addDuration,
initFreeTrial,
isCustomerProductTrialing,
isProductPaidAndRecurring,
secondsToMs,
} from "@autumn/shared";
import type Stripe from "stripe";
import { isStripeSubscriptionTrialing } from "@/external/stripe/subscriptions/utils/classifyStripeSubscriptionUtils";
import type { TrialContext } from "@/internal/billing/v2/billingContext";
export const setupTrialContext = ({
stripeSubscription,
customerProduct,
currentEpochMs,
params,
fullProduct,
}: {
stripeSubscription?: Stripe.Subscription;
customerProduct: FullCusProduct;
currentEpochMs: number;
params: UpdateSubscriptionV0Params;
fullProduct: FullProduct;
}): TrialContext | undefined => {
const freeTrialParams = params.free_trial;
// Case 1: If free trial is null (removing free trial)
if (freeTrialParams === null) {
return { freeTrial: null, trialEndsAt: null };
}
// Case 2: If free trial params are passed in
if (freeTrialParams) {
const dbFreeTrial = initFreeTrial({
freeTrialParams,
internalProductId: fullProduct.internal_id,
});
const trialEndsAt = addDuration({
now: currentEpochMs,
durationType: dbFreeTrial.duration,
durationLength: dbFreeTrial.length,
});
return {
freeTrial: dbFreeTrial,
trialEndsAt,
customFreeTrial: dbFreeTrial,
};
}
// Case 3: If new product is paid and recurring
if (isProductPaidAndRecurring(fullProduct)) {
if (
stripeSubscription &&
isStripeSubscriptionTrialing(stripeSubscription)
) {
const trialEndsAt = secondsToMs(
stripeSubscription.trial_end ?? undefined,
);
return {
freeTrial: null,
trialEndsAt: trialEndsAt,
};
} else {
return undefined;
}
}
// Case 4: Return free trial / trial ends at from current customer product
if (isCustomerProductTrialing(customerProduct, { nowMs: currentEpochMs })) {
return {
freeTrial: customerProduct.free_trial, // can be undefined...
trialEndsAt: customerProduct.trial_ends_at ?? null,
};
}
return undefined;
};