diff --git a/.changeset/brown-news-unite.md b/.changeset/brown-news-unite.md
new file mode 100644
index 00000000000..dc19b9a7f38
--- /dev/null
+++ b/.changeset/brown-news-unite.md
@@ -0,0 +1,11 @@
+---
+'@clerk/clerk-js': minor
+'@clerk/types': minor
+---
+
+ [Billing Beta] Cleanup naming inconsistencies in billing dates.
+
+## Migration
+- subscriptionItem.periodStartDate → subscriptionItem.periodStart
+- subscriptionItem.periodEndDate → subscriptionItem.periodEnd
+- subscriptionItem.canceledAtDate → subscriptionItem.canceledAt
diff --git a/packages/clerk-js/src/core/resources/CommerceSubscription.ts b/packages/clerk-js/src/core/resources/CommerceSubscription.ts
index 4c852f1d353..341b515f968 100644
--- a/packages/clerk-js/src/core/resources/CommerceSubscription.ts
+++ b/packages/clerk-js/src/core/resources/CommerceSubscription.ts
@@ -62,13 +62,10 @@ export class CommerceSubscriptionItem extends BaseResource implements CommerceSu
planPeriod!: CommerceSubscriptionPlanPeriod;
status!: CommerceSubscriptionStatus;
createdAt!: Date;
+ periodStart!: Date;
+ periodEnd!: Date | null;
+ canceledAt!: Date | null;
pastDueAt!: Date | null;
- periodStartDate!: Date;
- periodEndDate!: Date | null;
- canceledAtDate!: Date | null;
- periodStart!: number;
- periodEnd!: number;
- canceledAt!: number | null;
//TODO(@COMMERCE): Why can this be undefined ?
amount?: CommerceMoney;
credit?: {
@@ -90,16 +87,13 @@ export class CommerceSubscriptionItem extends BaseResource implements CommerceSu
this.plan = new CommercePlan(data.plan);
this.planPeriod = data.plan_period;
this.status = data.status;
- this.periodStart = data.period_start;
- this.periodEnd = data.period_end;
- this.canceledAt = data.canceled_at;
this.createdAt = unixEpochToDate(data.created_at);
this.pastDueAt = data.past_due_at ? unixEpochToDate(data.past_due_at) : null;
- this.periodStartDate = unixEpochToDate(data.period_start);
- this.periodEndDate = data.period_end ? unixEpochToDate(data.period_end) : null;
- this.canceledAtDate = data.canceled_at ? unixEpochToDate(data.canceled_at) : null;
+ this.periodStart = unixEpochToDate(data.period_start);
+ this.periodEnd = data.period_end ? unixEpochToDate(data.period_end) : null;
+ this.canceledAt = data.canceled_at ? unixEpochToDate(data.canceled_at) : null;
this.amount = data.amount ? commerceMoneyFromJSON(data.amount) : undefined;
this.credit = data.credit && data.credit.amount ? { amount: commerceMoneyFromJSON(data.credit.amount) } : undefined;
diff --git a/packages/clerk-js/src/ui/components/PricingTable/PricingTable.tsx b/packages/clerk-js/src/ui/components/PricingTable/PricingTable.tsx
index eae1fcd381c..f7c69c58611 100644
--- a/packages/clerk-js/src/ui/components/PricingTable/PricingTable.tsx
+++ b/packages/clerk-js/src/ui/components/PricingTable/PricingTable.tsx
@@ -25,7 +25,7 @@ const PricingTableRoot = (props: PricingTableProps) => {
// don't pay attention to the default plan
const activeSubscription = subscriptionItems?.find(
- sub => !sub.canceledAtDate && sub.status === 'active' && !sub.plan.isDefault,
+ sub => !sub.canceledAt && sub.status === 'active' && !sub.plan.isDefault,
);
if (activeSubscription) {
return activeSubscription.planPeriod;
diff --git a/packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx b/packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx
index 9d2ea35b194..b664a3c4b04 100644
--- a/packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx
+++ b/packages/clerk-js/src/ui/components/PricingTable/PricingTableDefault.tsx
@@ -141,7 +141,7 @@ function Card(props: CardProps) {
shouldShowFooter = true;
shouldShowFooterNotice = true;
} else if (subscription.status === 'active') {
- if (subscription.canceledAtDate) {
+ if (subscription.canceledAt) {
shouldShowFooter = true;
shouldShowFooterNotice = false;
} else if (planPeriod !== subscription.planPeriod && plan.annualMonthlyAmount > 0) {
@@ -233,7 +233,7 @@ function Card(props: CardProps) {
elementDescriptor={descriptors.pricingTableCardFooterNotice}
variant={isCompact ? 'buttonSmall' : 'buttonLarge'}
localizationKey={localizationKeys('badge__startsAt', {
- date: subscription?.periodStartDate,
+ date: subscription?.periodStart,
})}
colorScheme='secondary'
sx={t => ({
diff --git a/packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx b/packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
index 4ce9e8732ba..143ef4e22e4 100644
--- a/packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
+++ b/packages/clerk-js/src/ui/components/SubscriptionDetails/__tests__/SubscriptionDetails.test.tsx
@@ -68,9 +68,9 @@ describe('SubscriptionDetails', () => {
isDefault: false,
},
createdAt: new Date('2021-01-01'),
- periodStartDate: new Date('2021-01-01'),
- periodEndDate: new Date('2021-02-01'),
- canceledAtDate: null,
+ periodStart: new Date('2021-01-01'),
+ periodEnd: new Date('2021-02-01'),
+ canceledAt: null,
paymentSourceId: 'src_123',
planPeriod: 'month',
status: 'active',
@@ -161,9 +161,9 @@ describe('SubscriptionDetails', () => {
isDefault: false,
},
createdAt: new Date('2021-01-01'),
- periodStartDate: new Date('2021-01-01'),
- periodEndDate: new Date('2022-01-01'),
- canceledAtDate: null,
+ periodStart: new Date('2021-01-01'),
+ periodEnd: new Date('2022-01-01'),
+ canceledAt: null,
paymentSourceId: 'src_123',
planPeriod: 'annual' as const,
status: 'active' as const,
@@ -246,9 +246,9 @@ describe('SubscriptionDetails', () => {
isDefault: true,
},
createdAt: new Date('2021-01-01'),
- periodStartDate: new Date('2021-01-01'),
- periodEndDate: new Date('2021-02-01'),
- canceledAtDate: null,
+ periodStart: new Date('2021-01-01'),
+ periodEnd: new Date('2021-02-01'),
+ canceledAt: null,
paymentSourceId: 'src_123',
planPeriod: 'month' as const,
status: 'active' as const,
@@ -354,9 +354,9 @@ describe('SubscriptionDetails', () => {
id: 'sub_annual',
plan: planAnnual,
createdAt: new Date('2021-01-01'),
- periodStartDate: new Date('2021-01-01'),
- periodEndDate: new Date('2022-01-01'),
- canceledAtDate: new Date('2021-04-01'),
+ periodStart: new Date('2021-01-01'),
+ periodEnd: new Date('2022-01-01'),
+ canceledAt: new Date('2021-04-01'),
paymentSourceId: 'src_annual',
planPeriod: 'annual' as const,
status: 'active' as const,
@@ -365,9 +365,9 @@ describe('SubscriptionDetails', () => {
id: 'sub_monthly',
plan: planMonthly,
createdAt: new Date('2022-01-01'),
- periodStartDate: new Date('2022-02-01'),
- periodEndDate: new Date('2022-03-01'),
- canceledAtDate: null,
+ periodStart: new Date('2022-02-01'),
+ periodEnd: new Date('2022-03-01'),
+ canceledAt: null,
paymentSourceId: 'src_monthly',
planPeriod: 'month' as const,
status: 'upcoming' as const,
@@ -486,9 +486,9 @@ describe('SubscriptionDetails', () => {
id: 'test_active',
plan: planMonthly,
createdAt: new Date('2021-01-01'),
- periodStartDate: new Date('2021-01-01'),
- periodEndDate: new Date('2021-02-01'),
- canceledAtDate: new Date('2021-01-03'),
+ periodStart: new Date('2021-01-01'),
+ periodEnd: new Date('2021-02-01'),
+ canceledAt: new Date('2021-01-03'),
paymentSourceId: 'src_free_active',
planPeriod: 'month' as const,
status: 'active' as const,
@@ -497,8 +497,8 @@ describe('SubscriptionDetails', () => {
id: 'sub_free_upcoming',
plan: planFreeUpcoming,
createdAt: new Date('2021-01-03'),
- periodStartDate: new Date('2021-02-01'),
- canceledAtDate: null,
+ periodStart: new Date('2021-02-01'),
+ canceledAt: null,
paymentSourceId: 'src_free_upcoming',
planPeriod: 'month' as const,
status: 'upcoming' as const,
@@ -582,9 +582,9 @@ describe('SubscriptionDetails', () => {
isDefault: false,
},
createdAt: new Date('2021-01-01'),
- periodStartDate: new Date('2021-01-01'),
- periodEndDate: new Date('2021-02-01'),
- canceledAtDate: null,
+ periodStart: new Date('2021-01-01'),
+ periodEnd: new Date('2021-02-01'),
+ canceledAt: null,
paymentSourceId: 'src_123',
planPeriod: 'month' as const,
status: 'active' as const,
@@ -668,9 +668,9 @@ describe('SubscriptionDetails', () => {
id: 'sub_annual',
plan,
createdAt: new Date('2021-01-01'),
- periodStartDate: new Date('2021-01-01'),
- periodEndDate: new Date('2022-01-01'),
- canceledAtDate: new Date('2021-04-01'),
+ periodStart: new Date('2021-01-01'),
+ periodEnd: new Date('2022-01-01'),
+ canceledAt: new Date('2021-04-01'),
paymentSourceId: 'src_annual',
planPeriod: 'annual' as const,
status: 'active' as const,
@@ -755,9 +755,9 @@ describe('SubscriptionDetails', () => {
id: 'sub_annual',
plan,
createdAt: new Date('2021-01-01'),
- periodStartDate: new Date('2021-01-01'),
- periodEndDate: new Date('2022-01-01'),
- canceledAtDate: null,
+ periodStart: new Date('2021-01-01'),
+ periodEnd: new Date('2022-01-01'),
+ canceledAt: null,
paymentSourceId: 'src_annual',
planPeriod: 'annual' as const,
status: 'active' as const,
@@ -862,9 +862,9 @@ describe('SubscriptionDetails', () => {
id: 'sub_past_due',
plan,
createdAt: new Date('2021-01-01'),
- periodStartDate: new Date('2021-01-01'),
- periodEndDate: new Date('2021-02-01'),
- canceledAtDate: null,
+ periodStart: new Date('2021-01-01'),
+ periodEnd: new Date('2021-02-01'),
+ canceledAt: null,
paymentSourceId: 'src_123',
planPeriod: 'month' as const,
status: 'past_due' as const,
diff --git a/packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx b/packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
index 70a947b2b43..125e80c462c 100644
--- a/packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
+++ b/packages/clerk-js/src/ui/components/SubscriptionDetails/index.tsx
@@ -271,7 +271,7 @@ const SubscriptionDetailsFooter = withCardStateProvider(() => {
: localizationKeys('commerce.cancelSubscriptionAccessUntil', {
plan: selectedSubscription.plan.name,
// this will always be defined in this state
- date: selectedSubscription.periodEndDate as Date,
+ date: selectedSubscription.periodEnd as Date,
})
}
/>
@@ -339,8 +339,8 @@ const SubscriptionCardActions = ({ subscription }: { subscription: CommerceSubsc
subscription.planPeriod === 'annual') &&
subscription.status !== 'past_due';
const isFree = isFreePlan(subscription.plan);
- const isCancellable = subscription.canceledAtDate === null && !isFree && subscription.status !== 'past_due';
- const isReSubscribable = subscription.canceledAtDate !== null && !isFree;
+ const isCancellable = subscription.canceledAt === null && !isFree && subscription.status !== 'past_due';
+ const isReSubscribable = subscription.canceledAt !== null && !isFree;
const openCheckout = useCallback(
(params?: __internal_CheckoutProps) => {
@@ -523,14 +523,14 @@ const SubscriptionCard = ({ subscription }: { subscription: CommerceSubscription
value={formatDate(subscription.createdAt)}
/>
{/* The free plan does not have a period end date */}
- {subscription.periodEndDate && (
+ {subscription.periodEnd && (
)}
>
@@ -539,7 +539,7 @@ const SubscriptionCard = ({ subscription }: { subscription: CommerceSubscription
{subscription.status === 'upcoming' ? (
) : null}
diff --git a/packages/clerk-js/src/ui/components/Subscriptions/SubscriptionsList.tsx b/packages/clerk-js/src/ui/components/Subscriptions/SubscriptionsList.tsx
index fbb3e77a6f4..7db9432768d 100644
--- a/packages/clerk-js/src/ui/components/Subscriptions/SubscriptionsList.tsx
+++ b/packages/clerk-js/src/ui/components/Subscriptions/SubscriptionsList.tsx
@@ -120,7 +120,7 @@ export function SubscriptionsList({
>
{subscription.plan.name}
- {sortedSubscriptions.length > 1 || !!subscription.canceledAtDate ? (
+ {sortedSubscriptions.length > 1 || !!subscription.canceledAt ? (
) : null}
diff --git a/packages/clerk-js/src/ui/contexts/components/Plans.tsx b/packages/clerk-js/src/ui/contexts/components/Plans.tsx
index a18b7995877..f9117a90dfd 100644
--- a/packages/clerk-js/src/ui/contexts/components/Plans.tsx
+++ b/packages/clerk-js/src/ui/contexts/components/Plans.tsx
@@ -129,7 +129,7 @@ export const usePlansContext = () => {
// should the default plan be shown as active
const isDefaultPlanImplicitlyActiveOrUpcoming = useMemo(() => {
// are there no subscriptions or are all subscriptions canceled
- return subscriptionItems.length === 0 || !subscriptionItems.some(subscription => !subscription.canceledAtDate);
+ return subscriptionItems.length === 0 || !subscriptionItems.some(subscription => !subscription.canceledAt);
}, [subscriptionItems]);
// return the active or upcoming subscription for a plan if it exists
@@ -178,7 +178,7 @@ export const usePlansContext = () => {
({ plan, subscription: sub }: { plan?: CommercePlanResource; subscription?: CommerceSubscriptionItemResource }) => {
const subscription = sub ?? (plan ? activeOrUpcomingSubscription(plan) : undefined);
- return !subscription || !subscription.canceledAtDate;
+ return !subscription || !subscription.canceledAt;
},
[activeOrUpcomingSubscription],
);
@@ -214,7 +214,7 @@ export const usePlansContext = () => {
const getLocalizationKey = () => {
// Handle subscription cases
if (subscription) {
- if (_selectedPlanPeriod !== subscription.planPeriod && subscription.canceledAtDate) {
+ if (_selectedPlanPeriod !== subscription.planPeriod && subscription.canceledAt) {
if (_selectedPlanPeriod === 'month') {
return localizationKeys('commerce.switchToMonthly');
}
@@ -224,7 +224,7 @@ export const usePlansContext = () => {
}
}
- if (subscription.canceledAtDate) {
+ if (subscription.canceledAt) {
return localizationKeys('commerce.reSubscribe');
}
@@ -268,14 +268,14 @@ export const usePlansContext = () => {
}
if (subscription.status === 'upcoming') {
- return localizationKeys('badge__startsAt', { date: subscription.periodStartDate });
+ return localizationKeys('badge__startsAt', { date: subscription.periodStart });
}
- if (subscription.canceledAtDate) {
+ if (subscription.canceledAt) {
// @ts-expect-error `periodEndDate` is always defined when `canceledAtDate` exists
- return localizationKeys('badge__canceledEndsAt', { date: subscription.periodEndDate });
+ return localizationKeys('badge__canceledEndsAt', { date: subscription.periodEnd });
}
- if (subscription.periodEndDate) {
- return localizationKeys('badge__renewsAt', { date: subscription.periodEndDate });
+ if (subscription.periodEnd) {
+ return localizationKeys('badge__renewsAt', { date: subscription.periodEnd });
}
return;
}, []);
diff --git a/packages/types/src/commerce.ts b/packages/types/src/commerce.ts
index 3ae559e3c23..1b51dd1077c 100644
--- a/packages/types/src/commerce.ts
+++ b/packages/types/src/commerce.ts
@@ -1038,7 +1038,7 @@ export interface CommerceSubscriptionItemResource extends ClerkResource {
*
* ```
*/
- periodStartDate: Date;
+ periodStart: Date;
/**
* @experimental This is an experimental API for the Billing feature that is available under a public beta, and the API is subject to change.
* It is advised to pin the SDK version and the clerk-js version to a specific version to avoid breaking changes.
@@ -1047,7 +1047,7 @@ export interface CommerceSubscriptionItemResource extends ClerkResource {
*
* ```
*/
- periodEndDate: Date | null;
+ periodEnd: Date | null;
/**
* @experimental This is an experimental API for the Billing feature that is available under a public beta, and the API is subject to change.
* It is advised to pin the SDK version and the clerk-js version to a specific version to avoid breaking changes.
@@ -1056,19 +1056,7 @@ export interface CommerceSubscriptionItemResource extends ClerkResource {
*
* ```
*/
- canceledAtDate: Date | null;
- /**
- * @deprecated Use `periodStartDate` instead
- */
- periodStart: number;
- /**
- * @deprecated Use `periodEndDate` instead
- */
- periodEnd: number;
- /**
- * @deprecated Use `canceledAtDate` instead
- */
- canceledAt: number | null;
+ canceledAt: Date | null;
/**
* @experimental This is an experimental API for the Billing feature that is available under a public beta, and the API is subject to change.
* It is advised to pin the SDK version and the clerk-js version to a specific version to avoid breaking changes.
diff --git a/packages/types/src/json.ts b/packages/types/src/json.ts
index 11dd4760797..f7b4fa685fd 100644
--- a/packages/types/src/json.ts
+++ b/packages/types/src/json.ts
@@ -777,7 +777,10 @@ export interface CommerceSubscriptionItemJSON extends ClerkResourceJSON {
status: CommerceSubscriptionStatus;
created_at: number;
period_start: number;
- period_end: number;
+ /**
+ * Period end is `null` for subscription items that are on the free plan.
+ */
+ period_end: number | null;
canceled_at: number | null;
past_due_at: number | null;
}