Skip to content

Commit 81840b3

Browse files
fix(shared,clerk-js,backend,ui): use duration in cycles in payments and statements (#9401)
1 parent a9099bc commit 81840b3

10 files changed

Lines changed: 21 additions & 4 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@clerk/shared': patch
3+
'@clerk/clerk-js': patch
4+
'@clerk/backend': patch
5+
'@clerk/ui': patch
6+
---
7+
8+
Billing applied-discount snapshots now include optional `durationInCycles`. Payment attempt and statement UIs use the original discount length instead of cycles remaining, and omit the duration copy when it is unavailable.

packages/backend/src/util/billing.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ const billingAppliedDiscountFromJSON = (discount: BillingAppliedDiscountJSON): B
6262
amountOff: discount.amount_off ? billingMoneyAmountFromJSON(discount.amount_off) : undefined,
6363
promoCode: discount.promo_code,
6464
cyclesRemaining: discount.cycles_remaining,
65+
durationInCycles: discount.duration_in_cycles,
6566
});
6667

6768
const billingDiscountsFromJSON = (discounts: BillingDiscountsJSON): BillingDiscounts => ({

packages/clerk-js/src/utils/__tests__/billing.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const nextPaymentTotalsJSON = (): BillingTotalsJSON => ({
4949
percent_off: 20,
5050
promo_code: 'WELCOME20',
5151
cycles_remaining: 2,
52+
duration_in_cycles: 3,
5253
},
5354
total: moneyJSON(500),
5455
},
@@ -126,6 +127,7 @@ describe('billingPaymentTotalsFromJSON', () => {
126127
effect: 'fixed_amount',
127128
amount_off: moneyJSON(100),
128129
cycles_remaining: null,
130+
duration_in_cycles: null,
129131
},
130132
total: moneyJSON(16),
131133
},
@@ -142,6 +144,7 @@ describe('billingPaymentTotalsFromJSON', () => {
142144
effect: 'fixed_amount',
143145
amountOff: { amount: 100, amountFormatted: '1.00', currency: 'USD', currencySymbol: '$' },
144146
cyclesRemaining: null,
147+
durationInCycles: null,
145148
});
146149
expect(totals.discounts?.total.amount).toBe(16);
147150
});
@@ -243,6 +246,7 @@ describe('billingSubscriptionNextPaymentFromJSON', () => {
243246
percentOff: 20,
244247
promoCode: 'WELCOME20',
245248
cyclesRemaining: 2,
249+
durationInCycles: 3,
246250
},
247251
total: { amount: 500 },
248252
},

packages/clerk-js/src/utils/billing.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ const billingAppliedDiscountFromJSON = (data: BillingAppliedDiscountJSON): Billi
123123
amountOff: data.amount_off ? billingMoneyAmountFromJSON(data.amount_off) : undefined,
124124
promoCode: data.promo_code,
125125
cyclesRemaining: data.cycles_remaining,
126+
durationInCycles: data.duration_in_cycles,
126127
});
127128

128129
export const billingDiscountRedemptionFromJSON = (data: BillingDiscountRedemptionJSON): BillingDiscountRedemption => ({

packages/shared/src/types/billing.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,7 @@ export interface BillingAppliedDiscount {
10511051
amountOff?: BillingMoneyAmount;
10521052
promoCode?: string;
10531053
cyclesRemaining: number | null;
1054+
durationInCycles?: number | null;
10541055
}
10551056

10561057
/**

packages/shared/src/types/json.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,7 @@ export interface BillingAppliedDiscountJSON {
10221022
amount_off?: BillingMoneyAmountJSON;
10231023
promo_code?: string;
10241024
cycles_remaining: number | null;
1025+
duration_in_cycles?: number | null;
10251026
}
10261027

10271028
export interface BillingDiscountRedemptionJSON extends ClerkResourceJSON {

packages/ui/src/components/Checkout/__tests__/Checkout.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,6 +1764,7 @@ describe('Checkout', () => {
17641764
percentOff: 20,
17651765
promoCode: 'WELCOME20',
17661766
cyclesRemaining: 1,
1767+
durationInCycles: 1,
17671768
},
17681769
total: money(2598, '25.98'),
17691770
},

packages/ui/src/components/PaymentAttempts/PaymentAttemptPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ function PaymentAttemptBody({ paymentAttempt }: { paymentAttempt: BillingPayment
292292
title={catalogDiscount.name}
293293
description={getDiscountDescription(
294294
catalogDiscount,
295-
catalogDiscount.cyclesRemaining,
295+
catalogDiscount.durationInCycles,
296296
subscriptionItem.planPeriod,
297297
{ $, t },
298298
)}

packages/ui/src/components/Statements/StatementPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ export const StatementPage = () => {
151151
<Statement.SectionContentDetailsListItem
152152
label={`${item.totals.discounts.discount.name} ${getDiscountDescription(
153153
item.totals.discounts.discount,
154-
item.totals.discounts.discount.cyclesRemaining,
154+
item.totals.discounts.discount.durationInCycles,
155155
item.subscriptionItem.planPeriod,
156156
{ $, t },
157157
)}`}

packages/ui/src/utils/billing.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ type Localizations = Pick<ReturnType<typeof useLocalizations>, '$' | 't'>;
1313

1414
export function getDiscountDescription(
1515
discount: Discount,
16-
cycles: number | null,
16+
cycles: number | null | undefined,
1717
planPeriod: BillingSubscriptionPlanPeriod,
1818
{ $, t }: Localizations,
1919
) {
@@ -24,7 +24,7 @@ export function getDiscountDescription(
2424
? $(discount.amountOff)
2525
: '';
2626

27-
if (cycles === null) {
27+
if (cycles == null) {
2828
return t(localizationKeys('billing.discountAmount', { amount }));
2929
}
3030

0 commit comments

Comments
 (0)